How can I deal with localStorage in SvelteKit SSR?

Asked about 2 months ago Viewed 11 times

I'm building a Notice component that users can dismiss, and I'm storing the displayed state of the notice, however, I would like to preserve it across sessions. localStorage seems like a good way to accomplish this, however, when trying to use localStorage I get server rendering errors.

<script lang="ts>
    let display = $state(
        (window.localStorage.getItem(`notice:${id}`) ?? "true") === "true"
    );
</script>

// ...

The above throws ReferenceError: window is not defined on the server and returns a 500 Internal Error error to the client. How can I avoid this without having to store display state on the server or in a database?

0
1 Answer
Sort by
Accepted by Author Posted about 1 month ago

You're getting that error because the code to initialize display is getting run on the server, and the server does not have access to browser APIs like window. To solve this you can use browser to check if code is running on the server and fallback to a default value if it is.

<script lang="ts">
    import { browser } from "$app/environment";

    let display = $state(
        browser
            ? (window.localStorage.getItem(`notice:${id}`) ?? "true") === "true"
            : false // Fallback value
    );
</script>

// ...

You'll want to perform a check like this for any code that will attempt to access browser APIs (such as window) that can run on the server (i.e. outside of onMount, onclick, or similar).

1
w
79

Your Answer

You Must Log In or Sign Up to Answer Questions