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