<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Adele Beitvashahi</title>
    <description>The latest articles on Forem by Adele Beitvashahi (@adelbeit).</description>
    <link>https://forem.com/adelbeit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F964746%2F51a37dc3-e2af-4c01-b6c7-f561cf55c12e.jpeg</url>
      <title>Forem: Adele Beitvashahi</title>
      <link>https://forem.com/adelbeit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adelbeit"/>
    <language>en</language>
    <item>
      <title>Choosing a video hosting provider for hobby projects</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Mon, 30 Mar 2026 02:06:36 +0000</pubDate>
      <link>https://forem.com/adelbeit/choosing-a-video-hosting-provider-for-hobby-projects-12be</link>
      <guid>https://forem.com/adelbeit/choosing-a-video-hosting-provider-for-hobby-projects-12be</guid>
      <description>&lt;p&gt;Something embarrassing happened to me recently. I was at a networking event and I was excited to show someone my &lt;a href="https://adelbeit.com" rel="noopener noreferrer"&gt;website&lt;/a&gt; and passion project &lt;a href="https://jam.adelbeit.com" rel="noopener noreferrer"&gt;Jamroom&lt;/a&gt;. As soon as I pulled them up, I remembered how long it'd been since I created these projects. The UI/UX I'd built a couple of years ago felt stale, and there were unpolished edges I never went back to. &lt;/p&gt;

&lt;p&gt;So I spent last weekend to revamp the UI, rethink some of the UX, and I even finally recorded a demo for Jamroom&lt;sup id="fnref1"&gt;1&lt;/sup&gt; to showcase on my website!&lt;/p&gt;

&lt;p&gt;A new challenge I was presented with then was where to host the demo video. In the past I'd always reach for the quick and dirty solutions like hosting on &lt;a href="https://vimeo.com" rel="noopener noreferrer"&gt;Vimeo&lt;/a&gt;, &lt;a href="https://youtube.com" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;'s unlisted videos, or &lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; even. This time I decided it was time for change, I wanted to host my assets on my own infra. To do this I came up with two requirements:&lt;br&gt;
1) The solution needs to be free/dirt cheap&lt;br&gt;
2) The setup can't take more than a few minutes, time is money!&lt;/p&gt;

&lt;p&gt;Did some research and landed on &lt;a href="https://developers.cloudflare.com/r2/" rel="noopener noreferrer"&gt;Cloudflare R2&lt;/a&gt;, they offer a generous free tier. But mid-onboarding I realized in order to use the free tier, I'd have to either:&lt;br&gt;
1) Switch my DNS provider to &lt;a href="https://www.cloudflare.com/" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt;, having to migrate all my DNS records, which would absolutely take more than a few minutes.&lt;br&gt;
2) Setup URL pre-signing on my backend to provide public access to the videos in my private bucket. Which would be unnecessary work for my needs at this time.&lt;/p&gt;

&lt;p&gt;So I kept digging and voila! Enter &lt;a href="https://vercel.com/docs/storage/vercel-blob" rel="noopener noreferrer"&gt;Vercel Blob&lt;/a&gt; storage, their free tier offers free public access to your assets, albeit it's very limited. But it's good enough for now! There'll come a time when I'll have to finally setup the URL pre-signing to take advantage of the more generous free services out there, but till then I can invest my time in more pressing projects. &lt;/p&gt;

&lt;p&gt;Here are my realistic options, optimizing for ease of setup/use and cost.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;provider&lt;/th&gt;
&lt;th&gt;cheapest tier&lt;/th&gt;
&lt;th&gt;tier limits&lt;/th&gt;
&lt;th&gt;public URL access&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.backblaze.com/b2/cloud-storage.html" rel="noopener noreferrer"&gt;Backblaze B2&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;forever free&lt;/td&gt;
&lt;td&gt;10GB storage, unlimited free egress, 1M writes + 10M reads/mo&lt;/td&gt;
&lt;td&gt;Yes—public buckets support direct URLs , but cannot map custom domain without Cloudflare workaround&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://supabase.com/docs/guides/storage" rel="noopener noreferrer"&gt;Supabase Storage&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;free forever&lt;/td&gt;
&lt;td&gt;1GB file storage, 5GB bandwidth, 50K MAUs&lt;/td&gt;
&lt;td&gt;Yes—public buckets provide direct asset URLs without auth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.digitalocean.com/products/spaces" rel="noopener noreferrer"&gt;DigitalOcean Spaces&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$5/month&lt;/td&gt;
&lt;td&gt;250GB storage, 1TB outbound transfer&lt;/td&gt;
&lt;td&gt;Yes—files can be set to public permissions with direct URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vercel.com/docs/storage/vercel-blob" rel="noopener noreferrer"&gt;Vercel Blob&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;free (Hobby)&lt;/td&gt;
&lt;td&gt;1GB storage, 10GB Blob Data Transfer/month&lt;/td&gt;
&lt;td&gt;Yes—native public access with permanent URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;AWS S3&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;free 12mo&lt;/td&gt;
&lt;td&gt;5GB storage, 20K GET + 2K PUT requests/month, 100GB data transfer out&lt;/td&gt;
&lt;td&gt;Yes via public bucket or presigned URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Links
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://68fwap572n8u3jpb.public.blob.vercel-storage.com/jamroom-demo/jamroom-demo.mp4" rel="noopener noreferrer"&gt;Demo video&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jam.adelbeit.com" rel="noopener noreferrer"&gt;Jamroom Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://adelbeit.com" rel="noopener noreferrer"&gt;My Website&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Jamroom is a passion project I built a couple of years ago to teach myself about real time messaging systems and experiment with music. You can join a room with your friends and play virtual instruments (keyboard and drums) together in real time. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>devdiaries</category>
      <category>vercel</category>
      <category>cloudfront</category>
    </item>
    <item>
      <title>AI Resume Filters Can't Read Between the Lines</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Wed, 18 Mar 2026 21:33:29 +0000</pubDate>
      <link>https://forem.com/adelbeit/ai-resume-filters-cant-read-between-the-lines-56lo</link>
      <guid>https://forem.com/adelbeit/ai-resume-filters-cant-read-between-the-lines-56lo</guid>
      <description>&lt;p&gt;Picture this: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Resume bullet says: "built X system that served 1M+ users at "&lt;br&gt;
A job description says: "implement metrics, logging, and dashboards."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI sees no overlap and disqualifies the candidate. But any engineer who shipped to a million users (heck anyone who has built anything for any business) has &lt;em&gt;absolutely&lt;/em&gt; built observability infrastructure, they just didn't waste resume space saying so. Sometimes they handcrafted the dashboards, sometimes they used already present tooling like &lt;a href="https://mixpanel.com/" rel="noopener noreferrer"&gt;Mixpanel&lt;/a&gt; and other observability platforms with built in dashboarding capabilities. The point is &lt;strong&gt;businesses require observability period&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Observability is just one example. Testing, code review, documentation, incident response, none of it makes the resume because those are all implementation details of the role, the meat and the potatoes are the ✨results✨ &lt;/p&gt;

&lt;p&gt;Of course that's not to say those implementation details are unimportant, but time and place for everything, they're meant to be communicated verbally &lt;strong&gt;during the interview&lt;/strong&gt;. That's what interviews are for.&lt;/p&gt;

&lt;p&gt;Resumes are meant to showcase highlights of your career through story telling focused on impactful work, not serve as a laundry list of every single task you've done. That'd turn it into an unsustainably large alphabet soup. A soup so large even the AI systems ingesting it would lose their appetite.&lt;/p&gt;

&lt;p&gt;Of course I don't believe we'll ever give up AI in recruiting or any other industry. The AI isn't the problem. The prompt behind it is, and that's on whoever built the filtering tool. A productive step may be to work towards more intelligent system prompts that do more than just keyword matching. That's what LLMs are for after all. Here's an example of a system prompt designed to infer implied skills from context clues. Things like treating "served 1M+ users" as an observability signal, or treating quantified improvements as evidence of instrumentation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: this is illustrative, not a comprehensive solution.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a resume intelligence system. Your job is to evaluate a candidate's 
true qualifications by reading between the lines, not just scanning for keywords.

Experienced engineers don't list every task they performed. They tell a story 
of impact. Your job is to understand what that story implies.

When evaluating a resume against a job description, consider what the candidate 
almost certainly did but didn't write down. A system serving millions of users 
implies observability. Quantified improvements imply instrumentation. Enterprise 
experience implies process. Real-time features imply distributed systems thinking.
Startup experience implies ownership and autonomy.

Use context clues from company size, scale, tech stack, and career trajectory 
to infer unstated but implied competencies. Distinguish between a real skill gap 
and a resume brevity gap. Flag the latter for interview validation rather than 
automatic disqualification.

The best resumes are highlight reels, not task logs. They're narrative-driven 
stories of impact, not exhaustive records of everything someone has ever done. 
Don't penalize candidates for writing a good one.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>recruiting</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to use Filters in PrimeReact DataTables</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Mon, 09 Sep 2024 20:07:34 +0000</pubDate>
      <link>https://forem.com/adelbeit/how-to-use-filters-in-primereact-datatables-mhp</link>
      <guid>https://forem.com/adelbeit/how-to-use-filters-in-primereact-datatables-mhp</guid>
      <description>&lt;p&gt;[UPDATE]: I've made a comprehensive &lt;a href="https://stackblitz.com/edit/vz6wt2-cs8nz4?file=src%2FApp.tsx" rel="noopener noreferrer"&gt;demo on blitzstack&lt;/a&gt; which goes in depth on the different filtering scenarios that are neglected in the primereact docs. I'll update this article into a full writeup when I get the chance but for now that should serve all your filtering needs and then some! check it out&lt;/p&gt;

&lt;p&gt;[EDIT]: &lt;a href="https://github.com/primefaces/primereact/issues/3325#:~:text=To%20apply%20a%20custom%20filter%2C%20the%20following%20conditions%20must%20be%20met." rel="noopener noreferrer"&gt;insightful github discussion&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote a very long post then decided an image is worth a thousand words, so there you go. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaotv5dhsmk0329610ao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaotv5dhsmk0329610ao.png" alt="Code diagram" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Although the images uploaded to dev.to get downscaled so maybe this one is only worth 250 words.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The aim of this post was to reduce headaches induced by things unsaid in the &lt;a href="https://v9.primereact.org/datatable/#filter" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;. There was a lack of resources online for using filters with MultiSelect and Dropdown components correctly with a more-than-basic data structure setup. So I'm using this post as a resource for future me and anyone else that might find this useful&lt;/p&gt;

&lt;p&gt;If you look at the top left of that image there is a string[] that holds fruit names, that's because you can also use string[] instead of Object[] for the filter item list. I didn't expand on it because the &lt;a href="https://v9.primereact.org/datatable/#filter" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; do a good enough job doing it. &lt;/p&gt;

&lt;p&gt;I tried to cover things the docs failed to cover.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to setup dev containers in windows</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Wed, 28 Aug 2024 02:41:52 +0000</pubDate>
      <link>https://forem.com/adelbeit/how-to-setup-dev-containers-in-windows-3fcn</link>
      <guid>https://forem.com/adelbeit/how-to-setup-dev-containers-in-windows-3fcn</guid>
      <description>&lt;p&gt;If you are going to work with dev containers in Windows you need to realize that they will break HMR (hot module reload) and increase build time unless you put your code inside WSL instead of the windows filesystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Dev Containers Work in Windows
&lt;/h2&gt;

&lt;p&gt;Dev containers use Docker, which relies on WSL. When you spin up a dev container, VSCode starts a docker container in WSL, and mounts the files from windows (if they are stored there). This means changes have to cross the WSL-Windows environment. This tends to break HMR, because HMR relies on file change API of the host env, and the filesystem events don't travel well between different host environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn89s3s05asuhtbwens2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn89s3s05asuhtbwens2d.png" alt="code stored in Windows vs WSL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Correct setup for dev containers in Windows
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Dev container setup in WSL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Install Visual Studio Code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable WSL 2 by following the &lt;a href="https://learn.microsoft.com/windows/wsl/install" rel="noopener noreferrer"&gt;WSL 2 installation guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Ubuntu (or your preferred Linux distribution) from the &lt;a href="https://www.microsoft.com/p/ubuntu/9nblggh4msv6" rel="noopener noreferrer"&gt;Microsoft store&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-windows/wsl-tech-preview/#download" rel="noopener noreferrer"&gt;Install Docker Desktop Stable 2.3.0.2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally &lt;a href="https://docs.docker.com/desktop/wsl/#download:~:text=When%20Docker%20Desktop%20starts%2C%20go%20to%20Settings%20%3E%20Resources%20%3E%20WSL%20Integration" rel="noopener noreferrer"&gt;enable Docker support in WSL 2 distros&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow all the directions &lt;a href="https://code.visualstudio.com/blogs/2020/07/01/containers-wsl" rel="noopener noreferrer"&gt;here&lt;/a&gt; to finish setup. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Clone repo inside the WSL filesystem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you should be able to do yarn &amp;amp;&amp;amp; yarn dev inside WSL and HMR should work. &lt;/p&gt;

</description>
      <category>devcontainer</category>
      <category>vscode</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Connect to Azure VM w/SSH Through Azure CLI</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Mon, 12 Aug 2024 20:24:51 +0000</pubDate>
      <link>https://forem.com/adelbeit/connect-to-azure-vm-wssh-through-azure-cli-2ih8</link>
      <guid>https://forem.com/adelbeit/connect-to-azure-vm-wssh-through-azure-cli-2ih8</guid>
      <description>&lt;h4&gt;
  
  
  1. Create your VM
&lt;/h4&gt;

&lt;h4&gt;
  
  
  2. Assign a public IP to the virtual network/subnet that the VM is under
&lt;/h4&gt;

&lt;h4&gt;
  
  
  3. Install azure cli &amp;amp; login:
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;az login&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Install ssh extension for azure cli
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;az extension add --name ssh&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. SSH into vm
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;az ssh vm --private-key-file \path\to\private\key --resource-group &amp;lt;resource group name&amp;gt; --name &amp;lt;vm name&amp;gt; --local-user &amp;lt;local username (default: 'azureuser')&amp;gt;&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  FAQ
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. How to get vm/resource names
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;az vm list -d -o table&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;code&gt;az login&lt;/code&gt; not working on Windows
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;az login --use-device-code&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ssh</category>
      <category>azure</category>
      <category>vm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to remove AI summary search feature on Google search</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Wed, 08 May 2024 21:52:37 +0000</pubDate>
      <link>https://forem.com/adelbeit/how-to-remove-ai-summary-search-feature-on-google-search-560f</link>
      <guid>https://forem.com/adelbeit/how-to-remove-ai-summary-search-feature-on-google-search-560f</guid>
      <description>&lt;h1&gt;
  
  
  You can't turn it off, use DuckDuckGo or another search engine that's independent of large companies.
&lt;/h1&gt;

</description>
      <category>search</category>
      <category>unwantedfeatures</category>
    </item>
    <item>
      <title>How to persist client-side preferences on the client in Svelte (w/o DB)</title>
      <dc:creator>Adele Beitvashahi</dc:creator>
      <pubDate>Sun, 21 Apr 2024 08:48:19 +0000</pubDate>
      <link>https://forem.com/adelbeit/how-to-persist-user-preferences-in-svelte-wo-db-51nf</link>
      <guid>https://forem.com/adelbeit/how-to-persist-user-preferences-in-svelte-wo-db-51nf</guid>
      <description>&lt;h2&gt;
  
  
  &lt;center&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;I was in the middle of creating a static site with Svelte. Now of course you might say, why not just make it with plain HTML and CSS. To that I say, it's 2024 and you can go to jail for something like that. &lt;/p&gt;

&lt;p&gt;Now, I'm a React developer by trade, but I chose Svelte for this project, because; 1) it ships less JS to the browser due to it not using a virtual DOM. 2) it's excellent for static site generation (SSG), which is what I needed for this project. and most importantly, 3) it was time I finally learned it and saw what the craze was about, I can't go a day without hearing about the amazing developer experience (dx) Svelte provides. And by golly was I in for a treat! Seriously everyone &lt;strong&gt;needs&lt;/strong&gt; to learn Svelte.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;&lt;strong&gt;Challenge&lt;/strong&gt;&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;I needed to provide the website content in different locales, and I wanted to persist their preference across all time and space; all pages, routes, and sessions. This challenge is also applicable to website theming, and potentially any other user preference setting that isn't saved on serverside.&lt;/p&gt;

&lt;p&gt;First step is setting and viewing the user preference. &lt;/p&gt;

&lt;p&gt;Here's how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/+page.svelte&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// defaults to 'en';&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;preference&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;english&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;spanish&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;french&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is all good and well for a page, but if we wanna share it &lt;code&gt;between pages&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Enter, Svelte &lt;code&gt;+layout.svelte&lt;/code&gt;. If we move that code to the root layout, every descendant of that route (page.svelte and layout.svelte alike) will have that layout display without changing. If I navigate between routes as long as I don't move up above that layout, the preference will stay. &lt;/p&gt;

&lt;p&gt;Now the next issue is accessing that preference from a different component/page. To do that we will need a store. Which is just an object with a subscribe function. Whatever subscribes to that store will update when the store updates.&lt;/p&gt;

&lt;p&gt;Here's a brief review of how to create a &lt;a href="https://svelte.dev/docs/svelte-store" rel="noopener noreferrer"&gt;store in Svelte&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// $lib/utils/stores.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte/store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;defaultLocale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The locale selector is located inside the navbar, which I want to be nearly global to this site so it will live in &lt;code&gt;+layout.svelte&lt;/code&gt;&lt;br&gt;
Here's how to use that store, in a dumbed down version of my use case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/+layout.svelte&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/utils/stores.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;preference&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;english&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;spanish&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;french&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the state of locale will persist across page/route navigations, but it will reset upon refresh and or closing and reopening the site. &lt;/p&gt;

&lt;p&gt;So naturally we will want to persist the state somewhere tangible, and more enduring.&lt;br&gt;
How about ✨local storage✨? &lt;br&gt;
Let's do that, we can reuse the code from above and subscribe the localStorage to the store. So updates to store also update localStorage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// $lib/utils/stores.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$app/environment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte/store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// retrieve localStorage value if it's been set already&lt;/span&gt;
&lt;span class="c1"&gt;// important for persisting through refreshes&lt;/span&gt;
&lt;span class="c1"&gt;// broswer check is needed because localstorage doesn't exist on server side&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storedLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storedLocale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// subscribe to changes&lt;/span&gt;
&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/+layout.svelte&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/utils/stores.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;preference&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;english&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;spanish&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;french&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what we've achieved so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ get &amp;amp; set a preference &lt;/li&gt;
&lt;li&gt;✅ persist it through pages/routes&lt;/li&gt;
&lt;li&gt;✅ persist through refreshes AND sessions (new tab/window)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what's this?? there's a new problem. Everytime you reload the page, there's a layout shift, where the value of the preference will be set to its initial default before it fetches the stored localstorage value.&lt;/p&gt;

&lt;p&gt;This happens because of &lt;code&gt;server side rendering (SSR)&lt;/code&gt;, which is an amazing amazing feature that's readily available to us today. It works by partially rendering the website on server side before sending it to the client, and then &lt;code&gt;hydrating&lt;/code&gt; it with the rest of the javascript that's necessary for it to fully render, clientside JS basically. I won't go into details of why and how SSR is good, you know how to google.&lt;/p&gt;

&lt;p&gt;The problem is that, our user preferences are stored in localstorage, which is only available on client side. The server that's performing SSR is unaware of this localstorage. So when it partially renders the page, &lt;code&gt;localStorage.getItem()&lt;/code&gt; just returns undefined. So it will default to the fallback value of "en". Even though the users might have specified otherwise in their previous visit, and stored that preference in their localStorage. There are 2 ways to solve this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We can add conditional rendering for any affected content on the site so that it doesn't render until our hydration is fully complete, but that will defeat the purpose of SSR.&lt;/li&gt;
&lt;li&gt;We can use cookies 🍪 to store user preferences. Because unlike localStorage, cookies persist on user's system &lt;strong&gt;and&lt;/strong&gt; the server will have access to them. Perfect!&lt;/li&gt;
&lt;/ol&gt;

&lt;h6&gt;P.S. we could also try and fetch localstorage value first thing in our lifecycle events like onMount, but that doesn't follow the Svelte way. It doesn't fully embrace SSR as we are interrupting the initial load with dataloading/fetching, which should be done on server side as much as possible.

If we were in React land, then it'd be more acceptable.&lt;/h6&gt;

&lt;p&gt;To send and receive the preference cookies, we will need to setup a server js file for our layout that will handle the data fetching and initial data setting through Svelte's &lt;a href="https://kit.svelte.dev/docs/load" rel="noopener noreferrer"&gt;&lt;code&gt;load&lt;/code&gt; function&lt;/a&gt;. That data is then loaded into our route, as defined in +layout.svelte.&lt;/p&gt;

&lt;p&gt;For this, I'll move most of the store logic to +layout.svelte&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// $lib/utils/stores.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte/store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/+layout.server.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/data/en.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preferences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// routes/+layout.svelte&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/utils/stores.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$app/environment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$lib/utils/cookies.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// use the cookie value&lt;/span&gt;
  &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storedLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// prefer localstorage value if cookie is unreliable for any reason.&lt;/span&gt;
    &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;storedLocale&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// subscribe localstorage and cookies to the locale store&lt;/span&gt;
  &lt;span class="nl"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// setCookie is a custom function I wrote for managing cookies easier, you can find it under this codeblock&lt;/span&gt;
    &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;locale&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;preference&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;$locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;english&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;spanish&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;french&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// $lib/utils/cookies.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$app/environment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;setCookie can only be used in the browser, make sure to check for browser object first&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;farFutureDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100 years from now&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;farFutureDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUTCString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; expires=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; path=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you might be wondering why do we need localstorage if we are going to use cookies. The answer is redundancy.&lt;/p&gt;

&lt;p&gt;And there you have it! This was how to persist data on clientside and avoid layout shifts in SSR.&lt;/p&gt;

&lt;h6&gt;If you have any comments, questions, or concerns, please keep them to yourself.&lt;/h6&gt;

&lt;h6&gt;All typos are on purpose.&lt;/h6&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kit.svelte.dev/docs/" rel="noopener noreferrer"&gt;SvelteKit Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;Unpaid Intern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRhzdY2LIXuzsiEvKVd-jxZYF17s4WwtvIIdA&amp;amp;usqp=CAU" rel="noopener noreferrer"&gt;Emotional Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adelbeit.com/" rel="noopener noreferrer"&gt;Shameless Plug&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cover picture provided by &lt;a href="https://unsplash.com/photos/round-white-compass-iDzKdNI7Qgc?utm_content=creditShareLink&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>cookies</category>
    </item>
  </channel>
</rss>
