Context
Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as ‘prop-drilling’). The parent component sets context with setContext(key, value)
...
<script>
import { setContext } from 'svelte';
setContext('my-context', 'hello from Parent.svelte');
</script>
<script lang="ts">
import { setContext } from 'svelte';
setContext('my-context', 'hello from Parent.svelte');
</script>
...and the child retrieves it with getContext
:
<script>
import { getContext } from 'svelte';
const message = getContext('my-context');
</script>
<h1>{message}, inside Child.svelte</h1>
<script lang="ts">
import { getContext } from 'svelte';
const message = getContext('my-context');
</script>
<h1>{message}, inside Child.svelte</h1>
This is particularly useful when Parent.svelte
is not directly aware of Child.svelte
, but instead renders it as part of a children
snippet (demo):
<Parent>
<Child />
</Parent>
The key ('my-context'
, in the example above) and the context itself can be any JavaScript value.
In addition to setContext
and getContext
, Svelte exposes hasContext
and getAllContexts
functions.
Using context with state
You can store reactive state in context (demo)...
<script>
import { setContext } from 'svelte';
import Child from './Child.svelte';
let counter = $state({
count: 0
});
setContext('counter', counter);
</script>
<button onclick={() => counter.count += 1}>
increment
</button>
<Child />
<Child />
<Child />
...though note that if you reassign counter
instead of updating it, you will ‘break the link’ — in other words instead of this...
<button onclick={() => counter = { count: 0 }}>
reset
</button>
...you must do this:
<button onclick={() => counter.count = 0}>
reset
</button>
Svelte will warn you if you get it wrong.
Type-safe context
As an alternative to using setContext
and getContext
directly, you can use them via createContext
. This gives you type safety and makes it unnecessary to use a key:
import { function createContext<T>(): [() => T, (context: T) => T]
Returns a [get, set]
pair of functions for working with context in a type-safe way.
createContext } from 'svelte';
export const [const getUserContext: () => User
getUserContext, const setUserContext: (context: User) => User
setUserContext] = createContext<User>(): [() => User, (context: User) => User]
Returns a [get, set]
pair of functions for working with context in a type-safe way.
createContext<User>();
Replacing global state
When you have state shared by many different components, you might be tempted to put it in its own module and just import it wherever it’s needed:
export const const myGlobalState: {
user: {};
}
myGlobalState = function $state<{
user: {};
}>(initial: {
user: {};
}): {
user: {};
} (+1 overload)
namespace $state
$state({
user: {}
user: {
// ...
}
// ...
});
In many cases this is perfectly fine, but there is a risk: if you mutate the state during server-side rendering (which is discouraged, but entirely possible!)...
<script>
import { myGlobalState } from './state.svelte.js';
let { data } = $props();
if (data.user) {
myGlobalState.user = data.user;
}
</script>
<script lang="ts">
import { myGlobalState } from './state.svelte.js';
let { data } = $props();
if (data.user) {
myGlobalState.user = data.user;
}
</script>
...then the data may be accessible by the next user. Context solves this problem because it is not shared between requests.
Edit this page on GitHub llms.txt