My app stores user preferences in local storage, and I’m trying to make these values available as a context in my app. I’m stuck because I don’t understand how to set a context from an async function at the highest level of the app in SvelteKit.
I created a store that defaults to an object that has the default values (local storage hasn’t been loaded yet):
export const localStoragePreferences = writable(new LocalStoragePreferences());
Now, I have an async function queryLocalStoragePreferences
that returns the true value of local storage.
I tried to set this in the root layout.ts
:
export async function load() {
const localStoragePreferences = await queryLocalStoragePreferences();
setContext('localStoragePreferences', localStoragePreferences);
}
This fails because of the error Function called outside component initialization
.
According to this answer to a similar question, I should declare setContext in a high-level component, and then update the context with my async value in a lower-level component. What’s the place to do that in SvelteKit?
The highest level component in SvelteKit is the +layout.svelte
in the routes directory, every page has that as an ancestor.
Based on the answer by @brunnerh, here is what I did.
routes
directory +layout.svelte
import { setContext } from 'svelte';
/** @type {import('./$types').LayoutData} */
export let data;
setContext('localStoragePreferences', data.localStoragePreferences);
routes
directory +layout.ts
import queryLocalStoragePreferences from '$lib/queries/queryLocalStoragePreferences';
/** @type {import('./$types').LayoutServerLoad} */
export async function load() {
const newPreferences = await queryLocalStoragePreferences();
return {
localStoragePreferences: newPreferences
};
}
stores.ts
export const localStoragePreferences = writable(new LocalStoragePreferences());
Now I have a global store working as I expected!