How to persist _layout state between pages in Sveltekit

Viewed 837

I have a variable checked in my __layout.svelte and I want to have the value remain unchanged between page navigations. Instead when I navigate to a new page checked gets reset back to the default, false. Is there a way to simply persist layout or app state between page loads?

The context for the question is that I need to maintain the value of checked, which is a manual dark mode switch, across page navigations in the app.

<!-- __layout.svelte -->
<script>

  let checked = false

  $: checked, console.log('checked is', checked)

</script>

<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>

<div style="margin-top:2em">
  <label>
    <input type="checkbox" bind:checked/>
    a checkbox...
  </label>
</div>

<slot></slot>
1 Answers

This is a good example for Svelte Store. (Docs)

Best practice is to create a file containing your stored variables. In this case i called the file store.js inside the lib folder.

enter image description here

store.js:

import { writable } from "svelte/store";

export const checked = writable(false); // set the default value to false

Anywhere in your project you can now import this store with the following line in the <script/> tag:

import {checked} from '$lib/store.js';

You can also bind this store to a checkbox like so:

<input type="checkbox" bind:checked={$checked}/>

This could be your index.svelte file which will automatically update the <h1/> tag:

<script>
  import {checked} from '$lib/store.js';
</script>

<h1>{$checked}</h1>

Svelte Store offer many more features (subscribing, derived or readable stores,...). Therefore i linked the (Docs) above.


EDIT: Extending this concept by using the browsers localStorage allows us to save the data across browser sessions (Source).

The example below:

  1. Subscribes to the Svelte writable
  2. Checks if (browser) - due to SSR, the server would throw an error, since it doesn't have a localStorage
  3. Uses the JSON parser, because the localStorage only saves Strings and not Booleans

Updated store.js file:

import { writable } from "svelte/store";
import { browser } from "$app/env";

export const checked = writable();

if (browser){
    checked.set(JSON.parse(localStorage.getItem("checked")) || false);
    checked.subscribe(value => {
        localStorage.setItem("checked", JSON.stringify(value));
    });
}
Related