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).