Skip to main content

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

Parent
<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:

Child
<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:

context
import { function createContext<T>(): [() => T, (context: T) => T]

Returns a [get, set] pair of functions for working with context in a type-safe way.

get will throw an error if no parent component called set.

@since5.40.0
createContext
} from 'svelte';
export const [const getUserContext: () => UsergetUserContext, const setUserContext: (context: User) => UsersetUserContext] = createContext<User>(): [() => User, (context: User) => User]

Returns a [get, set] pair of functions for working with context in a type-safe way.

get will throw an error if no parent component called set.

@since5.40.0
createContext
<User>();

When writing component tests, it can be useful to create a wrapper component that sets the context in order to check the behaviour of a component that uses it. As of version 5.49, you can do this sort of thing:

import { function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component. Transitions will play during the initial render unless the intro option is set to false.

mount
,
function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>

Unmounts a component that was previously mounted using mount or hydrate.

Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.

Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).

import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
unmount
} from 'svelte';
import { const expect: ExpectStaticexpect, const test: TestAPI

Defines a test case with a given name and test function. The test function can optionally be configured with test options.

@paramname - The name of the test or a function that will be used as a test name.
@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.
@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.
@throwsError If called inside another test function.
@examplets // Define a simple test test('should add two numbers', () => { expect(add(1, 2)).toBe(3); });
@examplets // Define a test with options test('should subtract two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); });
test
} from 'vitest';
import { import setUserContextsetUserContext } from './context'; import
type MyComponent = SvelteComponent<Record<string, any>, any, any>
const MyComponent: LegacyComponentType
MyComponent
from './MyComponent.svelte';
test<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number | TestCollectorOptions): void (+2 overloads)

Defines a test case with a given name and test function. The test function can optionally be configured with test options.

@paramname - The name of the test or a function that will be used as a test name.
@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.
@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.
@throwsError If called inside another test function.
@examplets // Define a simple test test('should add two numbers', () => { expect(add(1, 2)).toBe(3); });
@examplets // Define a test with options test('should subtract two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); });
test
('MyComponent', () => {
function
function (local function) Wrapper(...args: any[]): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>
Wrapper
(...args: any[]args) {
import setUserContextsetUserContext({ name: stringname: 'Bob' }); return function MyComponent(internals: Brand<"ComponentInternals">, props: Record<string, any>): ReturnType<Component<Record<string, any>, Record<string, any>>>MyComponent(...args: any[]args); } const
const component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>
component
=
mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>>(component: ComponentType<...> | Component<...>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component. Transitions will play during the initial render unless the intro option is set to false.

mount
(
function (local function) Wrapper(...args: any[]): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>
Wrapper
, {
target: Document | Element | ShadowRoot

Target element where the component will be mounted.

target
: var document: Documentdocument.Document.body: HTMLElement

Specifies the beginning and end of the document body.

MDN Reference

body
}); expect<string>(actual: string, message?: string): Assertion<string> (+1 overload)expect(var document: Documentdocument.Document.body: HTMLElement

Specifies the beginning and end of the document body.

MDN Reference

body
.Element.innerHTML: stringinnerHTML).JestAssertion<string>.toBe: <string>(expected: string) => void

Checks that a value is what you expect. It calls Object.is to compare values. Don’t use toBe with floating-point numbers.

@exampleexpect(result).toBe(42); expect(status).toBe(true);
toBe
('<h1>Hello Bob!</h1>');
function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>

Unmounts a component that was previously mounted using mount or hydrate.

Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.

Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).

import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
unmount
(
const component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>
component
);
});

This approach also works with hydrate and render.

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:

state.svelte
export const 
const myGlobalState: {
    user: {};
}
myGlobalState
=
function $state<{
    user: {};
}>(initial: {
    user: {};
}): {
    user: {};
} (+1 overload)
namespace $state

Declares reactive state.

Example:

let count = $state(0);

https://svelte.dev/docs/svelte/$state

@paraminitial The initial value
$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!)...

App
<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

previous next