[{"data":1,"prerenderedAt":770},["ShallowReactive",2],{"navigation":3,"legal-\u002Fprivacy":48},[4],{"title":5,"path":6,"stem":7,"children":8,"page":47},"Blog","\u002Fblog","blog",[9,13,17,21,25,29,33,39,43],{"title":10,"path":11,"stem":12},"Building AI Agents with Claude","\u002Fblog\u002Fbuilding-ai-agents-with-claude","blog\u002Fbuilding-ai-agents-with-claude",{"title":14,"path":15,"stem":16},"Debugging Node.js Memory Leaks","\u002Fblog\u002Fdebugging-node-memory-leaks","blog\u002Fdebugging-node-memory-leaks",{"title":18,"path":19,"stem":20},"Getting Started with Nuxt 4","\u002Fblog\u002Fgetting-started-with-nuxt-4","blog\u002Fgetting-started-with-nuxt-4",{"title":22,"path":23,"stem":24},"Git Workflows That Scale","\u002Fblog\u002Fgit-workflows-that-scale","blog\u002Fgit-workflows-that-scale",{"title":26,"path":27,"stem":28},"Kubernetes for Solo Developers","\u002Fblog\u002Fkubernetes-for-solo-developers","blog\u002Fkubernetes-for-solo-developers",{"title":30,"path":31,"stem":32},"My Developer Setup in 2026","\u002Fblog\u002Fmy-developer-setup-2026","blog\u002Fmy-developer-setup-2026",{"title":34,"path":35,"stem":36,"children":37},"Postgres Indexing Explained","\u002Fblog\u002Fpostgres-indexing-explained","blog\u002Fpostgres-indexing-explained",[38],{"title":34,"path":35,"stem":36},{"title":40,"path":41,"stem":42},"Tailwind v4 Migration Notes","\u002Fblog\u002Ftailwind-v4-migration-notes","blog\u002Ftailwind-v4-migration-notes",{"title":44,"path":45,"stem":46},"TypeScript Patterns I Use Daily","\u002Fblog\u002Ftypescript-patterns-i-use-daily","blog\u002Ftypescript-patterns-i-use-daily",false,{"id":49,"title":50,"body":51,"description":759,"extension":760,"meta":761,"navigation":762,"path":763,"robots":764,"seo":765,"sitemap":766,"stem":767,"updated":768,"__hash__":769},"legal\u002Fprivacy.md","Privacy policy",{"type":52,"value":53,"toc":728},"minimark",[54,63,66,71,74,93,96,100,211,214,218,223,226,237,243,247,250,267,270,275,279,282,285,288,293,296,305,308,311,316,320,323,327,338,342,349,353,361,365,368,418,421,425,428,431,435,494,498,501,505,508,564,574,577,581,585,595,599,620,624,627,641,645,648,654,680,683,689,695,701,705,708,712,715,719],[55,56,57,58,62],"p",{},"This privacy policy explains what happens to your personal data when you read CodeJourney at ",[59,60,61],"code",{},"codejourney.io"," or write to us by email. Personal data means any information about you as a person, for example your email address or the pages you read.",[55,64,65],{},"CodeJourney is a personal blog. It shows no advertising, sells no data, and works fully without optional cookies. Some data only reaches us when you say yes in the consent banner.",[67,68,70],"h2",{"id":69},"who-is-responsible","Who is responsible",[55,72,73],{},"The person responsible for your data (the \"data controller\") is:",[75,76,77,85],"ul",{},[78,79,80,84],"li",{},[81,82,83],"strong",{},"Boluwatife Morawo",", the owner of CodeJourney, based in Nigeria.",[78,86,87,88],{},"Email: ",[89,90,92],"a",{"href":91},"mailto:contact@codejourney.io","contact@codejourney.io",[55,94,95],{},"Write to this address for every privacy question or request. We have not appointed a data protection officer, because the law does not require one for a site of this size.",[67,97,99],{"id":98},"summary","Summary",[101,102,103,125],"table",{},[104,105,106],"thead",{},[107,108,109,113,116,119,122],"tr",{},[110,111,112],"th",{},"What",[110,114,115],{},"When",[110,117,118],{},"Why",[110,120,121],{},"Legal basis",[110,123,124],{},"How long",[126,127,128,146,163,180,195],"tbody",{},[107,129,130,134,137,140,143],{},[131,132,133],"td",{},"Technical request data",[131,135,136],{},"Every visit",[131,138,139],{},"Deliver pages, keep the site safe",[131,141,142],{},"Legitimate interests",[131,144,145],{},"Not stored. Anonymous server records: up to 30 days",[107,147,148,151,154,157,160],{},[131,149,150],{},"Consent choice",[131,152,153],{},"When you choose in the banner",[131,155,156],{},"Remember your choice",[131,158,159],{},"Legal obligation to record consent, and legitimate interests",[131,161,162],{},"6 months, in your browser",[107,164,165,168,171,174,177],{},[131,166,167],{},"Analytics and error reports",[131,169,170],{},"Only if you accept \"Analytics\"",[131,172,173],{},"Find slow pages and errors",[131,175,176],{},"Consent",[131,178,179],{},"Up to 30 days",[107,181,182,185,188,191,193],{},[131,183,184],{},"Approximate location",[131,186,187],{},"Only if you accept \"Location\" too",[131,189,190],{},"See which regions read the blog and where pages are slow",[131,192,176],{},[131,194,179],{},[107,196,197,200,203,206,208],{},[131,198,199],{},"Emails you send us",[131,201,202],{},"When you write to us",[131,204,205],{},"Answer you",[131,207,142],{},[131,209,210],{},"Up to 2 years after the last message",[55,212,213],{},"The sections below explain each line.",[67,215,217],{"id":216},"data-we-process","Data we process",[219,220,222],"h3",{"id":221},"when-you-open-a-page","When you open a page",[55,224,225],{},"Your browser sends a request to our server for every page and image. The request contains your IP address, the address of the page, the time, and the name and version of your browser. The server needs this information to send the page back to you.",[75,227,228,231,234],{},[78,229,230],{},"Our server does not write your IP address into its logs.",[78,232,233],{},"The server measures every request: the page address, the status code, and how long the answer took. Before these measurements leave the server, the server deletes your IP address and the name of your browser. What remains cannot identify you. We keep these anonymous records for up to 30 days in Grafana Cloud (see \"Who receives data\").",[78,235,236],{},"Our server log files also pass a filter that replaces IP addresses and email addresses before the logs leave the server.",[55,238,239,242],{},[81,240,241],{},"Legal basis:"," our legitimate interest in running a fast and secure site (GDPR article 6(1)(f), and the same basis under the Nigeria Data Protection Act 2023 and similar laws).",[219,244,246],{"id":245},"analytics-and-error-reports-only-with-your-consent","Analytics and error reports (only with your consent)",[55,248,249],{},"If you accept \"Analytics\" in the consent banner, your browser loads Grafana Faro, a small monitoring script. Faro sends the following data to Grafana Cloud:",[75,251,252,255,258,261,264],{},[78,253,254],{},"the pages you open on CodeJourney, and how long they take to load;",[78,256,257],{},"performance measurements of the page (\"Web Vitals\"), for example how fast the main content appears;",[78,259,260],{},"JavaScript errors that happen in your browser, with the technical details of the error;",[78,262,263],{},"the name and version of your browser and operating system, the language of the browser, the size of the browser window, and whether you use a mobile device;",[78,265,266],{},"a random session id. Faro keeps the id in the session storage of your browser, and the browser forgets it when you close the tab. The id lets us see that several page views belong to the same visit. The id does not identify you, and we never combine it with your name or email address.",[55,268,269],{},"Faro does not use cookies, does not read what you type, and does not record your screen. We switched off the recording of browser console messages, because such messages can contain anything.",[55,271,272,274],{},[81,273,241],{}," your consent (GDPR article 6(1)(a), Nigeria Data Protection Act 2023, and the cookie rules of the EU ePrivacy Directive). You can withdraw your consent at any time with \"Privacy choices\" at the bottom of every page. The withdrawal applies from that moment on.",[219,276,278],{"id":277},"approximate-location-only-with-your-consent","Approximate location (only with your consent)",[55,280,281],{},"If you also accept \"Approximate location\", Grafana works out your continent, country, region and city from the IP address of the Faro request. Grafana uses an offline database on its own servers for this step and then throws the IP address away. Grafana does not store your IP address, and we never see it.",[55,283,284],{},"The result is a city, not your exact position. Under California law, \"precise geolocation\" means a position within about 565 meters (1,850 feet); a city is far less exact than that.",[55,286,287],{},"Without this choice, Faro tells Grafana not to work out any location.",[55,289,290,292],{},[81,291,241],{}," your consent, as above.",[219,294,202],{"id":295},"when-you-write-to-us",[55,297,298,299,301,302,304],{},"When you send an email to an address at ",[59,300,61],{},", for example ",[59,303,92],{},", our mail server stores your email address, your name if your email contains it, the content of the message, and the technical data of the email (for example the time and the sending server). Our mail server checks incoming mail for spam. Part of that check compares the address of the sending mail server with public block lists.",[55,306,307],{},"For security, the mail server also logs the IP address of the server that delivers each email. These local logs rotate within a few days, and the copy that leaves the server for monitoring has the IP addresses and email addresses removed.",[55,309,310],{},"We use your email only to answer you. We keep the conversation for up to 2 years after the last message, and then delete it, unless we need it longer to defend a legal claim. Our mail server keeps a backup copy for up to 7 days.",[55,312,313,315],{},[81,314,241],{}," our legitimate interest in answering messages (GDPR article 6(1)(f)), or steps that you ask for before a contract (GDPR article 6(1)(b)).",[219,317,319],{"id":318},"uptime-checks","Uptime checks",[55,321,322],{},"Grafana Cloud calls our pages and our mail server every few minutes from its own computers, to check that the site works. These checks contain no data about visitors.",[219,324,326],{"id":325},"search-images-and-links","Search, images and links",[75,328,329,332,335],{},[78,330,331],{},"The search box runs in your browser. Your search words do not leave your browser.",[78,333,334],{},"Every image on CodeJourney comes from our own server, even when a post uses a picture from another site. Our server fetches such a picture, so your browser never contacts the other site.",[78,336,337],{},"Links to other sites, for example GitHub, only take you there when you click. The privacy policy of that site then applies.",[219,339,341],{"id":340},"the-editor-of-the-blog","The editor of the blog",[55,343,344,345,348],{},"The owner signs in to an editor at ",[59,346,347],{},"\u002F_studio"," with a GitHub account. The editor uses its own cookies, only for the person who signs in. Readers never see the editor and get none of its cookies.",[67,350,352],{"id":351},"cookies-and-similar-technologies","Cookies and similar technologies",[55,354,355,356,360],{},"The ",[89,357,359],{"href":358},"\u002Fcookies","cookie policy"," lists every cookie and every item in the storage of your browser, with its purpose and how long it stays. In short: without your consent, CodeJourney only stores your consent choice and, if you pick one, your preferred light or dark mode.",[67,362,364],{"id":363},"who-receives-data","Who receives data",[55,366,367],{},"We do not sell your personal data, and we do not share it for advertising. The following companies process data on our behalf, as \"processors\". They may only use the data to provide their service to us.",[101,369,370,383],{},[104,371,372],{},[107,373,374,377,380],{},[110,375,376],{},"Company",[110,378,379],{},"Service",[110,381,382],{},"Where the data is",[126,384,385,396,407],{},[107,386,387,390,393],{},[131,388,389],{},"Contabo GmbH, Germany",[131,391,392],{},"Servers of the site and the mail server, backups",[131,394,395],{},"Germany (European Union)",[107,397,398,401,404],{},[131,399,400],{},"Grafana Labs",[131,402,403],{},"Grafana Cloud: monitoring of the servers, analytics and error reports, uptime checks",[131,405,406],{},"Amazon Web Services, Germany (European Union)",[107,408,409,412,415],{},[131,410,411],{},"GitHub, Inc., United States",[131,413,414],{},"Source code and posts of the blog, sign-in of the editor",[131,416,417],{},"United States. No reader data goes to GitHub.",[55,419,420],{},"We may also disclose personal data when a law, a court or an authority requires it.",[67,422,424],{"id":423},"data-outside-your-country","Data outside your country",[55,426,427],{},"We store personal data in Germany, in the European Union. If you read CodeJourney from outside the European Union, your data travels to Germany. The European Union has strict data protection rules.",[55,429,430],{},"Grafana Labs is a company in the United States, and its staff may access the data from outside the European Union, for example for support. Grafana Labs' data processing terms protect such access with safeguards that the law accepts, such as the Standard Contractual Clauses of the European Commission. Where the Nigeria Data Protection Act 2023 or another law sets rules for transfers abroad, we rely on the same safeguards.",[67,432,434],{"id":433},"how-long-we-keep-data","How long we keep data",[101,436,437,446],{},[104,438,439],{},[107,440,441,444],{},[110,442,443],{},"Data",[110,445,124],{},[126,447,448,455,462,478,486],{},[107,449,450,453],{},[131,451,452],{},"Anonymous server records and server logs",[131,454,179],{},[107,456,457,460],{},[131,458,459],{},"Analytics, error reports and approximate location",[131,461,179],{},[107,463,464,475],{},[131,465,466,467,470,471,474],{},"Your consent choice (cookies ",[59,468,469],{},"ncc_c"," and ",[59,472,473],{},"ncc_e",")",[131,476,477],{},"6 months, then the banner asks again",[107,479,480,483],{},[131,481,482],{},"Faro session id",[131,484,485],{},"Until you close the tab",[107,487,488,491],{},[131,489,490],{},"Emails",[131,492,493],{},"Up to 2 years after the last message, backups up to 7 days",[67,495,497],{"id":496},"how-we-protect-data","How we protect data",[55,499,500],{},"All connections to CodeJourney use encryption (HTTPS). Our servers only accept administration through a private network, and only the owner can sign in. Monitoring data passes through filters that remove IP addresses and email addresses before the data leaves our servers. Monitoring accounts use access keys with the smallest set of permissions that each part needs.",[67,502,504],{"id":503},"your-rights","Your rights",[55,506,507],{},"You have the following rights. The exact list depends on the law of the place where you live, but we give these rights to every reader:",[75,509,510,516,522,528,534,540,546,552,558],{},[78,511,512,515],{},[81,513,514],{},"Access:"," ask which data we hold about you, and get a copy.",[78,517,518,521],{},[81,519,520],{},"Correction:"," ask us to correct wrong data.",[78,523,524,527],{},[81,525,526],{},"Deletion:"," ask us to delete your data.",[78,529,530,533],{},[81,531,532],{},"Restriction:"," ask us to use your data only in limited ways while we check a request.",[78,535,536,539],{},[81,537,538],{},"Objection:"," object to processing that we base on legitimate interests.",[78,541,542,545],{},[81,543,544],{},"Portability:"," get the data you gave us in a common, machine-readable format.",[78,547,548,551],{},[81,549,550],{},"Withdraw consent:"," change your choice at any time with \"Privacy choices\" at the bottom of every page. The change applies from that moment on.",[78,553,554,557],{},[81,555,556],{},"No automated decisions:"," we make no decisions about you by automated means alone, and we build no profiles of you.",[78,559,560,563],{},[81,561,562],{},"Complaint:"," complain to a data protection authority (see below).",[55,565,566,567,569,570,573],{},"To use a right, write to ",[89,568,92],{"href":91},". We answer within one month, and the request is free. We may ask for information to confirm that the request comes from you. Please note: we cannot connect the random Faro session id to you, so we cannot find analytics data about a specific person. If you tell us the session id that your browser shows in its session storage (",[59,571,572],{},"com.grafana.faro.session","), we can delete the data of that session.",[55,575,576],{},"Using a right never leads to worse treatment of you.",[67,578,580],{"id":579},"information-for-readers-in-specific-regions","Information for readers in specific regions",[219,582,584],{"id":583},"nigeria","Nigeria",[55,586,587,588,594],{},"The Nigeria Data Protection Act 2023 and the General Application and Implementation Directive 2025 of the Nigeria Data Protection Commission apply to us. You have the rights listed above. You can complain to the ",[89,589,593],{"href":590,"rel":591},"https:\u002F\u002Fndpc.gov.ng",[592],"nofollow","Nigeria Data Protection Commission (NDPC)",".",[219,596,598],{"id":597},"other-african-countries","Other African countries",[55,600,601,602,607,608,613,614,619],{},"If you live in another African country, the data protection law of your country may also give you rights, for example the Protection of Personal Information Act (POPIA) in South Africa, the Data Protection Act 2019 in Kenya, the Data Protection Act 2012 in Ghana, or the Personal Data Protection Law in Egypt. You have the rights listed above, and you can complain to the data protection authority of your country, for example the ",[89,603,606],{"href":604,"rel":605},"https:\u002F\u002Finforegulator.org.za",[592],"Information Regulator"," in South Africa, the ",[89,609,612],{"href":610,"rel":611},"https:\u002F\u002Fwww.odpc.go.ke",[592],"Office of the Data Protection Commissioner"," in Kenya, or the ",[89,615,618],{"href":616,"rel":617},"https:\u002F\u002Fwww.dataprotection.org.gh",[592],"Data Protection Commission"," in Ghana.",[219,621,623],{"id":622},"european-union-european-economic-area-switzerland-and-the-united-kingdom","European Union, European Economic Area, Switzerland and the United Kingdom",[55,625,626],{},"The General Data Protection Regulation (GDPR), the UK GDPR and the Swiss data protection law give you the rights listed above. The legal basis of each use of data is named in \"Data we process\". The ePrivacy rules require your consent before a site stores anything in your browser that the site does not strictly need. That is why Faro only runs after your consent.",[55,628,629,630,635,636,594],{},"You can complain to the data protection authority in the country where you live or work. The ",[89,631,634],{"href":632,"rel":633},"https:\u002F\u002Fwww.edpb.europa.eu\u002Fabout-edpb\u002Fabout-edpb\u002Fmembers_en",[592],"European Data Protection Board"," lists the authorities of the EU. In the United Kingdom, the authority is the ",[89,637,640],{"href":638,"rel":639},"https:\u002F\u002Fico.org.uk",[592],"Information Commissioner's Office",[219,642,644],{"id":643},"united-states","United States",[55,646,647],{},"Privacy laws in California (CCPA and CPRA) and in other states, such as Colorado, Connecticut, Virginia, Utah, Texas and Oregon, give rights to residents of those states. Most of these laws only apply to businesses above a certain size, and CodeJourney is far below those sizes. We still give the following information and rights to every reader.",[55,649,650,653],{},[81,651,652],{},"Categories of personal information we collect"," (in the last 12 months):",[75,655,656,662,668,674],{},[78,657,658,661],{},[81,659,660],{},"Identifiers:"," a random session id (only with consent), and your email address when you write to us.",[78,663,664,667],{},[81,665,666],{},"Internet or network activity:"," the pages you open, page speed and errors (only with consent).",[78,669,670,673],{},[81,671,672],{},"Approximate geolocation:"," city, region and country (only with consent). We collect no precise geolocation.",[78,675,676,679],{},[81,677,678],{},"Communications:"," the content of emails you send us.",[55,681,682],{},"We collect this information from you and from your browser. We use it for the purposes in \"Data we process\". We disclose it only to the processors in \"Who receives data\", for those purposes.",[55,684,685,688],{},[81,686,687],{},"We do not sell your personal information, and we do not share it for cross-context behavioral advertising."," We have not done so in the last 12 months. We collect no sensitive personal information, and we do not knowingly collect information about anyone under 16.",[55,690,691,694],{},[81,692,693],{},"Global Privacy Control:"," if your browser sends the Global Privacy Control signal (GPC), we treat the signal as \"Reject all\" and do not show the banner. You can still turn analytics on with \"Privacy choices\".",[55,696,697,700],{},[81,698,699],{},"Your rights:"," you can ask to know what we collected, to get a copy, to correct it, and to delete it, and you can opt out of any sale or sharing (we do neither). You can use an authorized agent for a request; we may ask the agent for proof. We will not treat you differently for using a right. If we refuse a request, you can appeal by replying to our answer; we answer an appeal within 60 days. If the appeal fails, you can contact the attorney general of your state.",[67,702,704],{"id":703},"children","Children",[55,706,707],{},"CodeJourney is a tech blog for adults and teenagers who learn programming. The site is not directed at children under 13 (or under 16 in the European Union). We do not knowingly collect personal data from children. If you believe a child sent us personal data, write to us, and we will delete it.",[67,709,711],{"id":710},"changes-to-this-policy","Changes to this policy",[55,713,714],{},"We change this policy when the site changes. The date at the top shows the last change. When a change needs your consent again, the consent banner asks you again.",[67,716,718],{"id":717},"contact","Contact",[55,720,721,722,725,726],{},"Boluwatife Morawo, CodeJourney",[723,724],"br",{},"\nEmail: ",[89,727,92],{"href":91},{"title":729,"searchDepth":730,"depth":730,"links":731},"",2,[732,733,734,744,745,746,747,748,749,750,756,757,758],{"id":69,"depth":730,"text":70},{"id":98,"depth":730,"text":99},{"id":216,"depth":730,"text":217,"children":735},[736,738,739,740,741,742,743],{"id":221,"depth":737,"text":222},3,{"id":245,"depth":737,"text":246},{"id":277,"depth":737,"text":278},{"id":295,"depth":737,"text":202},{"id":318,"depth":737,"text":319},{"id":325,"depth":737,"text":326},{"id":340,"depth":737,"text":341},{"id":351,"depth":730,"text":352},{"id":363,"depth":730,"text":364},{"id":423,"depth":730,"text":424},{"id":433,"depth":730,"text":434},{"id":496,"depth":730,"text":497},{"id":503,"depth":730,"text":504},{"id":579,"depth":730,"text":580,"children":751},[752,753,754,755],{"id":583,"depth":737,"text":584},{"id":597,"depth":737,"text":598},{"id":622,"depth":737,"text":623},{"id":643,"depth":737,"text":644},{"id":703,"depth":730,"text":704},{"id":710,"depth":730,"text":711},{"id":717,"depth":730,"text":718},"What personal data CodeJourney collects, why, for how long, who receives it, and the rights you have in Africa, Europe, the United States and elsewhere.","md",{},true,"\u002Fprivacy",null,{"title":50,"description":759},{"loc":763},"privacy","2026-11-09","xa1GsV_m3zhGWFv6C2RFKSMAzjxwpor5a2RfEtZ7Ecw",1794249198477]