localStorage in SvelteKit SSR?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?
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).