Svelte.js
Svelte.js
md
---
title: Svelte
---
## docs/svelte/01-introduction/index.md
---
title: Introduction
---
## docs/svelte/01-introduction/01-overview.md
---
title: Overview
---
Svelte is a framework for building user interfaces on the web. It uses a compiler
to turn declarative components written in HTML, CSS and JavaScript...
```svelte
<!file: App.svelte>
<script>
function greet() {
alert('Welcome to Svelte!');
}
</script>
<style>
button {
font-size: 2em;
}
</style>
```
You can use it to build anything on the web, from standalone components to
ambitious full stack apps (using Svelte's companion application framework,
[SvelteKit](../kit)) and everything in between.
You can also try Svelte online in the [playground](/playground) or, if you need a
more fully-featured environment, on [StackBlitz](https://sveltekit.new).
## docs/svelte/01-introduction/02-getting-started.md
---
```bash
npx sv create myapp
cd myapp
npm install
npm run dev
```
Don't worry if you don't know Svelte yet! You can ignore all the nice features
SvelteKit brings on top for now and dive into it later.
## Alternatives to SvelteKit
You can also use Svelte directly with Vite by running `npm create vite@latest` and
selecting the `svelte` option. With this, `npm run build` will generate HTML, JS,
and CSS files inside the `dist` directory using
[vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte). In most
cases, you will probably need to [choose a routing library](faq#Is-there-a-router)
as well.
>[!NOTE] Vite is often used in standalone mode to build [single page apps (SPAs)]
(../kit/glossary#SPA), which you can also [build with SvelteKit](../kit/single-
page-apps).
## Editor tooling
You can also check your code from the command line using [sv
check](https://github.com/sveltejs/cli).
## Getting help
Don't be shy about asking for help in the [Discord chatroom](/chat)! You can also
find answers on [Stack
Overflow](https://stackoverflow.com/questions/tagged/svelte).
## docs/svelte/01-introduction/03-svelte-files.md
---
Components are the building blocks of Svelte applications. They are written into
`.svelte` files, using a superset of HTML.
All three sections — script, styles and markup — are optional.
```svelte
/// file: MyComponent.svelte
<script module>
// module-level logic goes here
// (you will rarely use this)
</script>
<script>
// instance-level logic goes here
</script>
<style>
/* styles go here */
</style>
```
## `<script>`
A `<script>` block contains JavaScript (or TypeScript, when adding the `lang="ts"`
attribute) that runs when a component instance is created. Variables declared (or
imported) at the top level can be referenced in the component's markup.
In addition to normal JavaScript, you can use _runes_ to declare [component props]
($props) and add reactivity to your component. Runes are covered in the next
section.
## `<script module>`
A `<script>` tag with a `module` attribute runs once when the module first
evaluates, rather than for each component instance. Variables declared in this
block can be referenced elsewhere in the component, but not vice versa.
```svelte
<script module>
let total = 0;
</script>
<script>
total += 1;
console.log(`instantiated ${total} times`);
</script>
```
You can `export` bindings from this block, and they will become exports of the
compiled module. You cannot `export default`, since the default export is the
component itself.
> [!LEGACY]
> In Svelte 4, this script tag was created using `<script context="module">`
## `<style>`
CSS inside a `<style>` block will be scoped to that component.
```svelte
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
```
## docs/svelte/01-introduction/04-svelte-js-files.md
---
These behave like any other `.js` or `.ts` module, except that you can use runes.
This is useful for creating reusable reactive logic, or sharing reactive state
across your app.
> [!LEGACY]
> This is a concept that didn't exist prior to Svelte 5
## docs/svelte/01-introduction/xx-props.md
---
Svelte uses the `$props` rune to declare _properties_ or _props_, which means
describing the public interface of the component which becomes accessible to
consumers of the component.
```svelte
<script>
let { foo, bar, baz } = $props();
You can specify a fallback value for a prop. It will be used if the component's
consumer doesn't specify the prop on the component when instantiating the
component, or if the passed value is `undefined` at some point.
```svelte
<script>
let { foo = 'optional default initial value' } = $props();
</script>
```
```svelte
<script>
let { a, b, c, ...everythingElse } = $props();
</script>
```
```svelte
<script>
// creates a `class` property, even
// though it is a reserved word
let { class: className } = $props();
</script>
```
```svelte
<script lang="ts">
interface Props {
required: string;
optional?: number;
[key: string]: unknown;
}
If you're using JavaScript, you can declare the prop types using JSDoc:
```svelte
<script>
/** @type {{ x: string }} */
let { x } = $props();
/**
* @typedef {Object} MyProps
* @property {string} y Some documentation
*/
Readonly props can be accessed as properties on the element, tied to the component
using [`bind:this` syntax](bindings#bind:this).
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the
same effect.
```svelte
<script>
let count = $state(0);
function handleClick() {
// calling this function will trigger an
// update if the markup references `count`
count = count + 1;
}
</script>
```
Svelte's `<script>` blocks are run only when the component is created, so
assignments within a `<script>` block are not automatically run again when a prop
updates.
```svelte
<script>
let { person } = $props();
// this will only set `name` on component creation
// it will not update when `person` does
let { name } = person;
</script>
```
If you'd like to react to changes to a prop, use the `$derived` or `$effect` runes
instead.
```svelte
<script>
let count = $state(0);
$effect(() => {
if (count > 10) {
alert('Too high!');
}
});
</script>
```
## docs/svelte/01-introduction/xx-reactivity-fundamentals.md
---
Reactivity is at the heart of interactive UIs. When you click a button, you expect
some kind of response. It's your job as a developer to make this happen. It's
Svelte's job to make your job as intuitive as possible, by providing a good API to
express reactive systems.
## Runes
Runes are function-like symbols that provide instructions to the Svelte compiler.
You don't need to import them from anywhere — when you use Svelte, they're part of
the language.
The following sections introduce the most important runes for declare state,
derived state and side effects at a high level. For more details refer to the later
sections on [state](state) and [side effects](side-effects).
## `$state`
```svelte
<script>
let count = $state(0);
</script>
You can also use `$state` in class fields (whether public or private):
```js
// @errors: 7006 2554
class Todo {
done = $state(false);
text = $state();
constructor(text) {
this.text = text;
}
}
```
> [!LEGACY]
> In Svelte 4, state was implicitly reactive if the variable was declared at the
top level
>
> ```svelte
> <script>
> let count = 0;
> </script>
>
> <button on:click={() => count++}>
> clicks: {count}
> </button>
> ```
## `$derived`
```svelte
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
> [!LEGACY]
> In Svelte 4, you could use reactive statements for this.
>
> ```svelte
> <script>
> let count = 0;
> $: doubled = count * 2;
> </script>
>
> <button on:click={() => count++}>
> {doubled}
> </button>
>
> <p>{count} doubled is {doubled}</p>
> ```
>
> This only worked at the top level of a component.
## `$effect`
To run _side-effects_ when the component is mounted to the DOM, and when values
change, we can use the `$effect` rune
([demo](/playground/untitled#H4sIAAAAAAAAE31T24rbMBD9lUG7kAQ2sbdlX7xOYNk_aB_rQhRpbA
sU2UiTW0P-vbrYubSlYGzmzMzROTPymdVKo2PFjzMzfIusYB99z14YnfoQuD1qQh-
7bmdFQEonrOppVZmKNBI49QthCc-OOOH0LZ-
9jxnR6c7eUpOnuv6KeT5JFdcqbvbcBcgDz1jXKGg6ncFyBedYR6IzLrAZwiN5vtSxaJA-
EzadfJEjKw11C6GR22-
BLH8B_wxdByWpvUYtqqal2XB6RVkG1CoHB6U1WJzbnYFDiwb3aGEdDa3Bm1oH12sQLTcNPp7r56m_00mHoc
SG97_zd7ICUXonA5fwKbPbkE2ZtMJGGVkEdctzQi4QzSwr9prnFYNk5hpmqVuqPQjNnfOJoMF22lUsrq_Uf
IN6lfSVyvQ7grB3X2mjMZYO3XO9w-
U5iLx42qg29md3BP_ni5P4gy9ikTBlHxjLzAtPDlyYZmRdjAbGq7HprEQ7p64v4LU_guu0kvAkhBim3nMpl
Wl8FreQD-CW20aZR0wq12t-KqDWeBywhvexKC3memmDwlHAv9q4Vo2ZK8KtK0CgX7u9J8wXbzdKv-
nRnfF_2baTqlYoWUF2h5efl9-n0O6koAMAAA==)):
```svelte
<script>
let size = $state(50);
let color = $state('#ff3e00');
let canvas;
$effect(() => {
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
The function passed to `$effect` will run when the component mounts, and will re-
run after any changes to the values it reads that were declared with `$state` or
`$derived` (including those passed in with `$props`). Re-runs are batched (i.e.
changing `color` and `size` in the same moment won't cause two separate runs), and
happen after any DOM updates have been applied.
> [!LEGACY]
> In Svelte 4, you could use reactive statements for this.
>
> ```svelte
> <script>
> let size = 50;
> let color = '#ff3e00';
>
> let canvas;
>
> $: {
> const context = canvas.getContext('2d');
> context.clearRect(0, 0, canvas.width, canvas.height);
>
> // this will re-run whenever `color` or `size` change
> context.fillStyle = color;
> context.fillRect(0, 0, size, size);
> }
> </script>
>
> <canvas bind:this={canvas} width="100" height="100" />
> ```
>
> This only worked at the top level of a component.
## docs/svelte/02-runes/index.md
---
title: Runes
---
## docs/svelte/02-runes/01-what-are-runes.md
---
>
> A letter or mark used as a mystical or magic symbol.
Runes are symbols that you use in `.svelte` and `.svelte.js`/`.svelte.ts` files to
control the Svelte compiler. If you think of Svelte as a language, runes are part
of the syntax — they are _keywords_.
```js
let message = $state('hello');
```
- You don't need to import them — they are part of the language
- They're not values — you can't assign them to a variable or pass them as
arguments to a function
- Just like JavaScript keywords, they are only valid in certain positions (the
compiler will help you if you put them in the wrong place)
> [!LEGACY]
> Runes didn't exist prior to Svelte 5.
## docs/svelte/02-runes/02-$state.md
---
title: $state
---
The `$state` rune allows you to create _reactive state_, which means that your UI
_reacts_ when it changes.
```svelte
<script>
let count = $state(0);
</script>
Unlike other frameworks you may have encountered, there is no API for interacting
with state — `count` is just a number, rather than an object or a function, and you
can update it like you would update any other variable.
State is proxified recursively until Svelte finds something other than an array or
simple object. In a case like this...
```js
let todos = $state([
{
done: false,
text: 'add more todos'
}
]);
```
```js
let todos = [{ done: false, text: 'add more todos' }];
//cut
todos[0].done = !todos[0].done;
```
```js
let todos = [{ done: false, text: 'add more todos' }];
//cut
todos.push({
done: false,
text: 'eat lunch'
});
```
Note that if you destructure a reactive value, the references are not reactive — as
in normal JavaScript, they are evaluated at the point of destructuring:
```js
let todos = [{ done: false, text: 'add more todos' }];
//cut
let { done, text } = todos[0];
You can also use `$state` in class fields (whether public or private):
```js
// @errors: 7006 2554
class Todo {
done = $state(false);
text = $state();
constructor(text) {
this.text = text;
}
reset() {
this.text = '';
this.done = false;
}
}
```
```svelte
<button onclick={todo.reset}>
reset
</button>
```
```svelte
<button onclick={() => todo.reset()}>
reset
</button>
```
```js
// @errors: 7006 2554
class Todo {
done = $state(false);
text = $state();
constructor(text) {
this.text = text;
}
reset = () => {
this.text = '';
this.done = false;
}
}
```
## `$state.raw`
In cases where you don't want objects and arrays to be deeply reactive you can use
`$state.raw`.
```js
let person = $state.raw({
name: 'Heraclitus',
age: 49
});
This can improve performance with large arrays and objects that you weren't
planning to mutate anyway, since it avoids the cost of making them reactive. Note
that raw state can _contain_ reactive state (for example, a raw array of reactive
objects).
## `$state.snapshot`
```svelte
<script>
let counter = $state({ count: 0 });
function onclick() {
// Will log `{ count: ... }` rather than `Proxy { ... }`
console.log($state.snapshot(counter));
}
</script>
```
This is handy when you want to pass some state to an external library or API that
doesn't expect a proxy, such as `structuredClone`.
```js
/// file: index.js
// @filename: index.js
//cut
/**
* @param {number} a
* @param {number} b
*/
function add(a, b) {
return a + b;
}
let a = 1;
let b = 2;
let total = add(a, b);
console.log(total); // 3
a = 3;
b = 4;
console.log(total); // still 3!
```
If `add` wanted to have access to the _current_ values of `a` and `b`, and to
return the current `total` value, you would need to use functions instead:
```js
/// file: index.js
// @filename: index.js
//cut
/**
* @param {() => number} getA
* @param {() => number} getB
*/
function add(getA, getB) {
return() => getA() + getB();
}
let a = 1;
let b = 2;
let total = add(() => a, () => b);
console.log(total()); // 3
a = 3;
b = 4;
console.log(total()); // 7
```
State in Svelte is no different — when you reference something declared with the
`$state` rune...
```js
let a =$state(1);
let b =$state(2);
```
input.a = 3;
input.b = 4;
console.log(total.value); // 7
```
...though if you find yourself writing code like that, consider using [classes]
(#Classes) instead.
## docs/svelte/02-runes/03-$derived.md
---
title: $derived
---
```svelte
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
## `$derived.by`
Sometimes you need to create complex derivations that don't fit inside a short
expression. In these cases, you can use `$derived.by` which accepts a function as
its argument.
```svelte
<script>
let numbers = $state([1, 2, 3]);
let total = $derived.by(() => {
let total = 0;
for (const n of numbers) {
total += n;
}
return total;
});
</script>
## Understanding dependencies
Derived expressions are recalculated when their dependencies change, but you can
temporarily override their values by reassigning them (unless they are declared
with `const`). This can be useful for things like _optimistic UI_, where a value is
derived from the 'source of truth' (such as data from your server) but you'd like
to show immediate feedback to the user:
```svelte
<script>
let { post, like } = $props();
Unlike `$state`, which converts objects and arrays to [deeply reactive proxies]
($state#Deep-state), `$derived` values are left as-is. For example, [in a case like
this](/playground/untitled#H4sIAAAAAAAAE4VU22rjMBD9lUHd3aaQi9PdstS1A3t5XvpQ2Ic4D7I1
iUUV2UjjNMX431eS7TRdSosxgjMzZ45mjt0yzffIYibvy0ojFJWqDKCQVBk2ZVup0LJ43TJ6rn2aBxw-
FP2o67k9oCKP5dziW3hRaUJNjoYltjCyplWmM1JIIAn3FlL4ZIkTTtYez6jtj4w8WwyXv9GiIXiQxLVs9pf
TMR7EuoSLIuLFbX7Z4930bZo_nBrD1bs834tlfvsBz9_SyX6PZXu9XaL4gOWn4sXjeyzftv4ZWfyxubpzxz
g6LfD4MrooxELEosKCUPigQCMPKCZh0OtQE1iSxcsmdHuBvCiHZXALLXiN08EL3RRkaJ_kDVGle0HcSD5TP
EeVtj67O4Nrg9aiSNtBY5oODJkrL5QsHtN2cgXp6nSJMWzpWWGasdlsGEMbzi5jPr5KFr0Ep7pdeM2-
TCelCddIhDxAobi1jqF3cMaC1RKp64bAW9iFAmXGIHfd4wNXDabtOLN53w8W53VvJoZLh7xk4Rr3CoL-
UNoLhWHrT1JQGcM17u96oES5K-
kc2XOzkzqGCKL5De79OUTyyrg1zgwXsrEx3ESfx4Bz0M5UjVMHB24mw9SuXtXFoN13fYKOM1tyUT3FbvbWm
SWCZX2Er-
41u5xPoml45svRahl9Wb9aasbINJixDZwcPTbyTLZSUsAvrg_cPuCR7s782_WU8343Y72Qtlb8OYatwuOQv
uN13M_hJKNfxann1v1U_B1KZ_D_mzhzhz24fw85CSz2irtN9w9HshBK7AQAAA==)...
```svelte
let items = $state([...]);
...you can change (or `bind:` to) properties of `selected` and it will affect the
underlying `items` array. If `items` was _not_ deeply reactive, mutating `selected`
would have no effect.
## Update propagation
```svelte
<script>
let count = $state(0);
let large = $derived(count > 10);
</script>
## docs/svelte/02-runes/04-$effect.md
---
title: $effect
---
Effects are functions that run when state updates, and can be used for things like
calling third-party libraries, drawing on `<canvas>` elements, or making network
requests. They only run in the browser, not during server-side rendering.
Generally speaking, you should _not_ update state inside effects, as it will make
code more convoluted and will often lead to never-ending update cycles. If you find
yourself doing so, see [when not to use `$effect`](#When-not-to-use-$effect) to
learn about alternative approaches.
```svelte
<script>
let size = $state(50);
let color = $state('#ff3e00');
let canvas;
$effect(() => {
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
When Svelte runs an effect function, it tracks which pieces of state (and derived
state) are accessed (unless accessed inside [`untrack`](svelte#untrack)), and re-
runs the function when that state later changes.
Your effects run after the component has been mounted to the DOM, and in a
[microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/
Microtask_guide) after state changes. Re-runs are batched (i.e. changing `color`
and `size` in the same moment won't cause two separate runs), and happen after any
DOM updates have been applied.
You can use `$effect` anywhere, not just at the top level of a component, as long
as it is called while a parent effect is running.
An effect can return a _teardown function_ which will run immediately before the
effect re-runs
([demo](/playground/untitled#H4sIAAAAAAAAE42SQVODMBCF_8pOxkPRKq3HCsx49K4n64xpskjGkD
DJ0tph-O8uINo6HjxB3u7HvrehE07WKDbiyZEhi1osRWksRrF57gQdm6E2CKx_dd43zU3co6VB28mIf-
nKO0JH_BmRRRVMQ8XWbXkAgfKtI8jhIpIkXKySu7lSG2tNRGZ1_GlYr1ZTD3ddYFmiosUigbyAbpC2lKbwW
JkIB8ZhhxBQBWRSw6FCh3sM8GrYTthL-wqqku4N44TyqEgwF3lmRHr4Op0PGXoH31c5rO8mqV-
eOZ49bikgtcHBL55tmhIkEMqg_cFB2TpFxjtg703we6NRL8HQFCS07oSUCZi6Rm04lz1yytIHBKoQpo1w6G
sm4gmyS8b8Y5PydeMdX8gwS2Ok4I-
ov5NZtvQde95GMsccn_1wzNKfu3RZtS66cSl9lvL7qO1aIk7knbJGvefdtIOzi73M4bYvovUHDFk6AcX_0H
RESxnpBOW_jfCDxIZCi_1L_wm4xGQ60wIAAA==)).
```svelte
<script>
let count = $state(0);
let milliseconds = $state(1000);
$effect(() => {
// This will be recreated whenever `milliseconds` changes
const interval = setInterval(() => {
count += 1;
}, milliseconds);
return () => {
// if a teardown function is provided, it will run
// a) immediately before the effect re-runs
// b) when the component is destroyed
clearInterval(interval);
};
});
</script>
<h1>{count}</h1>
Teardown functions also run when the effect is destroyed, which happens when its
parent is destroyed (for example, a component is unmounted) or the parent effect
re-runs.
If `$state` and `$derived` are used directly inside the `$effect` (for example,
during creation of a [reactive
class](https://svelte.dev/docs/svelte/$state#Classes)), those values will _not_ be
treated as dependencies.
Values that are read _asynchronously_ — after an `await` or inside a `setTimeout`,
for example — will not be tracked. Here, the canvas will be repainted when `color`
changes, but not when `size` changes
([demo](/playground/untitled#H4sIAAAAAAAAE31T246bMBD9lZF3pWSlBEirfaEQqdo_2PatVIpjBr
DkGGQPJGnEv1e2IZfVal-wfHzmzJyZ4cIqqdCy9M-
F0blDlnqArZjmB3f72XWRHVCRw_bc4me4aDWhJstSlllhZEfbQhekkMDKfwg5PFvihMvX5OXH_CJa1Zrb0-
Kpqr5jkiwC48rieuDWQbqgZ6wqFLRcvkC-
hYvnkWi1dWqa8ESQTxFRjfQWsOXiWzmr0sSLhEJu3p1YsoJkNUcdZUnN9dagrBu6FVRQHAM10sJRKgUG16b
XcGxQ44AGdt7SDkTDdY02iqLHnJVU6hedlWuIp94JW6Tf8oBt_8GdTxlF0b4n0C35ZLBzXb3mmYn3ae6cOW
74zj0YVzDNYXRHFt9mprNgHfZSl6mzml8CMoLvTV6wTZIUDEJv5us2iwMtiJRyAKG4tXnhl8O0yhbML0Wm-
B7VNlSSSd31BG7z8oIZZ6dgIffAVY_5xdU9Qrz1Bnx8fCfwtZ7v8Qc9j3nB8PqgmMWlHIID6-
bkVaPZwDySfWtKNGtquxQ23Qlsq2QJT0KIqb8dL0up6xQ2eIBkAg_c1FI_YqW0neLnFCqFpwmreedJYT7XX
8FVOBfwWRhXstZrSXiwKQjUhOZeMIleb5JZfHWn2Yq5pWEpmR7Hv-N_wEqT8hEEAAA=)):
```ts
// @filename: index.ts
declare let canvas: {
width: number;
height: number;
getContext(type: '2d', options?: CanvasRenderingContext2DSettings):
CanvasRenderingContext2D;
};
declare let color: string;
declare let size: number;
//cut
$effect(() => {
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
setTimeout(() => {
// ...but not when `size` changes
context.fillRect(0, 0, size, size);
}, 0);
});
```
An effect only reruns when the object it reads changes, not when a property inside
it changes. (If you want to observe changes _inside_ an object at dev time, you can
use [`$inspect`]($inspect).)
```svelte
<script>
let state = $state({ value: 0 });
let derived = $derived({ value: state.value * 2 });
// this will run once, because `state` is never reassigned (only mutated)
$effect(() => {
state;
});
An effect only depends on the values that it read the last time it ran. This has
interesting implications for effects that have conditional code.
For instance, if `a` is `true` in the code snippet below, the code inside the `if`
block will run and `b` will be evaluated. As such, changes to either `a` or `b`
[will cause the effect to re-run](/playground/untitled#H4sIAAAAAAAAE3VQzWrDMAx-
FdUU4kBp71li6EPstOxge0ox8-QQK2PD-N1nLy2F0Z2Evj9_chKkP1B04pnYscc3cRCT8xhF95IEf8-
Vq0DBr8rzPB_jJ3qumNERH-
E2ECNxiRF9tIubWY00lgcYNAywj6wZJS8rtk83wjwgCrXHaULLUrYwKEgVGrnkx-
Dx6MNFNstK5OjSbFGbwE0gdXuT_zGYrjmAuco515Hr1p_uXak3K3MgCGS9s-9D2grU-judlQYXIencnzad-
tdR79qZrMyvw9wd5Z8Yv1h09dz8mn8AkM7Pfo0BAAA=).
Conversely, if `a` is `false`, `b` will not be evaluated, and the effect will
_only_ re-run when `a` changes.
```ts
let a = false;
let b = false;
//cut
$effect(() => {
console.log('running');
if (a) {
console.log('b:', b);
}
});
```
## `$effect.pre`
In rare cases, you may need to run code _before_ the DOM updates. For this we can
use the `$effect.pre` rune:
```svelte
<script>
import { tick } from 'svelte';
// ...
$effect.pre(() => {
if (!div) return; // not yet mounted
<div bind:this={div}>
{#each messages as message}
<p>{message}</p>
{/each}
</div>
```
## `$effect.tracking`
The `$effect.tracking` rune is an advanced feature that tells you whether or not
the code is running inside a tracking context, such as an effect or inside your
template
([demo](/playground/untitled#H4sIAAAAAAAACn3PwYrCMBDG8VeZDYIt2PYeY8Dn2HrIhqkU08nQjI
tS-u6buAt7UDzmz8ePyaKGMWBS-nNRcmdU-
hHUTpGbyuvI3KZvDFLal0v4qvtIgiSZUSb5eWSxPfWSc4oB2xDP1XYk8HHiSHkICeXKeruDDQ4Demlldv4y
0rmq6z10HQwuJMxGVv4mVVXDwcJS0jP9u3knynwtoKz1vifT_Z9Jhm0WBCcOTlDD8kyspmML5qNpHg40jc3
fFryJ0iWsp_UHgz3180oBAAA=)):
```svelte
<script>
console.log('in component setup:', $effect.tracking()); // false
$effect(() => {
console.log('in effect:', $effect.tracking()); // true
});
</script>
## `$effect.root`
```svelte
<script>
let count = $state(0);
const cleanup = $effect.root(() => {
$effect(() => {
console.log(count);
});
return () => {
console.log('effect root cleanup');
};
});
</script>
```
```svelte
<script>
let count = $state(0);
let doubled = $state();
// don't do this!
$effect(() => {
doubled = count * 2;
});
</script>
```
...do this:
```svelte
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
```
If you're using an effect because you want to be able to reassign the derived value
(to build an optimistic UI, for example) note that [deriveds can be directly
overridden]($derived#Overriding-derived-values) as of Svelte 5.25.
You might be tempted to do something convoluted with effects to link one value to
another. The following example shows two inputs for "money spent" and "money left"
that are connected to each other. If you update one, the other should update
accordingly. Don't use effects for this
([demo](/playground/untitled#H4sIAAAAAAAACpVRy26DMBD8FcvKgUhtoIdeHBwp31F6MGSJkBbHwk
sEQvx77aWQqooq9bgzOzP7mGTdIHipPiZJowOpGJAv0po2VmfnDv4OSBErjYdneHWzBJaCjcx91TWOToUtC
IEE3cig0OIty44r5l1oDtjOkyFIsv3GINQ_CNYyGegd1DVUlCR7oU9iilDUcP8S8roYs9n8p2wdYNVFm4cs
Tx872BxNCcjr5I11fdgonEkXsjP2CoUUZWMv6m6wBz2x7yxaM-
iJvWeRsvSbSVeUy5i0uf8vKA78NIeJLSZWv1I8jQjLdyK4XuTSeIdmVKJGGI4LdjVOiezwDu1yG74My8PLC
QaSiroe5s_5C2PHrkVGAgAA)):
```svelte
<script>
let total = 100;
let spent = $state(0);
let left = $state(total);
$effect(() => {
left = total - spent;
});
$effect(() => {
spent = total - left;
});
</script>
<label>
<input type="range" bind:value={spent} max={total} />
{spent}/{total} spent
</label>
<label>
<input type="range" bind:value={left} max={total} />
{left}/{total} left
</label>
```
```svelte
<script>
let total = 100;
let spent = $state(0);
let left = $state(total);
function updateSpent(value) {
spent = value;
left = total - spent;
}
function updateLeft(value) {
left = value;
spent = total - left;
}
</script>
<label>
<input type="range" bind:value={() => spent, updateSpent} max={total} />
{spent}/{total} spent
</label>
<label>
<input type="range" bind:value={() => left, updateLeft} max={total} />
{left}/{total} left
</label>
```
If you absolutely have to update `$state` within an effect and run into an infinite
loop because you read and write to the same `$state`, use [untrack]
(svelte#untrack).
## docs/svelte/02-runes/05-$props.md
---
title: $props
---
```svelte
<!file: App.svelte>
<script>
import MyComponent from './MyComponent.svelte';
</script>
On the other side, inside `MyComponent.svelte`, we can receive props with the
`$props` rune...
```svelte
<!file: MyComponent.svelte>
<script>
let props = $props();
</script>
```svelte
<!file: MyComponent.svelte>
<script>
let{ adjective }= $props();
</script>
## Fallback values
Destructuring allows us to declare fallback values, which are used if the parent
component does not set a given prop:
```js
let { adjective = 'happy' } = $props();
```
## Renaming props
We can also use the destructuring assignment to rename props, which is necessary if
they're invalid identifiers, or a JavaScript keyword like `super`:
```js
let { super: trouper = 'lights are gonna find me' } = $props();
```
## Rest props
Finally, we can use a _rest property_ to get, well, the rest of the props:
```js
let { a, b, c, ...others } = $props();
```
## Updating props
References to a prop inside a component update when the prop itself updates — when
`count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the
child component is able to temporarily override the prop value, which can be useful
for unsaved ephemeral state
([demo](/playground/untitled#H4sIAAAAAAAAE6WQ0WrDMAxFf0WIQR0Wmu3VTQJln7HsIfVcZubIxl
bGRvC_DzuBraN92qPula50tODZWB1RPi_IX16jLALWSOOUq6P3-
_ihLWftNEZ9TVeOWBNHlNhGFYznfqCBzeRdYHh6M_YVzsFNsNs3pdpGd4eBcqPVDMrNxNDBXeSRtXioDgO1
zU8ataeZ2RE4Utao924RFXQ9iHXwvoPHKpW1xY4g_Bg0cSVhKS0p560Za95612ZC02ONrD8ZJYdZp_rGQ37
ff_mSP86Np2TWZaNNmdcH56P4P67K66_SXoK9pG-5dF5Z9QEAAA==)):
```svelte
<!file: App.svelte>
<script>
import Child from './Child.svelte';
```svelte
<!file: Child.svelte>
<script>
let { count } = $props();
</script>
While you can temporarily _reassign_ props, you should not _mutate_ props unless
they are [bindable]($bindable).
```svelte
<!file: App.svelte>
<script>
import Child from './Child.svelte';
</script>
```svelte
<!file: Child.svelte>
<script>
let { object } = $props();
</script>
If the prop is a reactive state proxy, however, then mutations _will_ have an
effect but you will see an [`ownership_invalid_mutation`](runtime-warnings#Client-
warnings-ownership_invalid_mutation) warning, because the component is mutating
state that does not 'belong' to it
([demo](/playground/untitled#H4sIAAAAAAAAE3WR0U7DMAxFf8VESBuiauG1WycheOEbKA9p67FA6k
SNszJV-XeUZhMw2GN8r-1znUmQ7FGU4pn2UqsOes-SlSGRia3S6ET5Mgk-2OiJBZGdOh6szd0eNcdaIx3-
V28NMRI7UYq1awdleVNTzaq3ZmB43CndwXYwPSzyYn4dWxermqJRI4Np3rFlqODasWRcTtAaT1zCHYSbVU3
r4nsyrdPMKTUFKDYiE4yfLEoePIbsQpqfy3_nOVMuJIqg0wk1RFg7GOuWfwEbz2wIDLVatR_VtLyBagNTHF
IUMCqtoZXeIfAOU1JoUJsR2IC3nWTMjt7GM4yKdyBhlAMpesvhydCC0y_i0ZagHByMh26WzUhXUUxKnpbcV
nBfUwhznJnNlac7JkuIURL-2VVfwxflyrWcSQIAAA==)):
```svelte
<!file: App.svelte>
<script>
import Child from './Child.svelte';
```svelte
<!file: Child.svelte>
<script>
let { object } = $props();
</script>
The fallback value of a prop not declared with `$bindable` is left untouched — it
is not turned into a reactive state proxy — meaning mutations will not cause
updates
([demo](/playground/untitled#H4sIAAAAAAAAE3WQwU7DMBBEf2VkIbUVoYFraCIh7vwA4eC4G9Wta1
vxpgJZ_nfkBEQp9OjxzOzTRGHlkUQlXpy9G0gq1idCL43ppDrAD84HUYheGwqieo2CP3y2Z0EU3-
En79fhRIaz1slA_-nKWSbLQVRiE9SgPTetbVkfvRsYzztttugHd8RiXU6vr-
jisbWb8idhN7O3bEQhmN5ZVDyMlIorcOddv_Eufq4AGmJEuG5PilEjQrnRcoV7JCTUuJlGWq7-
YHYjs7NwVhmtDnVcrlA3iLmzLLGTAdaB-j736h68Oxv-
JM1I0AFjoG1OzPfX023c1nhobUoT39QeKsRzS8owM8DFTG_pE6dcVl70AQAA))
```svelte
<!file: Child.svelte>
<script>
let { object = { count: 0 } } = $props();
</script>
In summary: don't mutate props. Either use callback props to communicate changes,
or — if parent and child should share the same object — use the [`$bindable`]
($bindable) rune.
## Type safety
You can add type safety to your components by annotating your props, as you would
with any other variable declaration. In TypeScript that might look like this...
```svelte
<script lang="ts">
let { adjective }: { adjective: string } = $props();
</script>
```
```svelte
<script>
/** @type {{ adjective: string }} */
let { adjective } = $props();
</script>
```
You can, of course, separate the type declaration from the annotation:
```svelte
<script lang="ts">
interface Props {
adjective: string;
}
Adding types is recommended, as it ensures that people using your component can
easily discover which props they should provide.
## `$props.id()`
This rune, added in version 5.20.0, generates an ID that is unique to the current
component instance. When hydrating a server-rendered component, the value will be
consistent between server and client.
This is useful for linking elements via attributes like `for` and `aria-
labelledby`.
```svelte
<script>
const uid = $props.id();
</script>
<form>
<label for="{uid}-firstname">First Name: </label>
<input id="{uid}-firstname" type="text" />
## docs/svelte/02-runes/06-$bindable.md
---
title: $bindable
---
Ordinarily, props go one way, from parent to child. This makes it easy to
understand how data flows around your app.
In Svelte, component props can be _bound_, which means that data can also flow _up_
from child to parent. This isn't something you should do often, but it can simplify
your code if used sparingly and carefully.
<style>
input {
font-family: 'Comic Sans MS';
color: deeppink;
}
</style>
```
Now, a component that uses `<FancyInput>` can add the [`bind:`](bind) directive
([demo](/playground/untitled#H4sIAAAAAAAAE3WQwWrDMBBEf2URBSfg2nfFMZRCoYeecqx6UJx1Iy
qvhLUONcb_XqSkTUOSk1az7DBvJtEai0HI90nw6FHIJIhckO7i78n7IhzQctS2OuAtvXHESByEFFVoeuO5V
qTYdN71DC-amvGV_MDQ9q6DrCjP0skkWymKJxYZOgxBfyKs4SGwZlxke7TWZcuVoqo8-
1P1z3lraCcP2g64nk4GM5S1osrXf0JV-lrkgvGbheR-wDm_g30V8JL-
1vpOCZFogpQsEsWcemtxscyhKArfOx9gjps0Lq4hzRVfemaYfu-
PoIqqwKPFY_XpaIqj4tYRP7a6M3aUkD27zjSw0RTgbZN6Z8WNs66XsEP03tBXUueUJFlelvYx_wCuI3leNw
IAAA==)):
```svelte
/// file: App.svelte
<script>
import FancyInput from './FancyInput.svelte';
The parent component doesn't _have_ to use `bind:` — it can just pass a normal
prop. Some parents don't want to listen to what their children have to say.
In this case, you can specify a fallback value for when no prop is passed at all:
```js
/// file: FancyInput.svelte
let { value = $bindable('fallback'), ...props } = $props();
```
## docs/svelte/02-runes/07-$inspect.md
---
title: $inspect
---
The `$inspect` rune is roughly equivalent to `console.log`, with the exception that
it will re-run whenever its argument changes. `$inspect` tracks reactive state
deeply, meaning that updating something inside an object or array using fine-
grained reactivity will cause it to re-fire
([demo](/playground/untitled#H4sIAAAAAAAACkWQ0YqDQAxFfyUMhSotdZ-
tCvu431AXtGOqQ2NmmMm0LOK_r7Utfby5JzeXTOpiCIPKT5PidkSVq2_n1F7Jn3uIcEMSXHSw0evHpAjaGy
dVzbUQCmgbWaCETZBWMPlKj29nxBDaHj_edkAiu12JhdkYDg61JGvE_s2nR8gyuBuiJZuDJTyQ7eE-
IEOzog1YD80Lb0APLfdYc5F9qnFxjiKWwbImo6_llKRQVs-
2u91c_bD2OCJLkT3JZasw7KLA2XCX31qKWE6vIzNk1fKE0XbmYrBTufiI8-_8D2cUWBA_AQAA)):
```svelte
<script>
let count = $state(0);
let message = $state('hello');
## $inspect(...).with
`$inspect` returns a property `with`, which you can invoke with a callback, which
will then be invoked instead of `console.log`. The first argument to the callback
is either `"init"` or `"update"`; subsequent arguments are the values passed to
`$inspect` ([demo](/playground/untitled#H4sIAAAAAAAACkVQ24qDMBD9lSEUqlTqPlsj7ON-
w7pQG8c2VCchmVSK-O-bKMs-
DefKYRYx6BG9qL4XQd2EohKf1opC8Nsm4F84MkbsTXAqMbVXTltuWmp5RAZlAjFIOHjuGLOP_BKVqB00eYu
Ks82Qn2fNjyxLtcWeyUE2sCRry3qATQIpJRyD7WPVMf9TW-
7xFu53dBcoSzAOrsqQNyOe2XUKr0Xi5kcMvdDB2wSYO-I9vKazplV1-T-
d6ltgNgSG1KjVUy7ZtmdbdjqtzRcphxMS1-XubOITJtPrQWMvKnYB15_1F7KKadA_AQAA)):
```svelte
<script>
let count = $state(0);
```js
// @errors: 2304
$inspect(stuff).with(console.trace);
```
## $inspect.trace(...)
```svelte
<script>
import { doSomeWork } from './elsewhere';
$effect(() => {
$inspect.trace();
doSomeWork();
});
</script>
```
`$inspect.trace` takes an optional first argument which will be used as the label.
## docs/svelte/02-runes/08-$host.md
---
title: $host
---
When compiling a component as a custom element, the `$host` rune provides access to
the host element, allowing you to (for example) dispatch custom events
([demo](/playground/untitled#H4sIAAAAAAAAE41Ry2rDMBD8FSECtqkTt1fHFpSSL-
ix7sFRNkTEXglrnTYY_3uRlDgxTaEHIfYxs7szA9-
rBizPPwZOZwM89wmecqxbF70as7InaMjltrWFR3mpkQDJ8pwXVnbKkKiwItUa3RGLVtk7gTHQXRDR2lXda4
CY1D0SK9nCUk0QPyfrCovsRoNFe17aQOAwGncgO2gBqRzihJXiQrEs2csYOhQ-7HgKHaLIbpRhhBG-
I2eD_8ciM4KnnOCbeE5dD2P6h0Dz0-
Yi_arNhPLJXBtSGi2TvSXdbpqwdsXvjuYsC1veabvvUTog2ylrapKH2G2XsMFLS4uDthQnq2t1cwKkGOGLv
YU5PvaQxLsxOkPmsm97Io1Mo2yUPF6VnOZFkw1RMoopKLKAE_9gmGxyDFMwMcwN-Bx_ABXQWmOtAgAA)):
```svelte
/// file: Stepper.svelte
<svelte:options customElement="my-stepper" />
<script>
function dispatch(type) {
$host().dispatchEvent(new CustomEvent(type));
}
</script>
```svelte
/// file: App.svelte
<script>
import './Stepper.svelte';
<my-stepper
ondecrement={() => count -= 1}
onincrement={() => count += 1}
></my-stepper>
<p>count: {count}</p>
```
## docs/svelte/03-template-syntax/index.md
---
## docs/svelte/03-template-syntax/01-basic-markup.md
---
## Tags
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag or
a tag that uses dot notation, such as `<Widget>` or `<my.stuff>`, indicates a
_component_.
```svelte
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget />
</div>
```
## Element attributes
```svelte
<div class="foo">
<button disabled>can't touch this</button>
</div>
```
```svelte
<input type=checkbox />
```
```svelte
<a href="page/{p}">page {p}</a>
```
```svelte
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>
```
>
> <!-- prettier-ignore -->
> ```svelte
> <button disabled="{number !== 42}">...</button>
> ```
When the attribute name and value match (`name={name}`), they can be replaced with
`{name}`.
```svelte
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->
```
## Component props
```svelte
<Widget foo={bar} answer={42} text="hello" />
```
```svelte
<Widget {...things} />
```
## Events
Listening to DOM events is possible by adding attributes to the element that start
with `on`. For example, to listen to the `click` event, add the `onclick` attribute
to a button:
```svelte
<button onclick={() => console.log('clicked')}>click me</button>
```
Event attributes are case sensitive. `onclick` listens to the `click` event,
`onClick` listens to the `Click` event, which is different. This ensures you can
listen to custom events that have uppercase characters in them.
Because events are just attributes, the same rules as for attributes apply:
Timing-wise, event attributes always fire after events from bindings (e.g.
`oninput` always fires after an update to `bind:value`). Under the hood, some event
handlers are attached directly with `addEventListener`, while others are
_delegated_.
When using `ontouchstart` and `ontouchmove` event attributes, the handlers are
[passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/
addEventListener#using_passive_listeners) for better performance. This greatly
improves responsiveness by allowing the browser to scroll the document immediately,
rather than waiting to see if the event handler calls `event.preventDefault()`.
In the very rare cases that you need to prevent these event defaults, you should
use [`on`](svelte-events#on) instead (for example inside an action).
To reduce memory footprint and increase performance, Svelte uses a technique called
event delegation. This means that for certain events — see the list below — a
single event listener at the application root takes responsibility for running any
handlers on the event's path.
- when you manually dispatch an event with a delegated listener, make sure to set
the `{ bubbles: true }` option or it won't reach the application root
- when using `addEventListener` directly, avoid calling `stopPropagation` or the
event won't reach the application root and handlers won't be invoked. Similarly,
handlers added manually inside the application root will run _before_ handlers
added declaratively deeper in the DOM (with e.g. `onclick={...}`), in both
capturing and bubbling phases. For these reasons it's better to use the `on`
function imported from `svelte/events` rather than `addEventListener`, as it will
ensure that order is preserved and `stopPropagation` is handled correctly.
- `beforeinput`
- `click`
- `change`
- `dblclick`
- `contextmenu`
- `focusin`
- `focusout`
- `input`
- `keydown`
- `keyup`
- `mousedown`
- `mousemove`
- `mouseout`
- `mouseover`
- `mouseup`
- `pointerdown`
- `pointermove`
- `pointerout`
- `pointerover`
- `pointerup`
- `touchend`
- `touchmove`
- `touchstart`
## Text expressions
```svelte
{expression}
```
Curly braces can be included in a Svelte template by using their [HTML entity]
(https://developer.mozilla.org/docs/Glossary/Entity) strings: `{`, `{`,
or `{` for `{` and `}`, `}`, or `}` for `}`.
```svelte
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
The expression will be stringified and escaped to prevent code injections. If you
want to render HTML, use the `{@html}` tag instead.
```svelte
{@html potentiallyUnsafeHtmlString}
```
## Comments
```svelte
<!-- this is a comment! --><h1>Hello world</h1>
```
Comments beginning with `svelte-ignore` disable warnings for the next block of
markup. Usually, these are accessibility warnings; make sure that you're disabling
them for a good reason.
```svelte
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />
```
You can add a special comment starting with `@component` that will show up when
hovering over the component name in other files.
````svelte
<!--
@component
You can use markdown here.
You can also use code blocks here.
Usage:
```html
<Main name="Arethra">
```
-->
<script>
let { name } = $props();
</script>
<main>
<h1>
Hello, {name}
</h1>
</main>
````
## docs/svelte/03-template-syntax/02-if.md
---
```svelte
<!copy: false>
{#if expression}...{/if}
```
```svelte
<!copy: false>
{#if expression}...{:else if expression}...{/if}
```
```svelte
<!copy: false>
{#if expression}...{:else}...{/if}
```
```svelte
{#if answer === 42}
<p>what was the question?</p>
{/if}
```
Additional conditions can be added with `{:else if expression}`, optionally ending
in an `{:else}` clause.
```svelte
{#if porridge.temperature > 100}
<p>too hot!</p>
{:else if 80 > porridge.temperature}
<p>too cold!</p>
{:else}
<p>just right!</p>
{/if}
```
(Blocks don't have to wrap elements, they can also wrap text within elements.)
## docs/svelte/03-template-syntax/03-each.md
---
```svelte
<!copy: false>
{#each expression as name}...{/each}
```
```svelte
<!copy: false>
{#each expression as name, index}...{/each}
```
Iterating over values can be done with an each block. The values in question can be
arrays, array-like objects (i.e. anything with a `length` property), or iterables
like `Map` and `Set` — in other words, anything that can be used with `Array.from`.
```svelte
<h1>Shopping list</h1>
<ul>
{#each items as item}
<li>{item.name} x {item.qty}</li>
{/each}
</ul>
```
An each block can also specify an _index_, equivalent to the second argument in an
`array.map(...)` callback:
```svelte
{#each items as item, i}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```
```svelte
<!copy: false>
{#each expression as name (key)}...{/each}
```
```svelte
<!copy: false>
{#each expression as name, index (key)}...{/each}
```
If a _key_ expression is provided — which must uniquely identify each list item —
Svelte will use it to diff the list when data changes, rather than adding or
removing items at the end. The key can be any object, but strings and numbers are
recommended since they allow identity to persist when the objects themselves
change.
```svelte
{#each items as item (item.id)}
<li>{item.name} x {item.qty}</li>
{/each}
You can freely use destructuring and rest patterns in each blocks.
```svelte
{#each items as { id, name, qty }, i (id)}
<li>{i + 1}: {name} x {qty}</li>
{/each}
```svelte
<!copy: false>
{#each expression}...{/each}
```
```svelte
<!copy: false>
{#each expression, index}...{/each}
```
In case you just want to render something `n` times, you can omit the `as` part
([demo](/playground/untitled#H4sIAAAAAAAAE3WR0W7CMAxFf8XKNAk0WsSeUEaRpn3Guoc0MbQiJF
HiMlDVf18SOrZJ48259_jaVgZmxBEZZ28thgCNFV6xBdt1GgPj7wOji0t2EqI-
wa_OleGEmpLWiID_6dIaQkMxhm1UdwKpRQhVzWSaVORJNdvWpqbhAYVsYQCNZk8thzWMC_DCHMZk3wPSThN
Q088I3mghD9UwSwHwlLE5PMIzVFUFq3G7WUZ2OyUvU3JOuZU332wCXTRmtPy1NgzXZtUFp8WFw9536uWqpb
IgPEaDsJBW90cTOHh0KGi2XsBq5-cT6-
3nPauxXqHnsHJnCFZ3CvJVkyuCQ0mFF9TZyCQ162WGvteLKfG197Y3iv_pz_fmS68Hxt8iPBPj5HscP8YvC
NX7uhYCAAA=)):
```svelte
<div class="chess-board">
{#each { length: 8 }, rank}
{#each { length: 8 }, file}
<div class:black={(rank + file) % 2 === 1}></div>
{/each}
{/each}
</div>
```
## Else blocks
```svelte
<!copy: false>
{#each expression as name}...{:else}...{/each}
```
An each block can also have an `{:else}` clause, which is rendered if the list is
empty.
```svelte
{#each todos as todo}
<p>{todo.text}</p>
{:else}
<p>No tasks today!</p>
{/each}
```
## docs/svelte/03-template-syntax/04-key.md
---
```svelte
<!copy: false>
{#key expression}...{/key}
```
Key blocks destroy and recreate their contents when the value of an expression
changes. When used around components, this will cause them to be reinstantiated and
reinitialised:
```svelte
{#key value}
<Component />
{/key}
```
It's also useful if you want a transition to play whenever a value changes:
```svelte
{#key value}
<div transition:fade>{value}</div>
{/key}
```
## docs/svelte/03-template-syntax/05-await.md
---
```svelte
<!copy: false>
{#await expression}...{:then name}...{:catch name}...{/await}
```
```svelte
<!copy: false>
{#await expression}...{:then name}...{/await}
```
```svelte
<!copy: false>
{#await expression then name}...{/await}
```
```svelte
<!copy: false>
{#await expression catch name}...{/await}
```
Await blocks allow you to branch on the three possible states of a [`Promise`]
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/
Promise) — pending, fulfilled or rejected.
```svelte
{#await promise}
<!-- promise is pending -->
<p>waiting for the promise to resolve...</p>
{:then value}
<!-- promise was fulfilled or not a Promise -->
<p>The value is {value}</p>
{:catch error}
<!-- promise was rejected -->
<p>Something went wrong: {error.message}</p>
{/await}
```
>
> If the provided expression is not a `Promise`, only the `:then` branch will be
rendered, including during server-side rendering.
The `catch` block can be omitted if you don't need to render anything when the
promise rejects (or no error is possible).
```svelte
{#await promise}
<!-- promise is pending -->
<p>waiting for the promise to resolve...</p>
{:then value}
<!-- promise was fulfilled -->
<p>The value is {value}</p>
{/await}
```
If you don't care about the pending state, you can also omit the initial block.
```svelte
{#await promise then value}
<p>The value is {value}</p>
{/await}
```
Similarly, if you only want to show the error state, you can omit the `then` block.
```svelte
{#await promise catch error}
<p>The error is {error}</p>
{/await}
```
>
> ```svelte
> {#await import('./Component.svelte') then { default: Component }}
> <Component />
> {/await}
> ```
## docs/svelte/03-template-syntax/06-snippet.md
---
```svelte
<!copy: false>
{#snippet name()}...{/snippet}
```
```svelte
<!copy: false>
{#snippet name(param1, param2, paramN)}...{/snippet}
```
Snippets, and [render tags](@render), are a way to create reusable chunks of markup
inside your components. Instead of writing duplicative code like
[this](/playground/untitled#H4sIAAAAAAAAE5VUYW-kIBD9K8Tmsm2yXXRzvQ-s3eR-R-
0HqqOQKhAZb9sz_vdDkV1t000vRmHewMx7w2AflbIGG7GnPlK8gYhFv42JthG-
m9Gwf6BGcLbVXZuPSGrzVho8ZirDGpDIhldgySN5GpEMez9kaNuckY1ANJZRamRuu2ZnhEZt6a84pvs43mz
D4pMsUDDi8DMkQFYCGdkvsJwblFq5uCik9bmJ4JZwUkv1eoknWigX2eGNN6aGXa6bjV8ybP-
X7sM36T58SVcrIIV2xVIaA41xeD5kKqWXuqpUJEefOqVuOkL9DfBchGrzWfu0vb-RpTd3o-
zBR045Ga3HfuE5BmJpKauuhbPtENlUF2sqR9jqpsPSxWsMrlngyj3VJiyYjJXb1-lMa7IWC-iSk2M5Zzh-
SJjShe-siq5kpZRPs55BbSGU5YPyte4vVV_VfFXxVb10dSLf17pS2lM5HnpPxw4Zpv6x-
F57p0jI3OKlVnhv5V9wPQrNYQQ9D_f6aGHlC89fq1Z3qmDkJCTCweOGF4VUFSPJvD_DhreVdA0eu8ehJJ5x
91dBaBkpWm3ureCFPt3uzRv56d4kdp-2euG38XZ6dsnd3ZmPG9yRBCrzRUvi-MccOdwz3qE-
fOZ7AwAhlrtTUx3c76vRhSwlFBHDtoPhefgHX3dM0PkEAAA=)...
```svelte
{#each images as image}
{#if image.href}
<a href={image.href}>
<figure>
<img src={image.src} alt={image.caption}
width={image.width} height={image.height} />
<figcaption>{image.caption}</figcaption>
</figure>
</a>
{:else}
<figure>
<img src={image.src} alt={image.caption} width={image.width}
height={image.height} />
<figcaption>{image.caption}</figcaption>
</figure>
{/if}
{/each}
```
```svelte
{#snippet figure(image)}
<figure>
<img src={image.src} alt={image.caption} width={image.width}
height={image.height} />
<figcaption>{image.caption}</figcaption>
</figure>
{/snippet}
## Snippet scope
Snippets can be declared anywhere inside your component. They can reference values
declared outside themselves, for example in the `<script>` tag or in `{#each ...}`
blocks ([demo](/playground/untitled#H4sIAAAAAAAAE12P0QrCMAxFfyWrwhSEvc8p-
h1OcG5RC10bmkyQ0n-
3HQPBx3vCPUmCemiDrOpLULYbUdXqTKR2Sj6UA7_RCKbMbvJ9Jg33XpMcW9uKQYEAIzJ3T4QD3LSUDE-
PnYA4YET4uOkGMc3W5B3xZrtvbVP9HDas2GqiZHqhMW6Tr9jGbG_oOCMImcUCwrIpFk1FqRyqpRpn0cmjHd
AvnrIzuscyq_4nd3dPPD01ukE_NA6qFj9hvMYvGjJADw8BAAA=))...
```svelte
<script>
let { message = `it's great to see you!` } = $props();
</script>
{#snippet hello(name)}
<p>hello {name}! {message}!</p>
{/snippet}
{@render hello('alice')}
{@render hello('bob')}
```
...and they are 'visible' to everything in the same lexical scope (i.e. siblings,
and children of those siblings):
```svelte
<div>
{#snippet x()}
{#snippet y()}...{/snippet}
```svelte
{#snippet blastoff()}
<span>🚀</span>
{/snippet}
{#snippet countdown(n)}
{#if n > 0}
<span>{n}...</span>
{@render countdown(n - 1)}
{:else}
{@render blastoff()}
{/if}
{/snippet}
{@render countdown(10)}
```
Within the template, snippets are values just like any other. As such, they can be
passed to components as props
([demo](/playground/untitled#H4sIAAAAAAAAE3VS247aMBD9lZGpBGwDASRegonaPvQL2qdlH5zYEK
vBNvbQLbL875VzAcKyj3PmzJnLGU8UOwqSkd8KJdaCk4TsZS0cyV49wYuJuQiQpGd-
N2bu_ooaI1YwJ57hpVYoFDqSEepKKw3mO7VDeTTaIvxiRS1gb_URxvO0ibrS8WanIrHUyiHs7Vmigy28Rmy
HHmKvDMbMmFq4cQInvGSwTsBYWYoMVhCSB2rBFFPsyl0uruTlR3JZCWvlTXl1Yy_mawiR_rbZKZrellJ-
5JQ0RiBUgnFhJ9OGR7HKmwVoilXeIye8DOJGfYCgRlZ3iE876TBsZPX7hPdteO75PC4QaIo8vwNPePmANQ2
fMeEFHrLD7rR1jTNkW986E8C3KwfwVr8HSHOSEBT_kGRozyIkn_zQveXDL3rIfPJHtUDwzShJd_Qk3gQCbO
GLsdq4yfTRJopRuin3I7nv6kL7ARRjmLdBDG3uv1mhuLA3V2mKtqNEf_oCn8p9aN-
WYqH5peP4kWBl1UwJzAEPT9U7K--
0fRrrWnPTXpCm1_EVdXjpNmlA8G1hPPyM1fKgMqjFHjctXGjLhZ05w0qpDhksGrybuNEHtJnCalZWsuaTlf
q6nPaaBSv_HKw-
K57BjzOiVj9ZKQYKzQjZodYFqydYTRN4gPhVzTDO2xnma3HsVWjaLjT8nbfwHy7Q5f2dBAAA)):
```svelte
<script>
import Table from './Table.svelte';
const fruits = [
{ name: 'apples', qty: 5, price: 2 },
{ name: 'bananas', qty: 10, price: 1 },
{ name: 'cherries', qty: 20, price: 0.5 }
];
</script>
{#snippet header()}
<th>fruit</th>
<th>qty</th>
<th>price</th>
<th>total</th>
{/snippet}
{#snippet row(d)}
<td>{d.name}</td>
<td>{d.qty}</td>
<td>{d.price}</td>
<td>{d.qty * d.price}</td>
{/snippet}
Think about it like passing content instead of data to a component. The concept is
similar to slots in web components.
```svelte
<!-- this is semantically the same as the above -->
<Table data={fruits}>
{#snippet header()}
<th>fruit</th>
<th>qty</th>
<th>price</th>
<th>total</th>
{/snippet}
{#snippet row(d)}
<td>{d.name}</td>
<td>{d.qty}</td>
<td>{d.price}</td>
<td>{d.qty * d.price}</td>
{/snippet}
</Table>
```
Any content inside the component tags that is _not_ a snippet declaration
implicitly becomes part of the `children` snippet
([demo](/playground/untitled#H4sIAAAAAAAAE3WOQQrCMBBFrzIMggql3ddY1Du4si5sOmIwnYRkFK
X07lKqglqX8_7_w2uRDw1hjlsWI5ZqTPBoLEXMdy3K3fdZDzB5Ndfep_FKVnpWHSKNce1YiCVijirqYLwUJ
QOYxrsgsLmIOIZjcA1M02w4n-
PpomSVvTclqyEutDX6DA2pZ7_ABIVugrmEC3XJH92P55_G39GodCmWBFrQJ2PrQAwdLGHig_NxNv9xrQa1d
hWIawrv1Wzeqawa8953D-8QOmaEAQAA)):
```svelte
<!file: App.svelte>
<Button>click me</Button>
```
```svelte
<!file: Button.svelte>
<script>
let { children } = $props();
</script>
You can declare snippet props as being optional. You can either use optional
chaining to not render anything if the snippet isn't set...
```svelte
<script>
let { children } = $props();
</script>
{@render children?.()}
```
```svelte
<script>
let { children } = $props();
</script>
{#if children}
{@render children()}
{:else}
fallback content
{/if}
```
## Typing snippets
```svelte
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
data: any[];
children: Snippet;
row: Snippet<[any]>;
}
With this change, red squigglies will appear if you try and use the component
without providing a `data` prop and a `row` snippet. Notice that the type argument
provided to `Snippet` is a tuple, since snippets can have multiple parameters.
We can tighten things up further by declaring a generic, so that `data` and `row`
refer to the same type:
```svelte
<script lang="ts" generics="T">
import type { Snippet } from 'svelte';
let {
data,
children,
row
}: {
data: T[];
children: Snippet;
row: Snippet<[T]>;
} = $props();
</script>
```
## Exporting snippets
Snippets declared at the top level of a `.svelte` file can be exported from a
`<script module>` for use in other components, provided they don't reference any
declarations in a non-module `<script>` (whether directly or indirectly, via other
snippets)
([demo](/playground/untitled#H4sIAAAAAAAAE3WPwY7CMAxEf8UyB1hRgdhjl13Bga8gHFJipEqtGy
UGFUX5dxJUtEB3b9bYM_MckHVLWOKut50TMuC5tpbEY4GnuiGP5T6gXG0-
ykLSB8vW2oW_UCNZq7Snv_Rjx0Kc4kpc-6OrrfwoVlK3uQ4CaGMgwsl1LUwXy0f54J9-
KV4vf20cNo7YkMu22aqAz4-oOLUI9YKluDPF4h_at-
hX5PFyzA1tZ84N3fGpf8YfUU6GvDumLqDKmEqCjjCHUEX4hqDTWCU5PJ6Or38c4g1cPu9tnAEAAA==)):
```svelte
<script module>
export { add };
</script>
## Programmatic snippets
## docs/svelte/03-template-syntax/07-@render.md
---
```svelte
{#snippet sum(a, b)}
<p>{a} + {b} = {a + b}</p>
{/snippet}
```svelte
{@render (cool ? coolSnippet : lameSnippet)()}
```
## Optional snippets
```svelte
{@render children?.()}
```
```svelte
{#if children}
{@render children()}
{:else}
<p>fallback content</p>
{/if}
```
## docs/svelte/03-template-syntax/08-@html.md
---
To inject raw HTML into your component, use the `{@html ...}` tag:
```svelte
<article>
{@html content}
</article>
```
The expression should be valid standalone HTML — this will not work, because
`</div>` is not valid HTML:
```svelte
{@html '<div>'}content{@html '</div>'}
```
## Styling
Content rendered this way is 'invisible' to Svelte and as such will not receive
[scoped styles](scoped-styles) — in other words, this will not work, and the `a`
and `img` styles will be regarded as unused:
```svelte
<article>
{@html content}
</article>
<style>
article {
a { color: hotpink }
img { width: 100% }
}
</style>
```
Instead, use the `:global` modifier to target everything inside the `<article>`:
```svelte
<style>
article:global{
a { color: hotpink }
img { width: 100% }
}
</style>
```
## docs/svelte/03-template-syntax/09-@const.md
---
```svelte
{#each boxes as box}
{@const area = box.width * box.height}
{box.width} * {box.height} = {area}
{/each}
```
## docs/svelte/03-template-syntax/10-@debug.md
---
```svelte
<script>
let user = {
firstname: 'Ada',
lastname: 'Lovelace'
};
</script>
{@debug user}
<h1>Hello {user.firstname}!</h1>
```
```svelte
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}
The `{@debug}` tag without any arguments will insert a `debugger` statement that
gets triggered when _any_ state changes, as opposed to the specified variables.
## docs/svelte/03-template-syntax/11-bind.md
---
title: bind:
---
Data ordinarily flows down, from parent to child. The `bind:` directive allows data
to flow the other way, from child to parent.
```svelte
<input bind:value={value} />
<input bind:value />
```
Svelte creates an event listener that updates the bound value. If an element
already has a listener for the same event, that listener will be fired before the
bound value is updated.
Most bindings are _two-way_, meaning that changes to the value will affect the
element and vice versa. A few bindings are _readonly_, meaning that changing their
value will have no effect on the element.
## Function bindings
You can also use `bind:property={get, set}`, where `get` and `set` are functions,
allowing you to perform validation and transformation:
```svelte
<input bind:value={
() => value,
(v) => value = v.toLowerCase()}
/>
```
```svelte
<div
bind:clientWidth={null, redraw}
bind:clientHeight={null, redraw}
>...</div>
```
## `<input bind:value>`
```svelte
<script>
let message = $state('hello');
</script>
```svelte
<script>
let a = $state(1);
let b = $state(2);
</script>
<label>
<input type="number" bind:value={a} min="0" max="10" />
<input type="range" bind:value={a} min="0" max="10" />
</label>
<label>
<input type="number" bind:value={b} min="0" max="10" />
<input type="range" bind:value={b} min="0" max="10" />
</label>
If the input is empty or invalid (in the case of `type="number"`), the value is
`undefined`.
```svelte
<script>
let value = $state('');
</script>
<form>
<input bind:value defaultValue="not the empty string">
<input type="reset" value="Reset">
</form>
```
> Use reset buttons sparingly, and ensure that users won't accidentally click them
while trying to submit the form.
## `<input bind:checked>`
```svelte
<label>
<input type="checkbox" bind:checked={accepted} />
Accept terms and conditions
</label>
```
```svelte
<script>
let checked = $state(true);
</script>
<form>
<input type="checkbox" bind:checked defaultChecked={true}>
<input type="reset" value="Reset">
</form>
```
## `<input bind:group>`
```svelte
<script>
let tortilla = $state('Plain');
## `<input bind:files>`
On `<input>` elements with `type="file"`, you can use `bind:files` to get the
[`FileList` of selected
files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). When you want to
update the files programmatically, you always need to use a `FileList` object.
Currently `FileList` objects cannot be constructed directly, so you need to create
a new [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/
DataTransfer) object and get `files` from there.
```svelte
<script>
let files = $state();
function clear() {
files = new DataTransfer().files; // null or undefined does not work
}
</script>
`FileList` objects also cannot be modified, so if you want to e.g. delete a single
file from the list, you need to create a new `DataTransfer` object and add the
files you want to keep.
## `<select bind:value>`
```svelte
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b}>b</option>
<option value={c}>c</option>
</select>
```
When the value of an `<option>` matches its text content, the attribute can be
omitted.
```svelte
<select multiple bind:value={fillings}>
<option>Rice</option>
<option>Beans</option>
<option>Cheese</option>
<option>Guac (extra)</option>
</select>
```
You can give the `<select>` a default value by adding a `selected` attribute to
the`<option>` (or options, in the case of `<select multiple>`) that should be
initially selected. If the `<select>` is part of a form, it will revert to that
selection when the form is reset. Note that for the initial render the value of the
binding takes precedence if it's not `undefined`.
```svelte
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b} selected>b</option>
<option value={c}>c</option>
</select>
```
## `<audio>`
`<audio>` elements have their own set of bindings — five two-way ones...
-
[`currentTime`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
currentTime)
- [`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/
HTMLMediaElement/playbackRate)
- [`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
paused)
- [`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
volume)
- [`muted`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
muted)
- [`duration`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
duration)
- [`buffered`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
buffered)
- [`seekable`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
seekable)
- [`seeking`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
seeking_event)
- [`ended`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
ended)
-
[`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
readyState)
```svelte
<audio src={clip} bind:duration bind:currentTime bind:paused></audio>
```
## `<video>`
`<video>` elements have all the same bindings as [`<audio>`](#audio) elements, plus
readonly
[`videoWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/
videoWidth) and
[`videoHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/
videoHeight) bindings.
## `<img>`
- [`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/
HTMLImageElement/naturalWidth)
- [`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/
HTMLImageElement/naturalHeight)
## `<details bind:open>`
```svelte
<details bind:open={isOpen}>
<summary>How do you comfort a JavaScript bug?</summary>
<p>You console it.</p>
</details>
```
## Contenteditable bindings
- [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
- [`innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/
innerText)
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/
textContent)
<!-- for some reason puts the comment and html on same line -->
```svelte
<div contenteditable="true" bind:innerHTML={html}></div>
```
## Dimensions
All visible elements have the following readonly bindings, measured with a
`ResizeObserver`:
- [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/
clientWidth)
- [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/
clientHeight)
- [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/
offsetWidth)
- [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/
offsetHeight)
```svelte
<div bind:offsetWidth={width} bind:offsetHeight={height}>
<Chart {width} {height} />
</div>
```
## bind:this
```svelte
<!copy: false>
bind:this={dom_node}
```
To get a reference to a DOM node, use `bind:this`. The value will be `undefined`
until the component is mounted — in other words, you should read it inside an
effect or an event handler, but not during component initialisation:
```svelte
<script>
/** @type {HTMLCanvasElement} */
let canvas;
$effect(() => {
const ctx = canvas.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvas}></canvas>
```
```svelte
<!file: App.svelte>
<ShoppingCart bind:this={cart} />
```svelte
<!file: ShoppingCart.svelte>
<script>
// All instance exports are available on the instance object
export function empty() {
// ...
}
</script>
```
```svelte
bind:property={variable}
```
You can bind to component props using the same syntax as for elements.
```svelte
<Keypad bind:value={pin} />
```
While Svelte props are reactive without binding, that reactivity only flows
downward into the component by default. Using `bind:property` allows changes to the
property from within the component to flow back up out of the component.
```svelte
<script>
let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
```
Declaring a property as bindable means it _can_ be used using `bind:`, not that it
_must_ be used using `bind:`.
```svelte
<script>
let { bindableProperty = $bindable('fallback value') } = $props();
</script>
```
This fallback value _only_ applies when the property is _not_ bound. When the
property is bound and a fallback value is present, the parent is expected to
provide a value other than `undefined`, else a runtime error is thrown. This
prevents hard-to-reason-about situations where it's unclear which value should
apply.
## docs/svelte/03-template-syntax/12-use.md
---
title: use:
---
Actions are functions that are called when an element is mounted. They are added
with the `use:` directive, and will typically use an `$effect` so that they can
reset any state when the element is unmounted:
```svelte
<!file: App.svelte>
<script>
/** @type {import('svelte/action').Action} */
function myaction(node) {
// the node has been mounted in the DOM
$effect(() => {
// setup goes here
return () => {
// teardown goes here
};
});
}
</script>
<div use:myaction>...</div>
```
```svelte
<!file: App.svelte>
<script>
/** @type {import('svelte/action').Action} */
function myaction(node,data) {
// ...
}
</script>
<div use:myaction={data}>...</div>
```
The action is only called once (but not during server-side rendering) — it will
_not_ run again if the argument changes.
> [!LEGACY]
> Prior to the `$effect` rune, actions could return an object with `update` and
`destroy` methods, where `update` would be called with the latest value of the
argument if it changed. Using effects is preferred.
## Typing
The `Action` interface receives three optional type arguments — a node type (which
can be `Element`, if the action applies to everything), a parameter, and any custom
event handlers created by the action:
```svelte
<!file: App.svelte>
<script>
/**
* @type {import('svelte/action').Action<
* HTMLDivElement,
* undefined,
* {
* onswiperight: (e: CustomEvent) => void;
* onswipeleft: (e: CustomEvent) => void;
* // ...
* }
* >}
*/
function gestures(node) {
$effect(() => {
// ...
node.dispatchEvent(new CustomEvent('swipeleft'));
// ...
node.dispatchEvent(new CustomEvent('swiperight'));
});
}
</script>
<div
use:gestures
onswipeleft={next}
onswiperight={prev}
>...</div>
```
## docs/svelte/03-template-syntax/13-transition.md
---
title: transition:
---
When a block (such as an `{#if ...}` block) is transitioning out, all elements
inside it, including those that do not have their own transitions, are kept in the
DOM until every transition in the block has been completed.
```svelte
<script>
import { fade } from 'svelte/transition';
{#if visible}
<divtransition:fade>fades in and out</div>
{/if}
```
## Built-in transitions
## Local vs global
Transitions are local by default. Local transitions only play when the block they
belong to is created or destroyed, _not_ when parent blocks are created or
destroyed.
```svelte
{#if x}
{#if y}
<p transition:fade>fades in and out only when y changes</p>
## Transition parameters
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside
an expression tag.)
```svelte
{#if visible}
<div transition:fade={{ duration: 2000 }}>fades in and out over two
seconds</div>
{/if}
```
```js
/// copy: false
// @noErrors
transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' |
'both' }) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
css?: (t: number, u: number) => string,
tick?: (t: number, u: number) => void
}
```
Transitions can use custom functions. If the returned object has a `css` function,
Svelte will generate keyframes for a [web
animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
The `t` argument passed to `css` is a value between `0` and `1` after the `easing`
function has been applied. _In_ transitions run from `0` to `1`, _out_ transitions
run from `1` to `0` — in other words, `1` is the element's natural state, as though
no transition had been applied. The `u` argument is equal to `1 - t`.
The function is called repeatedly _before_ the transition begins, with different
`t` and `u` arguments.
```svelte
<!file: App.svelte>
<script>
import { elasticOut } from 'svelte/easing';
/**
* @param {HTMLElement} node
* @param {{ delay?: number, duration?: number, easing?: (t: number) =>
number }} params
*/
function whoosh(node, params) {
const existingTransform =
getComputedStyle(node).transform.replace('none', '');
return {
delay: params.delay || 0,
duration: params.duration || 400,
easing: params.easing || elasticOut,
css: (t, u) => `transform: ${existingTransform} scale(${t})`
};
}
</script>
{#if visible}
<div in:whoosh>whooshes in</div>
{/if}
```
A custom transition function can also return a `tick` function, which is called
_during_ the transition with the same `t` and `u` arguments.
```svelte
<!file: App.svelte>
<script>
export let visible = false;
/**
* @param {HTMLElement} node
* @param {{ speed?: number }} params
*/
function typewriter(node, { speed = 1 }) {
const valid = node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE;
if (!valid) {
throw new Error(`This transition only works on elements with a
single text node child`);
}
return {
duration,
tick: (t) => {
const i = ~~(text.length * t);
node.textContent = text.slice(0, i);
}
};
}
</script>
{#if visible}
<p in:typewriter={{ speed: 1 }}>The quick brown fox jumps over the lazy
dog</p>
{/if}
```
## Transition events
An element with transitions will dispatch the following events in addition to any
standard DOM events:
- `introstart`
- `introend`
- `outrostart`
- `outroend`
```svelte
{#if visible}
<p
transition:fly={{ y: 200, duration: 2000 }}
onintrostart={() => (status = 'intro started')}
onoutrostart={() => (status = 'outro started')}
onintroend={() => (status = 'intro ended')}
onoutroend={() => (status = 'outro ended')}
>
Flies in and out
</p>
{/if}
```
## docs/svelte/03-template-syntax/14-in-and-out.md
---
```svelte
<script>
import { fade, fly } from 'svelte/transition';
let visible = $state(false);
</script>
<label>
<input type="checkbox" bind:checked={visible}>
visible
</label>
{#if visible}
<div in:fly={{ y: 200 }} out:fade>flies in, fades out</div>
{/if}
```
## docs/svelte/03-template-syntax/15-animate.md
---
title: animate:
---
```svelte
<!-- When `list` is reordered the animation will run -->
{#each list as item, index (item)}
<li animate:flip>{item}</li>
{/each}
```
## Animation Parameters
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside
an expression tag.)
```svelte
{#each list as item, index (item)}
<li animate:flip={{ delay: 500 }}>{item}</li>
{/each}
```
```js
/// copy: false
// @noErrors
animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
css?: (t: number, u: number) => string,
tick?: (t: number, u: number) => void
}
```
Animations can use custom functions that provide the `node`, an `animation` object
and any `parameters` as arguments. The `animation` parameter is an object
containing `from` and `to` properties each containing a
[DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties)
describing the geometry of the element in its `start` and `end` positions. The
`from` property is the DOMRect of the element in its starting position, and the
`to` property is the DOMRect of the element in its final position after the list
has been reordered and the DOM updated.
If the returned object has a `css` method, Svelte will create a [web animation]
(https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) that plays on
the element.
The `t` argument passed to `css` is a value that goes from `0` and `1` after the
`easing` function has been applied. The `u` argument is equal to `1 - t`.
The function is called repeatedly _before_ the animation begins, with different `t`
and `u` arguments.
```svelte
<!file: App.svelte>
<script>
import { cubicOut } from 'svelte/easing';
/**
* @param {HTMLElement} node
* @param {{ from: DOMRect; to: DOMRect }} states
* @param {any} params
*/
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px)
rotate(${t * 360}deg);`
};
}
</script>
A custom animation function can also return a `tick` function, which is called
_during_ the animation with the same `t` and `u` arguments.
```svelte
<!file: App.svelte>
<script>
import { cubicOut } from 'svelte/easing';
/**
* @param {HTMLElement} node
* @param {{ from: DOMRect; to: DOMRect }} states
* @param {any} params
*/
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ?
'Pink' : 'Blue' })
};
}
</script>
## docs/svelte/03-template-syntax/17-style.md
---
title: style:
---
```svelte
<!-- These are equivalent -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
```
```svelte
<div style:color={myColor}>...</div>
```
```svelte
<div style:color>...</div>
```
Multiple styles can be set on a single element:
```svelte
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' :
'white'}>...</div>
```
```svelte
<div style:color|important="red">...</div>
```
When `style:` directives are combined with `style` attributes, the directives will
take precedence:
```svelte
<div style="color: blue;" style:color="red">This will be red</div>
```
## docs/svelte/03-template-syntax/18-class.md
---
title: class
---
There are two ways to set classes on elements: the `class` attribute, and the
`class:` directive.
## Attributes
```svelte
<div class={large ? 'large' : 'small'}>...</div>
```
> For historical reasons, falsy values (like `false` and `NaN`) are stringified
(`class="false"`), though `class={undefined}` (or `null`) cause the attribute to be
omitted altogether. In a future version of Svelte, all falsy values will cause
`class` to be omitted.
Since Svelte 5.16, `class` can be an object or array, and is converted to a string
using [clsx](https://github.com/lukeed/clsx).
```svelte
<script>
let { cool } = $props();
</script>
```svelte
<!-- if `faded` and `large` are both truthy, results in
`class="saturate-0 opacity-50 scale-200"` -->
<div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}>...</div>
```
Note that whether we're using the array or object form, we can set multiple classes
simultaneously with a single condition, which is particularly useful if you're
using things like Tailwind.
Arrays can contain arrays and objects, and clsx will flatten them. This is useful
for combining local classes with props, for example:
```svelte
<!file: Button.svelte>
<script>
let props = $props();
</script>
The user of this component has the same flexibility to use a mixture of objects,
arrays and strings:
```svelte
<!file: App.svelte>
<script>
import Button from './Button.svelte';
let useTailwind = $state(false);
</script>
<Button
onclick={() => useTailwind = true}
class={{ 'bg-blue-700 sm:w-1/2': useTailwind }}
>
Accept the inevitability of Tailwind
</Button>
```
Svelte also exposes the `ClassValue` type, which is the type of value that the
`class` attribute on elements accept. This is useful if you want to use a type-safe
class name in component props:
```svelte
<script lang="ts">
import type { ClassValue } from 'svelte/elements';
Prior to Svelte 5.16, the `class:` directive was the most convenient way to set
classes on elements conditionally.
```svelte
<!-- These are equivalent -->
<div class={{ cool, lame: !cool }}>...</div>
<div class:cool={cool} class:lame={!cool}>...</div>
```
As with other directives, we can use a shorthand when the name of the class
coincides with the value:
```svelte
<div class:cool class:lame={!cool}>...</div>
```
## docs/svelte/03-template-syntax/xx-control-flow.md
---
- if
- each
- await (or move that into some kind of data loading section?)
- NOT: key (move into transition section, because that's the common use case)
Svelte augments HTML with control flow blocks to be able to express conditionally
rendered content or lists.
## {#if ...}
## {#each ...}
```svelte
<!copy: false>
{#each expression as name}...{/each}
```
```svelte
<!copy: false>
{#each expression as name, index}...{/each}
```
```svelte
<!copy: false>
{#each expression as name (key)}...{/each}
```
```svelte
<!copy: false>
{#each expression as name, index (key)}...{/each}
```
```svelte
<!copy: false>
{#each expression as name}...{:else}...{/each}
```
```svelte
<h1>Shopping list</h1>
<ul>
{#each items as item}
<li>{item.name} x {item.qty}</li>
{/each}
</ul>
```
You can use each blocks to iterate over any array or array-like value — that is,
any object with a `length` property.
An each block can also specify an _index_, equivalent to the second argument in an
`array.map(...)` callback:
```svelte
{#each items as item, i}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```
If a _key_ expression is provided — which must uniquely identify each list item —
Svelte will use it to diff the list when data changes, rather than adding or
removing items at the end. The key can be any object, but strings and numbers are
recommended since they allow identity to persist when the objects themselves
change.
```svelte
{#each items as item (item.id)}
<li>{item.name} x {item.qty}</li>
{/each}
You can freely use destructuring and rest patterns in each blocks.
```svelte
{#each items as { id, name, qty }, i (id)}
<li>{i + 1}: {name} x {qty}</li>
{/each}
An each block can also have an `{:else}` clause, which is rendered if the list is
empty.
```svelte
{#each todos as todo}
<p>{todo.text}</p>
{:else}
<p>No tasks today!</p>
{/each}
```
## docs/svelte/03-template-syntax/xx-data-fetching.md
---
Fetching data is a fundamental part of apps interacting with the outside world.
Svelte is unopinionated with how you fetch your data. The simplest way would be
using the built-in `fetch` method:
```svelte
<script>
let response = $state();
fetch('/api/data').then(async (r) => (response = r.json()));
</script>
```
While this works, it makes working with promises somewhat unergonomic. Svelte
alleviates this problem using the `#await` block.
## {#await ...}
## SvelteKit loaders
Fetching inside your components is great for simple use cases, but it's prone to
data loading waterfalls and makes code harder to work with because of the promise
handling. SvelteKit solves this problem by providing a opinionated data loading
story that is coupled to its router. Learn more about it [in the docs](../kit).
## docs/svelte/04-styling/index.md
---
title: Styling
---
## docs/svelte/04-styling/01-scoped-styles.md
---
Svelte components can include a `<style>` element containing CSS that belongs to
the component. This CSS is _scoped_ by default, meaning that styles will not apply
to any elements on the page outside the component in question.
This works by adding a class to affected elements, which is based on a hash of the
component styles (e.g. `svelte-123xyz`).
```svelte
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
```
## Specificity
In some cases, the scoping class must be added to a selector multiple times, but
after the first occurrence it is added with `:where(.svelte-xyz123)` in order to
not increase specificity further.
## Scoped keyframes
If a component defines `@keyframes`, the name is scoped to the component using the
same hashing approach. Any `animation` rules in the component will be similarly
adjusted:
```svelte
<style>
.bouncy {
animation: bounce 10s;
}
## docs/svelte/04-styling/02-global-styles.md
---
## :global(...)
```svelte
<style>
:global(body) {
/* applies to <body> */
margin: 0;
}
div :global(strong) {
/* applies to all <strong> elements, in any component,
that are inside <div> elements belonging
to this component */
color: goldenrod;
}
p:global(.big.red) {
/* applies to all <p> elements belonging to this component
with `class="big red"`, even if it is applied
programmatically (for example by a library) */
}
</style>
```
If you want to make @keyframes that are accessible globally, you need to prepend
your keyframe names with `-global-`.
The `-global-` part will be removed when compiled, and the keyframe will then be
referenced using just `my-animation-name` elsewhere in your code.
```svelte
<style>
@keyframes -global-my-animation-name {
/* code goes here */
}
</style>
```
## :global
```svelte
<style>
:global {
/* applies to every <div> in your application */
div { ... }
.a :global {
/* applies to every `.b .c .d` element, in any component,
that is inside an `.a` element in this component */
.b .c .d {...}
}
</style>
```
## docs/svelte/04-styling/03-custom-properties.md
---
You can pass CSS custom properties — both static and dynamic — to components:
```svelte
<Slider
bind:value
min={0}
max={100}
--track-color="black"
--thumb-color="rgb({r} {g} {b})"
/>
```
```svelte
<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color:
rgb({r} {g} {b})">
<Slider
bind:value
min={0}
max={100}
/>
</svelte-css-wrapper>
```
```svelte
<g style="--track-color: black; --thumb-color: rgb({r} {g} {b})">
<Slider
bind:value
min={0}
max={100}
/>
</g>
```
Inside the component, we can read these custom properties (and provide fallback
values) using
[`var(...)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_prop
erties):
```svelte
<style>
.track {
background: var(--track-color, #aaa);
}
.thumb {
background: var(--thumb-color, blue);
}
</style>
```
You don't _have_ to specify the values directly on the component; as long as the
custom properties are defined on a parent element, the component can use them. It's
common to define custom properties on the `:root` element in a global stylesheet so
that they apply to your entire application.
## docs/svelte/04-styling/04-nested-style-elements.md
---
In that case, the `<style>` tag will be inserted as-is into the DOM; no scoping or
processing will be done on the `<style>` tag.
```svelte
<div>
<style>
/* this style tag will be inserted as-is */
div {
/* this will apply to all `<div>` elements in the DOM */
color: red;
}
</style>
</div>
```
## docs/svelte/05-special-elements/index.md
---
## docs/svelte/05-special-elements/01-svelte-boundary.md
---
title: <svelte:boundary>
---
```svelte
<svelte:boundary onerror={handler}>...</svelte:boundary>
```
Boundaries allow you to guard against errors in part of your app from breaking the
app as a whole, and to recover from those errors.
Errors occurring outside the rendering process (for example, in event handlers or
after a `setTimeout` or async work) are _not_ caught by error boundaries.
## Properties
For the boundary to do anything, one or both of `failed` and `onerror` must be
provided.
### `failed`
If a `failed` snippet is provided, it will be rendered with the error that was
thrown, and a `reset` function that recreates the contents
([demo](/playground/hello-
world#H4sIAAAAAAAAE3VRy26DMBD8lS2tFCIh6JkAUlWp39Cq9EBg06CAbdlLArL87zWGKk8ORnhmd3Znr
D1WtOjFXqKO2BDGW96xqpBD5gXerm5QefG39mgQY9EIWHxueRMinLosti0UPsJLzggZKTeilLWgLGc51a3g
kuCjKQ7DO7cXZotgJ3kLqzC6hmex1SZnSXTWYHcrj8LJjWTk0PHoZ8VqIdCOKayPykcpuQxAokJaG1dGybY
j4gw4K5u6PKTasSbjXKgnIDlA8VvUdo-
pzonraBY2bsH7HAl78mKSHZpgIcuHjq9jXSpZSLixRlveKYQUXhQVhL6GPobXAAb7BbNeyvNUs4qfRg3OnE
LLj5hqH9eQZqCnoBwR9lYcQxuVXeBzc8kMF8yXY4yNJ5oGiUzP_aaf_waTRGJib5_Ad3P_vbCuaYxzeNpbU
0eUMPAOKh7Yw1YErgtoXyuYlPLzc10_xo_5A91zkQL_AgAA)):
```svelte
<svelte:boundary>
<FlakyComponent />
### `onerror`
If an `onerror` function is provided, it will be called with the same two `error`
and `reset` arguments. This is useful for tracking the error with an error
reporting service...
```svelte
<svelte:boundary onerror={(e) => report(e)}>
...
</svelte:boundary>
```
```svelte
<script>
let error = $state(null);
let reset = $state(() => {});
function onerror(e, r) {
error = e;
reset = r;
}
</script>
<svelte:boundary {onerror}>
<FlakyComponent />
</svelte:boundary>
{#if error}
<button onclick={() => {
error = null;
reset();
}}>
oops! try again
</button>
{/if}
```
If an error occurs inside the `onerror` function (or if you rethrow the error), it
will be handled by a parent boundary if such exists.
## docs/svelte/05-special-elements/02-svelte-window.md
---
title: <svelte:window>
---
```svelte
<svelte:window onevent={handler} />
```
```svelte
<svelte:window bind:prop={value} />
```
The `<svelte:window>` element allows you to add event listeners to the `window`
object without worrying about removing them when the component is destroyed, or
checking for the existence of `window` when server-side rendering.
This element may only appear at the top level of your component — it cannot be
inside a block or element.
```svelte
<script>
function handleKeydown(event) {
alert(`pressed the ${event.key} key`);
}
</script>
- `innerWidth`
- `innerHeight`
- `outerWidth`
- `outerHeight`
- `scrollX`
- `scrollY`
- `online` — an alias for `window.navigator.onLine`
- `devicePixelRatio`
```svelte
<svelte:window bind:scrollY={y} />
```
## docs/svelte/05-special-elements/03-svelte-document.md
---
title: <svelte:document>
---
```svelte
<svelte:document onevent={handler} />
```
```svelte
<svelte:document bind:prop={value} />
```
As with `<svelte:window>`, this element may only appear the top level of your
component and must never be inside a block or element.
```svelte
<svelte:document onvisibilitychange={handleVisibilityChange} use:someAction />
```
## docs/svelte/05-special-elements/04-svelte-body.md
---
title: <svelte:body>
---
```svelte
<svelte:body onevent={handler} />
```
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the
top level of your component and must never be inside a block or element.
```svelte
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave}
use:someAction />
```
## docs/svelte/05-special-elements/05-svelte-head.md
---
title: <svelte:head>
---
```svelte
<svelte:head>...</svelte:head>
```
```svelte
<svelte:head>
<title>Hello world!</title>
<meta name="description" content="This is where the description goes for SEO"
/>
</svelte:head>
```
## docs/svelte/05-special-elements/06-svelte-element.md
---
title: <svelte:element>
---
```svelte
<svelte:element this={expression} />
```
The `<svelte:element>` element lets you render an element that is unknown at author
time, for example because it comes from a CMS. Any properties and event listeners
present will be applied to the element.
The only supported binding is `bind:this`, since Svelte's built-in bindings do not
work with generic elements.
If `this` has a nullish value, the element and its children will not be rendered.
```svelte
<script>
let tag = $state('hr');
</script>
<svelte:element this={tag}>
This text cannot appear inside an hr element
</svelte:element>
```
Svelte tries its best to infer the correct namespace from the element's
surroundings, but it's not always possible. You can make it explicit with an
`xmlns` attribute:
```svelte
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
```
`this` needs to be a valid DOM element tag, things like `#text` or `svelte:head`
will not work.
## docs/svelte/05-special-elements/07-svelte-options.md
---
title: <svelte:options>
---
```svelte
<svelte:options option={value} />
```
```svelte
<svelte:options customElement="my-custom-element" />
```
## docs/svelte/06-runtime/index.md
---
title: Runtime
---
## docs/svelte/06-runtime/01-stores.md
---
title: Stores
---
A _store_ is an object that allows reactive access to a value via a simple _store
contract_. The [`svelte/store` module](../svelte-store) contains minimal store
implementations which fulfil this contract.
Any time you have a reference to a store, you can access its value inside a
component by prefixing it with the `$` character. This causes Svelte to declare the
prefixed variable, subscribe to the store at component initialisation and
unsubscribe when appropriate.
Note that the store must be declared at the top level of the component — not inside
an `if` block or a function, for example.
Local variables (that do not represent store values) must _not_ have a `$` prefix.
```svelte
<script>
import { writable } from 'svelte/store';
count.set(1);
console.log($count); // logs 1
$count = 2;
console.log($count); // logs 2
</script>
```
Prior to Svelte 5, stores were the go-to solution for creating cross-component
reactive states or extracting logic. With runes, these use cases have greatly
diminished.
```ts
/// file: state.svelte.js
export const userState = $state({
name: 'name',
/* ... */
});
```
```svelte
<!file: App.svelte>
<script>
import { userState } from './state.svelte.js';
</script>
Stores are still a good solution when you have complex asynchronous data streams or
it's important to have more manual control over updating values or listening to
changes. If you're familiar with RxJs and want to reuse that knowledge, the `$`
also comes in handy for you.
## svelte/store
The `svelte/store` module contains a minimal store implementation which fulfil the
store contract. It provides methods for creating stores that you can update from
the outside, stores you can only update from the inside, and for combining and
deriving stores.
### `writable`
Function that creates a store which has values that can be set from 'outside'
components. It gets created as an object with additional `set` and `update`
methods.
`set` is a method that takes one argument which is the value to be set. The store
value gets set to the value of the argument if the store value is not already equal
to it.
`update` is a method that takes one argument which is a callback. The callback
takes the existing store value as its argument and returns the new value to be set
to the store.
```js
/// file: store.js
import { writable } from 'svelte/store';
count.subscribe((value) => {
console.log(value);
}); // logs '0'
If a function is passed as the second argument, it will be called when the number
of subscribers goes from zero to one (but not from one to two, etc). That function
will be passed a `set` function which changes the value of the store, and an
`update` function which works like the `update` method on the store, taking a
callback to calculate the store's new value from its old value. It must return a
`stop` function that is called when the subscriber count goes from one to zero.
```js
/// file: store.js
import { writable } from 'svelte/store';
Note that the value of a `writable` is lost when it is destroyed, for example when
the page is refreshed. However, you can write your own logic to sync the value to
for example the `localStorage`.
### `readable`
Creates a store whose value cannot be set from 'outside', the first argument is the
store's initial value, and the second argument to `readable` is the same as the
second argument to `writable`.
```ts
import { readable } from 'svelte/store';
### `derived`
Derives a store from one or more other stores. The callback runs initially when the
first subscriber subscribes and then whenever the store dependencies change.
In the simplest version, `derived` takes a single store, and the callback returns a
derived value.
```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';
declare global {
const a: Writable<number>;
}
export {};
// @filename: index.ts
//cut
import { derived } from 'svelte/store';
In this case, you can also pass a third argument to `derived` — the initial value
of the derived store before `set` or `update` is first called. If no initial value
is specified, the store's initial value will be `undefined`.
```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';
declare global {
const a: Writable<number>;
}
export {};
// @filename: index.ts
// @errors: 18046 2769 7006
//cut
import { derived } from 'svelte/store';
If you return a function from the callback, it will be called when a) the callback
runs again, or b) the last subscriber unsubscribes.
```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';
declare global {
const frequency: Writable<number>;
}
export {};
// @filename: index.ts
//cut
import { derived } from 'svelte/store';
return () => {
clearInterval(interval);
};
},
2000
);
```
In both cases, an array of arguments can be passed as the first argument instead of
a single store.
```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';
declare global {
const a: Writable<number>;
const b: Writable<number>;
}
export {};
// @filename: index.ts
//cut
import { derived } from 'svelte/store';
### `readonly`
This simple helper function makes a store readonly. You can still subscribe to the
changes from the original one using this new readable store.
```js
import { readonly, writable } from 'svelte/store';
readableStore.subscribe(console.log);
writableStore.set(2); // console: 2
// @errors: 2339
readableStore.set(2); // ERROR
```
### `get`
Generally, you should read the value of a store by subscribing to it and using the
value as it changes over time. Occasionally, you may need to retrieve the value of
a store to which you're not subscribed. `get` allows you to do so.
```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';
declare global {
const store: Writable<string>;
}
export {};
// @filename: index.ts
//cut
import { get } from 'svelte/store';
## Store contract
```ts
// @noErrors
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?:
(value: any) => void }
```
1. A store must contain a `.subscribe` method, which must accept as its argument a
subscription function. This subscription function must be immediately and
synchronously called with the store's current value upon calling `.subscribe`. All
of a store's active subscription functions must later be synchronously called
whenever the store's value changes.
2. The `.subscribe` method must return an unsubscribe function. Calling an
unsubscribe function must stop its subscription, and its corresponding subscription
function must not be called again by the store.
3. A store may _optionally_ contain a `.set` method, which must accept as its
argument a new value for the store, and which synchronously calls all of the
store's active subscription functions. Such a store is called a _writable store_.
For interoperability with RxJS Observables, the `.subscribe` method is also allowed
to return an object with an `.unsubscribe` method, rather than return the
unsubscription function directly. Note however that unless `.subscribe`
synchronously calls the subscription (which is not required by the Observable
spec), Svelte will see the value of the store as `undefined` until it does.
## docs/svelte/06-runtime/02-context.md
---
title: Context
---
```svelte
<!file: Parent.svelte>
<script>
import { setContext } from 'svelte';
```svelte
<!file: Child.svelte>
<script>
import { getContext } from 'svelte';
```svelte
<Parent>
<Child />
</Parent>
```
The key (`'my-context'`, in the example above) and the context itself can be any
JavaScript value.
setContext('counter', counter);
</script>
<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...
```svelte
<button onclick={() => counter = { count: 0 }}>
reset
</button>
```
```svelte
<button onclick={() =>counter.count = 0}>
reset
</button>
```
## Type-safe context
```js
/// file: context.js
// @filename: ambient.d.ts
interface User {}
// @filename: index.js
//cut
import { getContext, setContext } from 'svelte';
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:
```js
/// file: state.svelte.js
export const myGlobalState = $state({
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!)...
```svelte
<!file: App.svelte->
<script>
import { myGlobalState } from 'svelte';
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.
## docs/svelte/06-runtime/03-lifecycle-hooks.md
---
<!-- - onMount/onDestroy
- mention that `$effect` might be better for your use case
- beforeUpdate/afterUpdate with deprecation notice?
- or skip this entirely and only have it in the reference docs? -->
In Svelte 5, the component lifecycle consists of only two parts: Its creation and
its destruction. Everything in-between — when certain state is updated — is not
related to the component as a whole; only the parts that need to react to the state
change are notified. This is because under the hood the smallest unit of change is
actually not a component, it's the (render) effects that the component sets up upon
component initialization. Consequently, there's no such thing as a "before
update"/"after update" hook.
## `onMount`
The `onMount` function schedules a callback to run as soon as the component has
been mounted to the DOM. It must be called during the component's initialisation
(but doesn't need to live _inside_ the component; it can be called from an external
module).
`onMount` does not run inside a component that is rendered on the server.
```svelte
<script>
import { onMount } from 'svelte';
onMount(() => {
console.log('the component has mounted');
});
</script>
```
```svelte
<script>
import { onMount } from 'svelte';
onMount(() => {
const interval = setInterval(() => {
console.log('beep');
}, 1000);
## `onDestroy`
```svelte
<script>
import { onDestroy } from 'svelte';
onDestroy(() => {
console.log('the component is being destroyed');
});
</script>
```
## `tick`
While there's no "after update" hook, you can use `tick` to ensure that the UI is
updated before continuing. `tick` returns a promise that resolves once any pending
state changes have been applied, or in the next microtask if there are none.
```svelte
<script>
import { tick } from 'svelte';
$effect.pre(() => {
console.log('the component is about to update');
tick().then(() => {
console.log('the component just updated');
});
});
</script>
```
Svelte 4 contained hooks that ran before and after the component as a whole was
updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not
available inside components that use runes.
```svelte
<script>
import { beforeUpdate, afterUpdate } from 'svelte';
beforeUpdate(() => {
console.log('the component is about to update');
});
afterUpdate(() => {
console.log('the component just updated');
});
</script>
```
To implement a chat window that autoscrolls to the bottom when new messages appear
(but only if you were _already_ scrolled to the bottom), we need to measure the DOM
before we update it.
With runes, we can use `$effect.pre`, which behaves the same as `$effect` but runs
before the DOM is updated. As long as we explicitly reference `messages` inside the
effect body, it will run whenever `messages` changes, but _not_ when `theme`
changes.
```svelte
<script>
import {beforeUpdate, afterUpdate,tick } from 'svelte';
let viewport;
beforeUpdate(() => {
$effect.pre(() => {
if (!updatingMessages) return;
messages;
const autoscroll = viewport && viewport.offsetHeight +
viewport.scrollTop > viewport.scrollHeight - 50;
if (autoscroll) {
tick().then(() => {
viewport.scrollTo(0, viewport.scrollHeight);
});
}
updatingMessages = false;
});
function handleKeydown(event) {
if (event.key === 'Enter') {
const text = event.target.value;
if (!text) return;
updatingMessages = true;
messages = [...messages, text];
event.target.value = '';
}
}
function toggle() {
theme = theme === 'dark' ? 'light' : 'dark';
}
</script>
<inputonkeydown={handleKeydown} />
## docs/svelte/06-runtime/04-imperative-component-api.md
---
- mount
- unmount
- render
- hydrate
- how they interact with each other -->
## `mount`
Instantiates a component and mounts it to the given target:
```js
// @errors: 2322
import { mount } from 'svelte';
import App from './App.svelte';
You can mount multiple components per page, and you can also mount from within your
application, for example when creating a tooltip component and attaching it to the
hovered element.
Note that unlike calling `new App(...)` in Svelte 4, things like effects (including
`onMount` callbacks, and action functions) will not run during `mount`. If you need
to force pending effects to run (in the context of a test, for example) you can do
so with `flushSync()`.
## `unmount`
```js
import { mount, unmount } from 'svelte';
import App from './App.svelte';
// later
unmount(app, { outro: true });
```
## `render`
Only available on the server and when compiling with the `server` option. Takes a
component and returns an object with `body` and `head` properties on it, which you
can use to populate the HTML when server-rendering your app:
```js
// @errors: 2724 2305 2307
import { render } from 'svelte/server';
import App from './App.svelte';
## `hydrate`
Like `mount`, but will reuse up any HTML rendered by Svelte's SSR output (from the
[`render`](#render) function) inside the target and make it interactive:
```js
// @errors: 2322
import { hydrate } from 'svelte';
import App from './App.svelte';
As with `mount`, effects will not run during `hydrate` — use `flushSync()`
immediately afterwards if you need them to.
## docs/svelte/07-misc/index.md
---
title: Misc
---
## docs/svelte/07-misc/02-testing.md
---
title: Testing
---
Testing helps you write and maintain your code and guard against regressions.
Testing frameworks help you with that, allowing you to describe assertions or
expectations about how your code should behave. Svelte is unopinionated about which
testing framework you use — you can write unit tests, integration tests, and end-
to-end tests using solutions like [Vitest](https://vitest.dev/), [Jasmine]
(https://jasmine.github.io/), [Cypress](https://www.cypress.io/) and [Playwright]
(https://playwright.dev/).
Unit tests allow you to test small isolated parts of your code. Integration tests
allow you to test parts of your application to see if they work together. If you're
using Vite (including via SvelteKit), we recommend using
[Vitest](https://vitest.dev/).
```bash
npm install -D vitest
```
```js
/// file: vite.config.js
import { defineConfig } from'vitest/config';
You can now write unit tests for code inside your `.js/.ts` files:
```js
/// file: multiplier.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { multiplier } from './multiplier.svelte.js';
test('Multiplier', () => {
let double = multiplier(0, 2);
expect(double.value).toEqual(0);
double.set(5);
expect(double.value).toEqual(10);
});
```
```js
/// file: multiplier.svelte.js
/**
* @param {number} initial
* @param {number} k
*/
export function multiplier(initial, k) {
let count = $state(initial);
return {
get value() {
return count * k;
},
/** @param {number} c */
set: (c) => {
count = c;
}
};
}
```
Since Vitest processes your test files the same way as your source files, you can
use runes inside your tests as long as the filename includes `.svelte`:
```js
/// file: multiplier.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { multiplier } from './multiplier.svelte.js';
test('Multiplier', () => {
let count = $state(0);
let double = multiplier(() => count, 2);
expect(double.value).toEqual(0);
count = 5;
expect(double.value).toEqual(10);
});
```
```js
/// file: multiplier.svelte.js
/**
* @param {() => number} getCount
* @param {number} k
*/
export function multiplier(getCount, k) {
return {
get value() {
return getCount() * k;
}
};
}
```
If the code being tested uses effects, you need to wrap the test inside
`$effect.root`:
```js
/// file: logger.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { logger } from './logger.svelte.js';
test('Effect', () => {
const cleanup = $effect.root(() => {
let count = $state(0);
count = 1;
flushSync();
expect(log.value).toEqual([0, 1]);
});
cleanup();
});
```
```js
/// file: logger.svelte.js
/**
* @param {() => any} getValue
*/
export function logger(getValue) {
/** @type {any[]} */
let log = $state([]);
$effect(() => {
log.push(getValue());
});
return {
get value() {
return log;
}
};
}
```
```bash
npm install -D jsdom
```
```js
/// file: vite.config.js
import { defineConfig } from 'vitest/config';
After that, you can create a test file in which you import the component to test,
interact with it programmatically and write expectations about the results:
```js
/// file: component.test.js
import { flushSync, mount, unmount } from 'svelte';
import { expect, test } from 'vitest';
import Component from './Component.svelte';
test('Component', () => {
// Instantiate the component using Svelte's `mount` API
const component = mount(Component, {
target: document.body, // `document` exists because of jsdom
props: { initial: 0 }
});
expect(document.body.innerHTML).toBe('<button>0</button>');
// Click the button, then flush the changes so you can synchronously write
expectations
document.body.querySelector('button').click();
flushSync();
expect(document.body.innerHTML).toBe('<button>1</button>');
While the process is very straightforward, it is also low level and somewhat
brittle, as the precise structure of your component may change frequently. Tools
like [@testing-library/svelte](https://testing-library.com/docs/svelte-testing-
library/intro/) can help streamline your tests. The above test could be rewritten
like this:
```js
/// file: component.test.js
import { render, screen } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { expect, test } from 'vitest';
import Component from './Component.svelte';
await user.click(button);
expect(button).toHaveTextContent(1);
});
```
When writing component tests that involve two-way bindings, context or snippet
props, it's best to create a wrapper component for your specific test and interact
with that. `@testing-library/svelte` contains some [examples](https://testing-
library.com/docs/svelte-testing-library/example).
E2E (short for 'end to end') tests allow you to test your full application through
the eyes of the user. This section uses [Playwright](https://playwright.dev/) as an
example, but you can also use other solutions like
[Cypress](https://www.cypress.io/) or [NightwatchJS](https://nightwatchjs.org/).
To get started with Playwright, either install it via [the VS Code extension]
(https://playwright.dev/docs/getting-started-vscode), or install it from the
command line using `npm init playwright`. It is also part of the setup CLI when you
run `npx sv create`.
After you've done that, you should have a `tests` folder and a Playwright config.
You may need to adjust that config to tell Playwright what to do before running the
tests - mainly starting your application at a certain port:
```js
/// file: playwright.config.js
const config = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};
You can now start writing tests. These are totally unaware of Svelte as a
framework, so you mainly interact with the DOM and write assertions.
```js
// @errors: 2307 7031
/// file: tests/hello-world.spec.js
import { expect, test } from '@playwright/test';
## docs/svelte/07-misc/03-typescript.md
---
title: TypeScript
---
<!-- - [basically what we have today](https://svelte.dev/docs/typescript)
- built-in support, but only for type-only features
- generics
- using `Component` and the other helper types
- using `svelte-check` -->
You can use TypeScript within Svelte components. IDE extensions like the [Svelte VS
Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-
vscode) will help you catch errors right in your editor, and [`svelte-check`]
(https://www.npmjs.com/package/svelte-check) does the same on the command line,
which you can integrate into your CI.
## `<script lang="ts">`
To use TypeScript inside your Svelte components, add `lang="ts"` to your `script`
tags:
```svelte
<script lang="ts">
let name: string = 'world';
Doing so allows you to use TypeScript's _type-only_ features. That is, all features
that just disappear when transpiling to JavaScript, such as type annotations or
interface declarations. Features that require the TypeScript compiler to output
actual code are not supported. This includes:
- using enums
- using `private`, `protected` or `public` modifiers in constructor functions
together with initializers
- using features that are not yet part of the ECMAScript standard (i.e. not level 4
in the TC39 process) and therefore not implemented yet within Acorn, the parser we
use for parsing JavaScript
If you want to use one of these features, you need to setup up a `script`
preprocessor.
## Preprocessor setup
To use non-type-only TypeScript features within Svelte components, you need to add
a preprocessor that will turn TypeScript into JavaScript.
```ts
/// file: svelte.config.js
// @noErrors
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
// Note the additional `{ script: true }`
preprocess: vitePreprocess({ script: true })
};
The easiest way to get started is scaffolding a new SvelteKit project by typing
`npx sv create`, following the prompts and choosing the TypeScript option.
```ts
/// file: svelte.config.js
// @noErrors
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: vitePreprocess()
};
If you don't need or want all the features SvelteKit has to offer, you can scaffold
a Svelte-flavoured Vite project instead by typing `npm create vite@latest` and
selecting the `svelte-ts` option.
If you're using tools like Rollup or Webpack instead, install their respective
Svelte plugins. For Rollup that's
[rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) and for
Webpack that's [svelte-loader](https://github.com/sveltejs/svelte-loader). For
both, you need to install `typescript` and `svelte-preprocess` and add the
preprocessor to the plugin config (see the respective READMEs for more info). If
you're starting a new project, you can also use the
[rollup](https://github.com/sveltejs/template) or
[webpack](https://github.com/sveltejs/template-webpack) template to scaffold the
setup from a script.
## tsconfig.json settings
## Typing `$props`
```svelte
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
requiredProperty: number;
optionalProperty?: boolean;
snippetWithStringArgument: Snippet<[string]>;
eventHandler: (arg: string) => void;
[key: string]: unknown;
}
let {
requiredProperty,
optionalProperty,
snippetWithStringArgument,
eventHandler,
...everythingElse
}: Props = $props();
</script>
## Generic `$props`
Components can declare a generic relationship between their properties. One example
is a generic list component that receives a list of items and a callback property
that receives an item from the list. To declare that the `items` property and the
`select` callback operate on the same types, add the `generics` attribute to the
`script` tag:
```svelte
<script lang="ts" generics="Item extends { text: string }">
interface Props {
items: Item[];
select(item: Item): void;
}
The content of `generics` is what you would put between the `<...>` tags of a
generic function. In other words, you can use multiple generics, `extends` and
fallback types.
In case you're writing a component that wraps a native element, you may want to
expose all the attributes of the underlying element to the user. In that case, use
(or extend from) one of the interfaces provided by `svelte/elements`. Here's an
example for a `Button` component:
```svelte
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
<button {...rest}>
{@render children?.()}
</button>
```
Not all elements have a dedicated type definition. For those without one, use
`SvelteHTMLElements`:
```svelte
<script lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
<div {...rest}>
{@render children?.()}
</div>
```
## Typing `$state`
```ts
let count: number = $state(0);
```
If you don't give `$state` an initial value, part of its types will be `undefined`.
```ts
// @noErrors
// Error: Type 'number | undefined' is not assignable to type 'number'
let count: number = $state();
```
If you know that the variable _will_ be defined before you first use it, use an
`as` casting. This is especially useful in the context of classes:
```ts
class Counter {
count = $state() as number;
constructor(initial: number) {
this.count = initial;
}
}
```
Svelte components are of type `Component`. You can use it and its related types to
express a variety of constraints.
Using it together with dynamic components to restrict what kinds of component can
be passed to it:
```svelte
<script lang="ts">
import type { Component } from 'svelte';
interface Props {
// only components that have at most the "prop"
// property required can be passed
DynamicComponent: Component<{ prop: string }>;
}
```ts
import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';
```svelte
<script lang="ts">
import MyComponent from './MyComponent.svelte';
Svelte provides a best effort of all the HTML DOM types that exist. Sometimes you
may want to use experimental attributes or custom events coming from an action. In
these cases, TypeScript will throw a type error, saying that it does not know these
types. If it's a non-experimental standard attribute/event, this may very well be a
missing typing from our [HTML
typings](https://github.com/sveltejs/svelte/blob/main/packages/svelte/
elements.d.ts). In that case, you are welcome to open an issue and/or a PR fixing
it.
```ts
/// file: additional-svelte-typings.d.ts
declare namespace svelteHTML {
// enhance elements
interface IntrinsicElements {
'my-custom-element': { someattribute: string; 'on:event': (e:
CustomEvent<any>) => void };
}
// enhance attributes
interface HTMLAttributes<T> {
// If you want to use the beforeinstallprompt event
onbeforeinstallprompt?: (event: any) => any;
// If you want to use myCustomAttribute={..} (note: all lowercase)
mycustomattribute?: any; // You can replace any with something more
specific if you like
}
}
```
Then make sure that `d.ts` file is referenced in your `tsconfig.json`. If it reads
something like `"include": ["src/**/*"]` and your `d.ts` file is inside `src`, it
should work. You may need to reload for the changes to take effect.
You can also declare the typings by augmenting the `svelte/elements` module like
this:
```ts
/// file: additional-svelte-typings.d.ts
import { HTMLButtonAttributes } from 'svelte/elements';
// allows for more granular control over what element to add the typings to
export interface HTMLButtonAttributes {
veryexperimentalattribute?: string;
}
}
export {}; // ensure this is not an ambient module, else types will be overridden
instead of augmented
```
## docs/svelte/07-misc/04-custom-elements.md
---
Svelte components can also be compiled to custom elements (aka web components)
using the `customElement: true` compiler option. You should specify a tag name for
the component using the `<svelte:options>` [element](svelte-options).
```svelte
<svelte:options customElement="my-element" />
<script>
let { name = 'world' } = $props();
</script>
<h1>Hello {name}!</h1>
<slot />
```
You can leave out the tag name for any of your inner components which you don't
want to expose and use them like regular Svelte components. Consumers of the
component can still name it afterwards if needed, using the static `element`
property which contains the custom element constructor and which is available when
the `customElement` compiler option is `true`.
```js
// @noErrors
import MyElement from './MyElement.svelte';
customElements.define('my-element', MyElement.element);
```
Once a custom element has been defined, it can be used as a regular DOM element:
```js
document.body.innerHTML = `
<my-element>
<p>This is some slotted content</p>
</my-element>
`;
```
```js
// @noErrors
const el = document.querySelector('my-element');
Note that you need to list out all properties explicitly, i.e. doing `let props =
$props()` without declaring `props` in the [component options](#Component-options)
means that Svelte can't know which props to expose as properties on the DOM
element.
## Component lifecycle
Custom elements are created from Svelte components using a wrapper approach. This
means the inner Svelte component has no knowledge that it is a custom element. The
custom element wrapper takes care of handling its lifecycle appropriately.
When a custom element is created, the Svelte component it wraps is _not_ created
right away. It is only created in the next tick after the `connectedCallback` is
invoked. Properties assigned to the custom element before it is inserted into the
DOM are temporarily saved and then set on component creation, so their values are
not lost. The same does not work for invoking exported functions on the custom
element though, they are only available after the element has mounted. If you need
to invoke functions before component creation, you can work around it by using the
[`extend` option](#Component-options).
When a custom element written with Svelte is created or updated, the shadow DOM
will reflect the value in the next tick, not immediately. This way updates can be
batched, and DOM moves which temporarily (but synchronously) detach the element
from the DOM don't lead to unmounting the inner component.
The inner Svelte component is destroyed in the next tick after the
`disconnectedCallback` is invoked.
## Component options
When constructing a custom element, you can tailor several aspects by defining
`customElement` as an object within `<svelte:options>` since Svelte 4. This object
may contain the following properties:
- `tag: string`: an optional `tag` property for the custom element's name. If set,
a custom element with this tag name will be defined with the document's
`customElements` registry upon importing this component.
- `shadow`: an optional property that can be set to `"none"` to forgo shadow root
creation. Note that styles are then no longer encapsulated, and you can't use slots
- `props`: an optional property to modify certain details and behaviors of your
component's properties. It offers the following settings:
- `attribute: string`: To update a custom element's prop, you have two
alternatives: either set the property on the custom element's reference as
illustrated above or use an HTML attribute. For the latter, the default attribute
name is the lowercase property name. Modify this by assigning `attribute: "<desired
name>"`.
- `reflect: boolean`: By default, updated prop values do not reflect back to the
DOM. To enable this behavior, set `reflect: true`.
- `type: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object'`: While converting
an attribute value to a prop value and reflecting it back, the prop value is
assumed to be a `String` by default. This may not always be accurate. For instance,
for a number type, define it using `type: "Number"`
You don't need to list all properties, those not listed will use the default
settings.
- `extend`: an optional property which expects a function as its argument. It is
passed the custom element class generated by Svelte and expects you to return a
custom element class. This comes in handy if you have very specific requirements to
the life cycle of the custom element or want to enhance the class to for example
use [ElementInternals](https://developer.mozilla.org/en-US/docs/Web/API/
ElementInternals#examples) for better HTML form integration.
```svelte
<svelte:options
customElement={{
tag: 'custom-element',
shadow: 'none',
props: {
name: { reflect: true, type: 'Number', attribute: 'element-index'
}
},
extend: (customElementConstructor) => {
// Extend the class so we can let it participate in HTML forms
return class extends customElementConstructor {
static formAssociated = true;
constructor() {
super();
this.attachedInternals = this.attachInternals();
}
<script>
let { elementIndex, attachedInternals } = $props();
// ...
function check() {
attachedInternals.checkValidity();
}
</script>
...
```
Custom elements can be a useful way to package components for consumption in a non-
Svelte app, as they will work with vanilla HTML and JavaScript as well as [most
frameworks](https://custom-elements-everywhere.com/). There are, however, some
important differences to be aware of:
- Styles are _encapsulated_, rather than merely _scoped_ (unless you set `shadow:
"none"`). This means that any non-component styles (such as you might have in a
`global.css` file) will not apply to the custom element, including styles with the
`:global(...)` modifier
- Instead of being extracted out as a separate .css file, styles are inlined into
the component as a JavaScript string
- Custom elements are not generally suitable for server-side rendering, as the
shadow DOM is invisible until JavaScript loads
- In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In
other words, it will always be created even if the component's `<slot>` element is
inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}`
block will not cause the slotted content to be rendered multiple times
- The deprecated `let:` directive has no effect, because custom elements do not
have a way to pass data to the parent component that fills the slot
- Polyfills are required to support older browsers
- You can use Svelte's context feature between regular Svelte components within a
custom element, but you can't use them across custom elements. In other words, you
can't use `setContext` on a parent custom element and read that with `getContext`
in a child custom element.
- Don't declare properties or attributes starting with `on`, as their usage will be
interpreted as an event listener. In other words, Svelte treats `<custom-element
oneworld={true}></custom-element>` as `customElement.addEventListener('eworld',
true)` (and not as `customElement.oneworld = true`)
## docs/svelte/07-misc/06-v4-migration-guide.md
---
This migration guide provides an overview of how to migrate from Svelte version 3
to 4. See the linked PRs for more details about each change. Use the migration
script to migrate some of these automatically: `npx svelte-migrate@latest svelte-4`
Bundlers must now specify the `browser` condition when building a frontend bundle
for the browser. SvelteKit and Vite will handle this automatically for you. If
you're using any others, you may observe lifecycle callbacks such as `onMount` not
get called and you'll need to update the module resolution configuration.
- For Rollup this is done within the `@rollup/plugin-node-resolve` plugin by
setting `browser: true` in its options. See the
[`rollup-plugin-svelte`](https://github.com/sveltejs/rollup-plugin-svelte/#usage)
documentation for more details
- For webpack this is done by adding `"browser"` to the `conditionNames` array. You
may also have to update your `alias` config, if you have set it. See the [`svelte-
loader`](https://github.com/sveltejs/svelte-loader#usage) documentation for more
details
([#8516](https://github.com/sveltejs/svelte/issues/8516))
Svelte no longer supports the CommonJS (CJS) format for compiler output and has
also removed the `svelte/register` hook and the CJS runtime version. If you need to
stay on the CJS output format, consider using a bundler to convert Svelte's ESM
output to CJS in a post-build step.
([#8613](https://github.com/sveltejs/svelte/issues/8613))
```ts
// @errors: 2554 2345
import { createEventDispatcher } from 'svelte';
// Svelte version 3:
dispatch('optional');
dispatch('required'); // I can still omit the detail argument
dispatch('noArgument', 'surprise'); // I can still add a detail argument
```ts
// @noErrors
const action: Action = (node, params) => { ... } // this is now an error if you use
params in any way
const action: Action<HTMLElement, string> = (node, params) => { ... } // params is
of type string
```
- `onMount` now shows a type error if you return a function asynchronously from it,
because this is likely a bug in your code where you expect the callback to be
called on destroy, which it will only do for synchronously returned functions
([#8136](https://github.com/sveltejs/svelte/issues/8136))
```js
// @noErrors
// Example where this change reveals an actual bug
onMount(
// someCleanup() not called because function handed to onMount is async
async () => {
const something = await foo();
// someCleanup() is called because function handed to onMount is sync
() => {
foo().then(something => {...});
// ...
return () => someCleanup();
}
);
```
The creation of custom elements with Svelte has been overhauled and significantly
improved. The `tag` option is deprecated in favor of the new `customElement`
option:
```svelte
<svelte:options tag="my-component" />
<svelte:options customElement="my-component" />
```
## SvelteComponentTyped is deprecated
```js
import { SvelteComponentTyped } from 'svelte';
import { SvelteComponent } from 'svelte';
If you have used `SvelteComponent` as the component instance type previously, you
may see a somewhat opaque type error now, which is solved by changing `: typeof
SvelteComponent` to `: typeof SvelteComponent<any>`.
```svelte
<script>
import ComponentA from './ComponentA.svelte';
import ComponentB from './ComponentB.svelte';
import { SvelteComponent } from 'svelte';
function choseRandomly() {
component = Math.random() > 0.5 ? ComponentA : ComponentB;
}
</script>
<button on:click={choseRandomly}>random</button>
<svelte:element this={component} />
```
Transitions are now local by default to prevent confusion around page navigations.
"local" means that a transition will not play if it's within a nested control flow
block (`each/if/await/key`) and not the direct parent block but a block above it is
created/destroyed. In the following example, the `slide` intro animation will only
play when `success` goes from `false` to `true`, but it will _not_ play when `show`
goes from `false` to `true`:
```svelte
{#if show}
...
{#if success}
<p in:slide>Success</p>
{/each}
{/if}
```
To make transitions global, add the `|global` modifier - then they will play when
_any_ control flow block above is created/destroyed. The migration script will do
this automatically for you.
([#6686](https://github.com/sveltejs/svelte/issues/6686))
Default slot bindings are no longer exposed to named slots and vice versa:
```svelte
<script>
import Nested from './Nested.svelte';
</script>
<Nested let:count>
<p>
count in default slot - is available: {count}
</p>
<p slot="bar">
count in bar slot - is not available: {count}
</p>
</Nested>
```
This makes slot bindings more consistent as the behavior is undefined when for
example the default slot is from a list and the named slot is not. ([#6049]
(https://github.com/sveltejs/svelte/issues/6049))
## Preprocessors
The order in which preprocessors are applied has changed. Now, preprocessors are
executed in order, and within one group, the order is markup, script, style.
```js
// @errors: 2304
import { preprocess } from 'svelte/compiler';
// Svelte 3 logs:
// markup-1
// markup-2
// script-1
// script-2
// style-1
// style-2
// Svelte 4 logs:
// markup-1
// script-1
// style-1
// markup-2
// script-2
// style-2
```
This could affect you for example if you are using `MDsveX` - in which case you
should make sure it comes before any script or style preprocessor.
```js
// @noErrors
preprocess: [
vitePreprocess(),
mdsvex(mdsvexConfig)
mdsvex(mdsvexConfig),
vitePreprocess()
]
```
- the `inert` attribute is now applied to outroing elements to make them invisible
to assistive technology and prevent interaction.
([#8628](https://github.com/sveltejs/svelte/pull/8628))
- the runtime now uses `classList.toggle(name, boolean)` which may not work in very
old browsers. Consider using a [polyfill](https://github.com/eligrey/classList.js)
if you need to support these browsers.
([#8629](https://github.com/sveltejs/svelte/issues/8629))
- the runtime now uses the `CustomEvent` constructor which may not work in very old
browsers. Consider using a [polyfill](https://github.com/theftprevention/event-
constructor-polyfill/tree/master) if you need to support these browsers. ([#8775]
(https://github.com/sveltejs/svelte/pull/8775))
- people implementing their own stores from scratch using the `StartStopNotifier`
interface (which is passed to the create function of `writable` etc) from
`svelte/store` now need to pass an update function in addition to the set function.
This has no effect on people using stores or creating stores using the existing
Svelte stores. ([#6750](https://github.com/sveltejs/svelte/issues/6750))
- `derived` will now throw an error on falsy values instead of stores passed to it.
([#7947](https://github.com/sveltejs/svelte/issues/7947))
- type definitions for `svelte/internal` were removed to further discourage usage
of those internal methods which are not public API. Most of these will likely
change for Svelte 5
- Removal of DOM nodes is now batched which slightly changes its order, which might
affect the order of events fired if you're using a `MutationObserver` on these
elements ([#8763](https://github.com/sveltejs/svelte/pull/8763))
- if you enhanced the global typings through the `svelte.JSX` namespace before, you
need to migrate this to use the `svelteHTML` namespace. Similarly if you used the
`svelte.JSX` namespace to use type definitions from it, you need to migrate those
to use the types from `svelte/elements` instead. You can find more information
about what to do
[here](https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/
typescript.md#im-getting-deprecation-warnings-for-sveltejsx--i-want-to-migrate-to-
the-new-typings)
## docs/svelte/07-misc/07-v5-migration-guide.md
---
Version 5 comes with an overhauled syntax and reactivity system. While it may look
different at first, you'll soon notice many similarities. This guide goes over the
changes in detail and shows you how to upgrade. Along with it, we also provide
information on _why_ we did these changes.
You don't have to migrate to the new syntax right away - Svelte 5 still supports
the old Svelte 4 syntax, and you can mix and match components using the new syntax
with components using the old and vice versa. We expect many people to be able to
upgrade with only a few lines of code changed initially. There's also a [migration
script](#Migration-script) that helps you with many of these steps automatically.
At the heart of Svelte 5 is the new runes API. Runes are basically compiler
instructions that inform Svelte about reactivity. Syntactically, runes are
functions starting with a dollar-sign.
```svelte
<script>
let count =$state(0);
</script>
```
Nothing else changes. `count` is still the number itself, and you read and write
directly to it, without a wrapper like `.value` or `getCount()`.
> `let` being implicitly reactive at the top level worked great, but it meant that
reactivity was constrained - a `let` declaration anywhere else was not reactive.
This forced you to resort to using stores when refactoring code out of the top
level of components for reuse. This meant you had to learn an entirely separate
reactivity model, and the result often wasn't as nice to work with. Because
reactivity is more explicit in Svelte 5, you can keep using the same API outside
the top level of components. Head to [the tutorial](/tutorial) to learn more.
### $: → $derived/$effect
```svelte
<script>
let count = $state(0);
$:constdouble =$derived(count * 2);
</script>
```
As with `$state`, nothing else changes. `double` is still the number itself, and
you read it directly, without a wrapper like `.value` or `getDouble()`.
A `$:` statement could also be used to create side effects. In Svelte 5, this is
achieved using the `$effect` rune:
```svelte
<script>
let count = $state(0);
$:$effect(() =>{
if (count > 5) {
alert('Count is too high!');
}
});
</script>
```
> `$:` was a great shorthand and easy to get started with: you could slap a `$:` in
front of most code and it would somehow work. This intuitiveness was also its
drawback the more complicated your code became, because it wasn't as easy to reason
about. Was the intent of the code to create a derivation, or a side effect? With
`$derived` and `$effect`, you have a bit more up-front decision making to do
(spoiler alert: 90% of the time you want `$derived`), but future-you and other
developers on your team will have an easier time.
>
> There were also gotchas that were hard to spot:
>
> - `$:` only updated directly before rendering, which meant you could read stale
values in-between rerenders
> - `$:` only ran once per tick, which meant that statements may run less often
than you think
> - `$:` dependencies were determined through static analysis of the dependencies.
This worked in most cases, but could break in subtle ways during a refactoring
where dependencies would be for example moved into a function and no longer be
visible as a result
> - `$:` statements were also ordered by using static analysis of the dependencies.
In some cases there could be ties and the ordering would be wrong as a result,
needing manual interventions. Ordering could also break while refactoring code and
some dependencies no longer being visible as a result.
>
> Lastly, it wasn't TypeScript-friendly (our editor tooling had to jump through
some hoops to make it valid for TypeScript), which was a blocker for making
Svelte's reactivity model truly universal.
>
> `$derived` and `$effect` fix all of these by
>
> - always returning the latest value
> - running as often as needed to be stable
> - determining the dependencies at runtime, and therefore being immune to
refactorings
> - executing dependencies as needed and therefore being immune to ordering
problems
> - being TypeScript-friendly
```svelte
<script>
export let optional = 'unset';
export let required;
let { optional = 'unset', required } = $props();
</script>
```
There are multiple cases where declaring properties becomes less straightforward
than having a few `export let` declarations:
- you want to rename the property, for example because the name is a reserved
identifier (e.g. `class`)
- you don't know which other properties to expect in advance
- you want to forward every property to another component
In Svelte 5, the `$props` rune makes this straightforward without any additional
Svelte-specific syntax:
```svelte
<script>
let klass = '';
export { klass as class};
let { class: klass, ...rest } = $props();
</script>
<button class={klass} {...$$restPropsrest}>click me</button>
```
> `export let` was one of the more controversial API decisions, and there was a lot
of debate about whether you should think about a property being `export`ed or
`import`ed. `$props` doesn't have this trait. It's also in line with the other
runes, and the general thinking reduces to "everything special to reactivity in
Svelte is a rune".
>
> There were also a lot of limitations around `export let`, which required
additional API, as shown above. `$props` unite this in one syntactical concept that
leans heavily on regular JavaScript destructuring syntax.
## Event changes
Event handlers have been given a facelift in Svelte 5. Whereas in Svelte 4 we use
the `on:` directive to attach an event listener to an element, in Svelte 5 they are
properties like any other (in other words - remove the colon):
```svelte
<script>
let count = $state(0);
</script>
Since they're just properties, you can use the normal shorthand syntax...
```svelte
<script>
let count = $state(0);
function onclick() {
count++;
}
</script>
<button {onclick}>
clicks: {count}
</button>
```
...though when using a named event handler function it's usually better to use a
more descriptive name.
```svelte
<!file: App.svelte>
<script>
import Pump from './Pump.svelte';
function reset() {
size = 15;
burst = false;
}
</script>
<Pump
on:inflate={(power) => {
size += power.detail;
if (size > 75) burst = true;
}}
on:deflate={(power) => {
if (size > 0) size -= power.detail;
}}
/>
{#if burst}
<button onclick={reset}>new balloon</button>
<span class="boom">💥</span>
{:else}
<span class="balloon" style="scale: {0.01 * size}">
🎈
</span>
{/if}
```
```svelte
<!file: Pump.svelte>
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
Instead of doing `<button on:click>` to 'forward' the event from the element to the
component, the component should accept an `onclick` callback prop:
```svelte
<script>
let { onclick } = $props();
</script>
<buttonon:click{onclick}>
click me
</button>
```
Note that this also means you can 'spread' event handlers onto the element along
with other props instead of tediously forwarding each event separately:
```svelte
<script>
let props = $props();
</script>
```svelte
<button on:click|once|preventDefault={handler}>...</button>
```
Modifiers are specific to `on:` and as such do not work with modern event handlers.
Adding things like `event.preventDefault()` inside the handler itself is
preferable, since all the logic lives in one place rather than being split between
handler and modifiers.
Since event handlers are just functions, you can create your own wrappers as
necessary:
```svelte
<script>
function once(fn) {
return function (event) {
if (fn) fn.call(this, event);
fn = null;
};
}
function preventDefault(fn) {
return function (event) {
event.preventDefault();
fn.call(this, event);
};
}
</script>
<button onclick={once(preventDefault(handler))}>...</button>
```
There are three modifiers — `capture`, `passive` and `nonpassive` — that can't be
expressed as wrapper functions, since they need to be applied when the event
handler is bound rather than when it runs.
```svelte
<button onclickcapture={...}>...</button>
```
Changing the
[`passive`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/
addEventListener#using_passive_listeners) option of an event handler, meanwhile, is
not something to be done lightly. If you have a use case for it — and you probably
don't! — then you will need to use an action to apply the event handler yourself.
```svelte
<button on:click={one} on:click={two}>...</button>
```
```svelte
<button
onclick={(e) => {
one(e);
two(e);
}}
>
...
</button>
```
When spreading props, local event handlers must go _after_ the spread, or they risk
being overwritten:
```svelte
<button
{...props}
onclick={(e) => {
doStuff(e);
props.onclick?.(e);
}}
>
...
</button>
```
They continue to work, however, and you can pass snippets to a component that uses
slots:
```svelte
<!file: Child.svelte>
<slot />
<hr />
<slot name="foo" message="hello" />
```
```svelte
<!file: Parent.svelte>
<script>
import Child from './Child.svelte';
</script>
<Child>
default child content
(The reverse is not true — you cannot pass slotted content to a component that uses
[`{@render ...}`](/docs/svelte/@render) tags.)
When using custom elements, you should still use `<slot />` like before. In a
future version, when Svelte removes its internal version of slots, it will leave
those slots as-is, i.e. output a regular DOM tag instead of transforming it.
In Svelte 4, the easiest way to pass a piece of UI to the child was using a
`<slot />`. In Svelte 5, this is done using the `children` prop instead, which is
then shown with `{@render children()}`:
```svelte
<script>
let { children } = $props();
</script>
<slot />
{@render children?.()}
```
If you wanted multiple UI placeholders, you had to use named slots. In Svelte 5,
use props instead, name them however you like and `{@render ...}` them:
```svelte
<script>
let { header, main, footer } = $props();
</script>
<header>
<slot name="header" />
{@render header()}
</header>
<main>
<slot name="main" />
{@render main()}
</main>
<footer>
<slot name="footer" />
{@render footer()}
</footer>
```
In Svelte 4, you would pass data to a `<slot />` and then retrieve it with `let:`
in the parent component. In Svelte 5, snippets take on that responsibility:
```svelte
<!file: App.svelte>
<script>
import List from './List.svelte';
</script>
```svelte
<!file: List.svelte>
<script>
let { items,item, empty} = $props();
</script>
{#if items.length}
<ul>
{#each items as entry}
<li>
<slot item={entry} />
{@render item(entry)}
</li>
{/each}
</ul>
{:else}
<slot name="empty" />
{@render empty?.()}
{/if}
```
> Slots were easy to get started with, but the more advanced the use case became,
the more involved and confusing the syntax became:
>
> - the `let:` syntax was confusing to many people as it _creates_ a variable
whereas all other `:` directives _receive_ a variable
> - the scope of a variable declared with `let:` wasn't clear. In the example
above, it may look like you can use the `item` slot prop in the `empty` slot, but
that's not true
> - named slots had to be applied to an element using the `slot` attribute.
Sometimes you didn't want to create an element, so we had to add the
`<svelte:fragment>` API
> - named slots could also be applied to a component, which changed the semantics
of where `let:` directives are available (even today us maintainers often don't
know which way around it works)
>
> Snippets solve all of these problems by being much more readable and clear. At
the same time they're more powerful as they allow you to define sections of UI that
you can render _anywhere_, not just passing them as props to a component.
## Migration script
By now you should have a pretty good understanding of the before/after and how the
old syntax relates to the new syntax. It probably also became clear that a lot of
these migrations are rather technical and repetitive - something you don't want to
do by hand.
We thought the same, which is why we provide a migration script to do most of the
migration automatically. You can upgrade your project by using `npx sv migrate
svelte-5`. This will do the following things:
- bump core dependencies in your `package.json`
- migrate to runes (`let` → `$state` etc)
- migrate to event attributes for DOM elements (`on:click` → `onclick`)
- migrate slot creations to render tags (`<slot />` → `{@render children()}`)
- migrate slot usages to snippets (`<div slot="x">...</div>` → `{#snippet
x()}<div>...</div>{/snippet}`)
- migrate obvious component creations (`new Component(...)` →
`mount(Component, ...)`)
You can also migrate a single component in VS Code through the `Migrate Component
to Svelte 5 Syntax` command, or in our Playground through the `Migrate` button.
Not everything can be migrated automatically, and some migrations need manual
cleanup afterwards. The following sections describe these in more detail.
### run
You may see that the migration script converts some of your `$:` statements to a
`run` function which is imported from `svelte/legacy`. This happens if the
migration script couldn't reliably migrate the statement to a `$derived` and
concluded this is a side effect instead. In some cases this may be wrong and it's
best to change this to use a `$derived` instead. In other cases it may be right,
but since `$:` statements also ran on the server but `$effect` does not, it isn't
safe to transform it as such. Instead, `run` is used as a stopgap solution. `run`
mimics most of the characteristics of `$:`, in that it runs on the server once, and
runs as `$effect.pre` on the client (`$effect.pre` runs _before_ changes are
applied to the DOM; most likely you want to use `$effect` instead).
```svelte
<script>
import { run } from 'svelte/legacy';
run(() => {
$effect(() => {
// some side effect code
})
</script>
```
Event modifiers are not applicable to event attributes (e.g. you can't do `onclick|
preventDefault={...}`). Therefore, when migrating event directives to event
attributes, we need a function-replacement for these modifiers. These are imported
from `svelte/legacy`, and should be migrated away from in favor of e.g. just using
`event.preventDefault()`.
```svelte
<script>
import { preventDefault } from 'svelte/legacy';
</script>
<button
onclick={preventDefault((event) => {
event.preventDefault();
// ...
})}
>
click me
</button>
```
The migration script does not convert `createEventDispatcher`. You need to adjust
those parts manually. It doesn't do it because it's too risky because it could
result in breakage for users of the component, which the migration script cannot
find out.
In Svelte 3 and 4, components are classes. In Svelte 5 they are functions and
should be instantiated differently. If you need to manually instantiate components,
you should use `mount` or `hydrate` (imported from `svelte`) instead. If you see
this error using SvelteKit, try updating to the latest version of SvelteKit first,
which adds support for Svelte 5. If you're using Svelte without SvelteKit, you'll
likely have a `main.js` file (or similar) which you need to adjust:
```js
import { mount } from 'svelte';
import App from './App.svelte'
`mount` and `hydrate` have the exact same API. The difference is that `hydrate`
will pick up the Svelte's server-rendered HTML inside its target and hydrate it.
Both return an object with the exports of the component and potentially property
accessors (if compiled with `accessors: true`). They do not come with the `$on`,
`$set` and `$destroy` methods you may know from the class component API. These are
its replacements:
For `$on`, instead of listening to events, pass them via the `events` property on
the options argument.
```js
import { mount } from 'svelte';
import App from './App.svelte'
For `$set`, use `$state` instead to create a reactive property object and
manipulate it. If you're doing this inside a `.js` or `.ts` file, adjust the ending
to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`.
```js
import { mount } from 'svelte';
import App from './App.svelte'
```js
import { mount, unmount } from 'svelte';
import App from './App.svelte'
```js
import { createClassComponent } from 'svelte/legacy';
import App from './App.svelte'
If this component is not under your control, you can use the
`compatibility.componentApi` compiler option for auto-applied backwards
compatibility, which means code using `new Component(...)` keeps working without
adjustments (note that this adds a bit of overhead to each component). This will
also add `$set` and `$on` methods for all component instances you get through
`bind:this`.
```js
/// svelte.config.js
export default {
compilerOptions: {
compatibility: {
componentApi: 4
}
}
};
```
Note that `mount` and `hydrate` are _not_ synchronous, so things like `onMount`
won't have been called by the time the function returns and the pending block of
promises will not have been rendered yet (because `#await` waits a microtask to
wait for a potentially immediately-resolved promise). If you need that guarantee,
call `flushSync` (import from `'svelte'`) after calling `mount/hydrate`.
Similarly, components no longer have a `render` method when compiled for server
side rendering. Instead, pass the function to `render` from `svelte/server`:
```js
import { render } from 'svelte/server';
import App from './App.svelte';
The change from classes towards functions is also reflected in the typings:
`SvelteComponent`, the base class from Svelte 4, is deprecated in favour of the new
`Component` type which defines the function shape of a Svelte component. To
manually define a component shape in a `d.ts` file:
```ts
import type { Component } from 'svelte';
export declare const MyComponent: Component<{
foo: string;
}>;
```
```js
import { ComponentA, ComponentB } from 'component-library';
import type { SvelteComponent } from 'svelte';
import type { Component } from 'svelte';
The two utility types `ComponentEvents` and `ComponentType` are also deprecated.
`ComponentEvents` is obsolete because events are defined as callback props now, and
`ComponentType` is obsolete because the new `Component` type is the component type
already (i.e. `ComponentType<SvelteComponent<{ prop: string }>>` is equivalent to
`Component<{ prop: string }>`).
In Svelte 4, components are _static_ — if you render `<Thing>`, and the value of
`Thing` changes, [nothing happens](/playground/7f1fa24f0ab44c1089dcbb03568f8dfa?
version=4.2.18). To make it dynamic you had to use `<svelte:component>`.
```svelte
<script>
import A from './A.svelte';
import B from './B.svelte';
<select bind:value={Thing}>
<option value={A}>A</option>
<option value={B}>B</option>
</select>
```svelte
{#each items as item}
<item.component {...item.props} />
{/each}
```
- it uses [`Proxies`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/
Reference/Global_Objects/Proxy)
- elements with `clientWidth`/`clientHeight`/`offsetWidth`/`offsetHeight` bindings
use a [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/
ResizeObserver) rather than a convoluted `<iframe>` hack
- `<input type="range" bind:value={...} />` only uses an `input` event listener,
rather than also listening for `change` events as a fallback
The `legacy` compiler option, which generated bulkier but IE-friendly code, no
longer exists.
- The `false`/`true` (already deprecated previously) and the `"none"` values were
removed as valid values from the `css` option
- The `legacy` option was repurposed
- The `hydratable` option has been removed. Svelte components are always hydratable
now
- The `enableSourcemap` option has been removed. Source maps are always generated
now, tooling can choose to ignore it
- The `tag` option was removed. Use `<svelte:options customElement="tag-name" />`
inside the component instead
- The `loopGuardTimeout`, `format`, `sveltePath`, `errorMode` and `varsReport`
options were removed
Content inside component tags becomes a snippet prop called `children`. You cannot
have a separate prop by that name.
Some breaking changes only apply once your component is in runes mode.
Exports from runes mode components cannot be bound to directly. For example, having
`export const foo = ...` in component `A` and then doing `<A bind:foo />` causes an
error. Use `bind:this` instead — `<A bind:this={a} />` — and access the export as
`a.foo`. This change makes things easier to reason about, as it enforces a clear
separation between props and exports.
In Svelte 4 syntax, every property (declared via `export let`) is bindable, meaning
you can `bind:` to it. In runes mode, properties are not bindable by default: you
need to denote bindable props with the `$bindable` rune.
```svelte
<svelte:options accessors={true} />
<script>
// available via componentInstance.name
export let name;
</script>
```
In runes mode, properties are never accessible on the component instance. You can
use component exports instead if you need to expose them.
```svelte
<script>
let { name } = $props();
// available via componentInstance.getName()
export const getName = () => name;
</script>
```
Alternatively, if the place where they are instantiated is under your control, you
can also make use of runes inside `.js/.ts` files by adjusting their ending to
include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`, and then use `$state`:
```js
import { mount } from 'svelte';
import App from './App.svelte'
Setting the `immutable` option has no effect in runes mode. This concept is
replaced by how `$state` and its variations work.
```svelte
<script>
let foo = new Foo();
</script>
In the very rare cases that you need to prevent these event defaults, you should
use [`on`](/docs/svelte/svelte-events#on) instead (for example inside an action).
```svelte
<Component prop=this{is}valid />
```
This is a footgun. In runes mode, if you want to concatenate stuff you must wrap
the value in quotes:
```svelte
<Component prop="this{is}valid" />
```
Note that Svelte 5 will also warn if you have a single expression wrapped in
quotes, like `answer="{42}"` — in Svelte 6, that will cause the value to be
converted to a string, rather than passed as a number.
In Svelte 4, you were allowed to write HTML code that would be repaired by the
browser when server side rendering it. For example you could write this...
```svelte
<table>
<tr>
<td>hi</td>
</tr>
</table>
```
```svelte
<table>
<tbody>
<tr>
<td>hi</td>
</tr>
</tbody>
</table>
```
Svelte 5 is more strict about the HTML structure and will throw a compiler error in
cases where the browser would repair the DOM.
Previously, Svelte did not analyse selectors inside `:is(...)` and `:where(...)`,
effectively treating them as global. Svelte 5 analyses them in the context of the
current component. As such, some selectors may now be treated as unused if they
were relying on this treatment. To fix this, use `:global(...)` inside the
`:is(...)/:where(...)` selectors.
```css
main:global{
@apply bg-blue-100 dark:bg-blue-900;
}
```
Previously Svelte would always insert the CSS hash last. This is no longer
guaranteed in Svelte 5. This is only breaking if you [have very weird css
selectors](https://stackoverflow.com/questions/15670631/does-the-order-of-classes-
listed-on-an-item-affect-the-css).
In the event that you need to support ancient browsers that don't implement
`:where`, you can manually alter the emitted CSS, at the cost of unpredictable
specificity changes:
```js
// @errors: 2552
css = css.replace(/:where\((.+?)\)/, '$1');
```
Error and warning codes have been renamed. Previously they used dashes to separate
the words, they now use underscores (e.g. foo-bar becomes foo_bar). Additionally, a
handful of codes have been reworded slightly.
### Reduced number of namespaces
The number of valid namespaces you can pass to the compiler option `namespace` has
been reduced to `html` (the default), `mathml` and `svg`.
The `foreign` namespace was only useful for Svelte Native, which we're planning to
support differently in a 5.x minor.
```svelte
<button onclick="alert('hello')">...</button>
```
Previously, bindings did not take into account `reset` event of forms, and
therefore values could get out of sync with the DOM. Svelte 5 fixes this by placing
a `reset` listener on the document and invoking bindings where necessary.
### `walk` no longer exported
In Svelte 4 you could have content inside a `<svelte:options />` tag. It was
ignored, but you could write something in there. In Svelte 5, content inside that
tag is a compiler error.
Svelte 4 replaced the `<slot />` tag in all places with its own version of slots.
Svelte 5 preserves them in the case they are a child of a `<template
shadowrootmode="...">` element.
```svelte
<svelte:element this={"div"}>
```
The `mount` function used to render a component tree plays transitions by default
unless the `intro` option is set to `false`. This is different from legacy class
components which, when manually instantiated, didn't play transitions by default.
### `<img src={...}>` and `{@html ...}` hydration mismatches are not repaired
In Svelte 4, if the value of a `src` attribute or `{@html ...}` tag differ between
server and client (a.k.a. a hydration mismatch), the mismatch is repaired. This is
very costly: setting a `src` attribute (even if it evaluates to the same thing)
causes images and iframes to be reloaded, and reinserting a large blob of HTML is
slow.
Since these mismatches are extremely rare, Svelte 5 assumes that the values are
unchanged, but in development will warn you if they are not. To force an update you
can do something like this:
```svelte
<script>
let { markup, src } = $props();
$effect(() => {
// ...and reset after we've mounted
markup = initial.markup;
src = initial.src;
});
}
</script>
{@html markup}
<img {src} />
```
Svelte 5 makes use of comments during server side rendering which are used for more
robust and efficient hydration on the client. As such, you shouldn't remove
comments from your HTML output if you intend to hydrate it, and if you manually
authored HTML to be hydrated by a Svelte component, you need to adjust that HTML to
include said comments at the correct positions.
<!-- TODO in final docs, add link to corresponding section for more details -->
## docs/svelte/07-misc/99-faq.md
---
We think the best way to get started is playing through the interactive [tutorial]
(/tutorial). Each step there is mainly focused on one specific aspect and is easy
to follow. You'll be editing and running real Svelte components right in your
browser.
Five to ten minutes should be enough to get you up and running. An hour and a half
should get you through the entire tutorial.
There are online forums and chats which are a great place for discussion about best
practices, application architecture or just to get to know fellow Svelte users.
[Our Discord](/chat) or [the Reddit channel](https://www.reddit.com/r/sveltejs/)
are examples of that. If you have an answerable code-level question, Stack Overflow
is usually a better fit.
In editors which use the Svelte Language Server you can document Components,
functions and exports using specially formatted comments.
````svelte
<script>
/** What should we call the user? */
export let name = 'world';
</script>
<!--
@component
Here's some documentation for this component.
It will show up on hover.
There will be a blog post about this eventually, but in the meantime, check out
[this issue](https://github.com/sveltejs/svelte/issues/2546).
How your application is structured and where logic is defined will determine the
best way to ensure it is properly tested. It is important to note that not all
logic belongs within a component - this includes concerns such as data
transformation, cross-component state management, and logging, among others.
Remember that the Svelte library has its own test suite, so you do not need to
write tests to validate implementation details provided by Svelte.
A Svelte application will typically have three different types of tests: Unit,
Component, and End-to-End (E2E).
_End-to-End Tests_: To ensure your users are able to interact with your application
it is necessary to test it as a whole in a manner as close to production as
possible. This is done by writing end-to-end (E2E) tests which load and interact
with a deployed version of your application in order to simulate how the user will
interact with your application. When creating a new SvelteKit project, you will be
asked whether you would like to setup [Playwright](https://playwright.dev/) for
end-to-end testing. There are many other E2E test libraries available for use as
well.
## Is there a router?
However, you can use any router library. A lot of people use
[page.js](https://github.com/visionmedia/page.js). There's also
[navaid](https://github.com/lukeed/navaid), which is very similar. And [universal-
router](https://github.com/kriasoft/universal-router), which is isomorphic with
child routes, but without built-in history support.
If you need hash-based routing on the client side, check out the [hash option]
(https://svelte.dev/docs/kit/configuration#router) in SvelteKit, [svelte-spa-
router](https://github.com/ItalyPaleAle/svelte-spa-router), or [abstract-state-
router](https://github.com/TehShrike/abstract-state-router/).
While most mobile apps are written without using JavaScript, if you'd like to
leverage your existing Svelte components and knowledge of Svelte when building
mobile apps, you can turn a [SvelteKit SPA](https://kit.svelte.dev/docs/single-
page-apps) into a mobile app with
[Tauri](https://v2.tauri.app/start/frontend/sveltekit/) or
[Capacitor](https://capacitorjs.com/solution/svelte). Mobile features like the
camera, geolocation, and push notifications are available via plugins for both
platforms.
Svelte Native was an option available for Svelte 4, but note that Svelte 5 does not
currently support it. Svelte Native lets you write NativeScript apps using Svelte
components that contain [NativeScript UI
components](https://docs.nativescript.org/ui/) rather than DOM elements, which may
be familiar for users coming from React Native.
Svelte's component style scoping works by generating a class unique to the given
component, adding it to the relevant elements in the component that are under
Svelte's control, and then adding it to each of the selectors in that component's
styles. When the compiler can't see what elements a style selector applies to,
there would be two bad options for keeping it:
- If it keeps the selector and adds the scoping class to it, the selector will
likely not match the expected elements in the component, and they definitely won't
if they were created by a child component or `{@html ...}`.
- If it keeps the selector without adding the scoping class to it, the given style
will become a global style, affecting your entire page.
If you need to style something that Svelte can't identify at compile time, you will
need to explicitly opt into global styles by using `:global(...)`. But also keep in
mind that you can wrap `:global(...)` around only part of a selector.
`.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the
component's `.foo` elements. As long as there's some parent element in the current
component to start from, partially global selectors like this will almost always be
able to get you what you want.
New features aren't being added to it, and bugs will probably only be fixed if they
are extremely nasty or present some sort of security vulnerability.
We recommend using [SvelteKit](/docs/kit), which supports HMR out of the box and is
built on top of [Vite](https://vitejs.dev/) and
[svelte-hmr](https://github.com/sveltejs/svelte-hmr). There are also community
plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and
[webpack](https://github.com/sveltejs/svelte-loader).
## docs/svelte/07-misc/xx-reactivity-indepth.md
---
- how to think about Runes ("just JavaScript" with added reactivity, what this
means for keeping reactivity alive across boundaries)
- signals
## docs/svelte/98-reference/index.md
---
title: Reference
---
## docs/svelte/98-reference/20-svelte.md
---
title: svelte
---
```js
// @noErrors
import {
SvelteComponent,
SvelteComponentTyped,
afterUpdate,
beforeUpdate,
createEventDispatcher,
createRawSnippet,
flushSync,
getAllContexts,
getContext,
hasContext,
hydrate,
mount,
onDestroy,
onMount,
setContext,
tick,
unmount,
untrack
} from 'svelte';
```
## SvelteComponent
This was the base class for Svelte components in Svelte 4. Svelte 5+ components
are completely different under the hood. For typing, use `Component` instead.
To instantiate components, use `mount` instead.
See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-
classes) for more info.
<div class="ts-block">
```dts
class SvelteComponent<
Props extends Record<string, any> = Record<string, any>,
Events extends Record<string, any> = any,
Slots extends Record<string, any> = any
> {/*…*/}
```
<div class="ts-block-property">
```dts
static element?: typeof HTMLElement;
```
<div class="ts-block-property-details">
The custom element version of the component. Only present if compiled with the
`customElement` compiler option
</div>
</div>
<div class="ts-block-property">
```dts
[prop: string]: any;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
constructor(options: ComponentConstructorOptions<Properties<Props, Slots>>);
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
$destroy(): void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
$on<K extends Extract<keyof Events, string>>(
type: K,
callback: (e: Events[K]) => void
): () => void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
$set(props: Partial<Props>): void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
## SvelteComponentTyped
</blockquote>
<div class="ts-block">
```dts
class SvelteComponentTyped<
Props extends Record<string, any> = Record<string, any>,
Events extends Record<string, any> = any,
Slots extends Record<string, any> = any
> extends SvelteComponent<Props, Events, Slots> {}
```
</div>
## afterUpdate
</blockquote>
Schedules a callback to run immediately after the component has been updated.
The first time the callback runs will be after the initial `onMount`.
<div class="ts-block">
```dts
function afterUpdate(fn: () => void): void;
```
</div>
## beforeUpdate
</blockquote>
Schedules a callback to run immediately before the component is updated after any
state change.
The first time the callback runs will be before the initial `onMount`.
<div class="ts-block">
```dts
function beforeUpdate(fn: () => void): void;
```
</div>
## createEventDispatcher
</blockquote>
The event dispatcher can be typed to narrow the allowed event names and the type of
the `detail` argument:
```ts
const dispatch = createEventDispatcher<{
loaded: never; // does not take a detail argument
change: string; // takes a detail argument of type string, which is required
optional: number | null; // takes an optional detail argument of type number
}>();
```
<div class="ts-block">
```dts
function createEventDispatcher<
EventMap extends Record<string, any> = any
>(): EventDispatcher<EventMap>;
```
</div>
## createRawSnippet
<div class="ts-block">
```dts
function createRawSnippet<Params extends unknown[]>(
fn: (...params: Getters<Params>) => {
render: () => string;
setup?: (element: Element) => void | (() => void);
}
): Snippet<Params>;
```
</div>
## flushSync
<div class="ts-block">
```dts
function flushSync<T = void>(fn?: (() => T) | undefined): T;
```
</div>
## getAllContexts
Retrieves the whole context map that belongs to the closest parent component.
Must be called during component initialisation. Useful, for example, if you
programmatically create a component and want to pass the existing context to it.
<div class="ts-block">
```dts
function getAllContexts<
T extends Map<any, any> = Map<any, any>
>(): T;
```
</div>
## getContext
Retrieves the context that belongs to the closest parent component with the
specified `key`.
Must be called during component initialisation.
<div class="ts-block">
```dts
function getContext<T>(key: any): T;
```
</div>
## hasContext
Checks whether a given `key` has been set in the context of a parent component.
Must be called during component initialisation.
<div class="ts-block">
```dts
function hasContext(key: any): boolean;
```
</div>
## hydrate
Hydrates a component on the given target and returns the exports and potentially
the props (if compiled with `accessors: true`) of the component
<div class="ts-block">
```dts
function hydrate<
Props extends Record<string, any>,
Exports extends Record<string, any>
>(
component:
| ComponentType<SvelteComponent<Props>>
| Component<Props, Exports, any>,
options: {} extends Props
? {
target: Document | Element | ShadowRoot;
props?: Props;
events?: Record<string, (e: any) => any>;
context?: Map<any, any>;
intro?: boolean;
recover?: boolean;
}
: {
target: Document | Element | ShadowRoot;
props: Props;
events?: Record<string, (e: any) => any>;
context?: Map<any, any>;
intro?: boolean;
recover?: boolean;
}
): Exports;
```
</div>
## mount
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`.
<div class="ts-block">
```dts
function mount<
Props extends Record<string, any>,
Exports extends Record<string, any>
>(
component:
| ComponentType<SvelteComponent<Props>>
| Component<Props, Exports, any>,
options: MountOptions<Props>
): Exports;
```
</div>
## onDestroy
<div class="ts-block">
```dts
function onDestroy(fn: () => any): void;
```
</div>
## onMount
It must be called during the component's initialisation (but doesn't need to live
_inside_ the component;
it can be called from an external module). If a function is returned
_synchronously_ from `onMount`,
it will be called when the component is unmounted.
<div class="ts-block">
```dts
function onMount<T>(
fn: () =>
| NotFunction<T>
| Promise<NotFunction<T>>
| (() => any)
): void;
```
</div>
## setContext
Associates an arbitrary `context` object with the current component and the
specified `key`
and returns that object. The context is then available to children of the component
(including slotted content) with `getContext`.
<div class="ts-block">
```dts
function setContext<T>(key: any, context: T): T;
```
</div>
## tick
Returns a promise that resolves once any pending state changes have been applied.
<div class="ts-block">
```dts
function tick(): Promise<void>;
```
</div>
## unmount
```js
// @errors: 7031
import { mount, unmount } from 'svelte';
import App from './App.svelte';
// later...
unmount(app, { outro: true });
```
<div class="ts-block">
```dts
function unmount(
component: Record<string, any>,
options?:
| {
outro?: boolean;
}
| undefined
): Promise<void>;
```
</div>
## untrack
```ts
$effect(() => {
// this will run when `data` changes, but not when `time` changes
save(data, {
timestamp: untrack(() => time)
});
});
```
<div class="ts-block">
```dts
function untrack<T>(fn: () => T): T;
```
</div>
## Component
#### Example:
<div class="ts-block">
```dts
interface Component<
Props extends Record<string, any> = {},
Exports extends Record<string, any> = {},
Bindings extends keyof Props | '' = string
> {/*…*/}
```
<div class="ts-block-property">
```dts
(
this: void,
internals: ComponentInternals,
props: Props
): {
/**
* @deprecated This method only exists when using one of the legacy
compatibility helpers, which
* is a stop-gap solution. See [migration
guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-
classes)
* for more info.
*/
$on?(type: string, callback: (e: any) => void): () => void;
/**
* @deprecated This method only exists when using one of the legacy
compatibility helpers, which
* is a stop-gap solution. See [migration
guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-
classes)
* for more info.
*/
$set?(props: Partial<Props>): void;
} & Exports;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
element?: typeof HTMLElement;
```
<div class="ts-block-property-details">
The custom element version of the component. Only present if compiled with the
`customElement` compiler option
</div>
</div></div>
## ComponentConstructorOptions
</blockquote>
<div class="ts-block">
```dts
interface ComponentConstructorOptions<
Props extends Record<string, any> = Record<string, any>
> {/*…*/}
```
<div class="ts-block-property">
```dts
target: Element | Document | ShadowRoot;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
anchor?: Element;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
props?: Props;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
context?: Map<any, any>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
hydrate?: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
intro?: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
recover?: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
sync?: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
idPrefix?: string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
$$inline?: boolean;
```
<div class="ts-block-property-details"></div>
</div></div>
## ComponentEvents
The new `Component` type does not have a dedicated Events type. Use
`ComponentProps` instead.
</blockquote>
<div class="ts-block">
```dts
type ComponentEvents<Comp extends SvelteComponent> =
Comp extends SvelteComponent<any, infer Events>
? Events
: never;
```
</div>
## ComponentInternals
<div class="ts-block">
```dts
type ComponentInternals = Branded<{}, 'ComponentInternals'>;
```
</div>
## ComponentProps
```ts
import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';
Example: A generic function that accepts some component and infers the type of its
props:
```ts
import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';
<div class="ts-block">
```dts
type ComponentProps<
Comp extends SvelteComponent | Component<any, any>
> =
Comp extends SvelteComponent<infer Props>
? Props
: Comp extends Component<infer Props, any>
? Props
: never;
```
</div>
## ComponentType
This type is obsolete when working with the new `Component` type.
</blockquote>
<div class="ts-block">
```dts
type ComponentType<
Comp extends SvelteComponent = SvelteComponent
> = (new (
options: ComponentConstructorOptions<
Comp extends SvelteComponent<infer Props>
? Props
: Record<string, any>
>
) => Comp) & {
/** The custom element version of the component. Only present if compiled
with the `customElement` compiler option */
element?: typeof HTMLElement;
};
```
</div>
## EventDispatcher
<div class="ts-block">
```dts
interface EventDispatcher<
EventMap extends Record<string, any>
> {/*…*/}
```
<div class="ts-block-property">
```dts
<Type extends keyof EventMap>(
...args: null extends EventMap[Type]
? [type: Type, parameter?: EventMap[Type] | null | undefined, options?:
DispatchOptions]
: undefined extends EventMap[Type]
? [type: Type, parameter?: EventMap[Type] | null | undefined,
options?: DispatchOptions]
: [type: Type, parameter: EventMap[Type], options?:
DispatchOptions]
): boolean;
```
<div class="ts-block-property-details"></div>
</div></div>
## MountOptions
<div class="ts-block">
```dts
type MountOptions<
Props extends Record<string, any> = Record<string, any>
> = {
/**
* Target element where the component will be mounted.
*/
target: Document | Element | ShadowRoot;
/**
* Optional node inside `target`. When specified, it is used to render the
component immediately before it.
*/
anchor?: Node;
/**
* Allows the specification of events.
* @deprecated Use callback props instead.
*/
events?: Record<string, (e: any) => any>;
/**
* Can be accessed via `getContext()` at the component level.
*/
context?: Map<any, any>;
/**
* Whether or not to play transitions on initial render.
* @default true
*/
intro?: boolean;
} & ({} extends Props
? {
/**
* Component properties.
*/
props?: Props;
}
: {
/**
* Component properties.
*/
props: Props;
});
```
</div>
## Snippet
The type of a `#snippet` block. You can use it to (for example) express that your
component expects a snippet of a certain type:
```ts
let { banner }: { banner: Snippet<[{ text: string }]> } = $props();
```
You can only call a snippet through the `{@render ...}` tag.
<div class="ts-block">
```dts
interface Snippet<Parameters extends unknown[] = []> {/*…*/}
```
<div class="ts-block-property">
```dts
(
this: void,
// this conditional allows tuples but not arrays. Arrays would indicate a
// rest parameter type, which is not supported. If rest parameters are added
// in the future, the condition can be removed.
...args: number extends Parameters['length'] ? never : Parameters
): {
'{@render ...} must be called with a Snippet': "import type { Snippet } from
'svelte'";
} & typeof SnippetReturn;
```
<div class="ts-block-property-details"></div>
</div></div>
## docs/svelte/98-reference/21-svelte-action.md
---
title: svelte/action
---
## Action
You can return an object with methods `update` and `destroy` from the function and
type which additional attributes and events it has.
See interface `ActionReturn` for more details.
<div class="ts-block">
```dts
interface Action<
Element = HTMLElement,
Parameter = undefined,
Attributes extends Record<string, any> = Record<
never,
any
>
> {/*…*/}
```
<div class="ts-block-property">
```dts
<Node extends Element>(
...args: undefined extends Parameter
? [node: Node, parameter?: Parameter]
: [node: Node, parameter: Parameter]
): void | ActionReturn<Parameter, Attributes>;
```
<div class="ts-block-property-details"></div>
</div></div>
## ActionReturn
Actions can return an object containing the two properties defined in this
interface. Both are optional.
- update: An action can have a parameter. This method will be called whenever that
parameter changes,
immediately after Svelte has applied updates to the markup. `ActionReturn`
and `ActionReturn<undefined>` both
mean that the action accepts no parameters.
- destroy: Method that is called after the element is unmounted
Additionally, you can specify which additional attributes and events the action
enables on the applied element.
This applies to TypeScript typings only and has no effect at runtime.
Example usage:
```ts
interface Attributes {
newprop?: string;
'on:event': (e: CustomEvent<boolean>) => void;
}
<div class="ts-block">
```dts
interface ActionReturn<
Parameter = undefined,
Attributes extends Record<string, any> = Record<
never,
any
>
> {/*…*/}
```
<div class="ts-block-property">
```dts
update?: (parameter: Parameter) => void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
destroy?: () => void;
```
<div class="ts-block-property-details"></div>
</div></div>
## docs/svelte/98-reference/21-svelte-animate.md
---
title: svelte/animate
---
```js
// @noErrors
import { flip } from 'svelte/animate';
```
## flip
The flip function calculates the start and end position of an element and animates
between them, translating the x and y values.
`flip` stands for [First, Last, Invert, Play](https://aerotwist.com/blog/flip-your-
animations/).
<div class="ts-block">
```dts
function flip(
node: Element,
{
from,
to
}: {
from: DOMRect;
to: DOMRect;
},
params?: FlipParams
): AnimationConfig;
```
</div>
## AnimationConfig
<div class="ts-block">
```dts
interface AnimationConfig {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: (t: number) => number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
css?: (t: number, u: number) => string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
tick?: (t: number, u: number) => void;
```
<div class="ts-block-property-details"></div>
</div></div>
## FlipParams
<div class="ts-block">
```dts
interface FlipParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number | ((len: number) => number);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: (t: number) => number;
```
<div class="ts-block-property-details"></div>
</div></div>
## docs/svelte/98-reference/21-svelte-compiler.md
---
title: svelte/compiler
---
```js
// @noErrors
import {
VERSION,
compile,
compileModule,
migrate,
parse,
preprocess,
walk
} from 'svelte/compiler';
```
## VERSION
<div class="ts-block">
```dts
const VERSION: string;
```
</div>
## compile
`compile` converts your `.svelte` source code into a JavaScript module that exports
a component
<div class="ts-block">
```dts
function compile(
source: string,
options: CompileOptions
): CompileResult;
```
</div>
## compileModule
`compileModule` takes your JavaScript source code containing runes, and turns it
into a JavaScript module.
<div class="ts-block">
```dts
function compileModule(
source: string,
options: ModuleCompileOptions
): CompileResult;
```
</div>
## migrate
Does a best-effort migration of Svelte code towards using runes, event attributes
and render tags.
May throw an error if the code is too complex to migrate automatically.
<div class="ts-block">
```dts
function migrate(
source: string,
{
filename,
use_ts
}?:
| {
filename?: string;
use_ts?: boolean;
}
| undefined
): {
code: string;
};
```
</div>
## parse
The parse function parses a component, returning only its abstract syntax tree.
The `modern` option (`false` by default in Svelte 5) makes the parser return a
modern AST instead of the legacy AST.
`modern` will become `true` by default in Svelte 6, and the option will be removed
in Svelte 7.
<div class="ts-block">
```dts
function parse(
source: string,
options: {
filename?: string;
modern: true;
loose?: boolean;
}
): AST.Root;
```
</div>
<div class="ts-block">
```dts
function parse(
source: string,
options?:
| {
filename?: string;
modern?: false;
loose?: boolean;
}
| undefined
): Record<string, any>;
```
</div>
## preprocess
<div class="ts-block">
```dts
function preprocess(
source: string,
preprocessor: PreprocessorGroup | PreprocessorGroup[],
options?:
| {
filename?: string;
}
| undefined
): Promise<Processed>;
```
</div>
## walk
</blockquote>
<div class="ts-block">
```dts
function walk(): never;
```
</div>
## AST
<div class="ts-block">
```dts
namespace AST {
export interface BaseNode {
type: string;
start: number;
end: number;
}
</div>
## CompileError
<div class="ts-block">
```dts
interface CompileError extends ICompileDiagnostic {}
```
</div>
## CompileOptions
<div class="ts-block">
```dts
interface CompileOptions extends ModuleCompileOptions {/*…*/}
```
<div class="ts-block-property">
```dts
name?: string;
```
<div class="ts-block-property-details">
Sets the name of the resulting JavaScript class (though the compiler will rename it
if it would otherwise conflict with other variables in scope).
If unspecified, will be inferred from `filename`
</div>
</div>
<div class="ts-block-property">
```dts
customElement?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
accessors?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, getters and setters will be created for the component's props. If
`false`, they will only be created for readonly exported values (i.e. those
declared with `const`, `class` and `function`). If compiling with `customElement:
true` this option defaults to `true`.
</div>
</div>
<div class="ts-block-property">
```dts
namespace?: Namespace;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- <span class="tag">default</span> `'html'`
</div>
</div>
</div>
<div class="ts-block-property">
```dts
immutable?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, tells the compiler that you promise not to mutate any objects.
This allows it to be less conservative about checking whether values have changed.
</div>
</div>
<div class="ts-block-property">
```dts
css?: 'injected' | 'external';
```
<div class="ts-block-property-details">
- `'injected'`: styles will be included in the `head` when using `render(...)`, and
injected into the document (if not already present) when the component mounts. For
components compiled as custom elements, styles are injected to the shadow root.
- `'external'`: the CSS will only be returned in the `css` field of the compilation
result. Most Svelte bundler plugins will set this to `'external'` and use the CSS
that is statically generated for better performance, as it will result in smaller
JavaScript bundles and the output can be served as cacheable `.css` files.
This is always `'injected'` when compiling with `customElement` mode.
</div>
</div>
<div class="ts-block-property">
```dts
cssHash?: CssHashGetter;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
A function that takes a `{ hash, css, name, filename }` argument and returns the
string that is used as a classname for scoped CSS.
It defaults to returning `svelte-${hash(css)}`.
</div>
</div>
<div class="ts-block-property">
```dts
preserveComments?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, your HTML comments will be preserved in the output. By default, they are
stripped out.
</div>
</div>
<div class="ts-block-property">
```dts
preserveWhitespace?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, whitespace inside and between elements is kept as you typed it, rather
than removed or collapsed to a single space where possible.
</div>
</div>
<div class="ts-block-property">
```dts
runes?: boolean | undefined;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Set to `true` to force the compiler into runes mode, even if there are no
indications of runes usage.
Set to `false` to force the compiler into ignoring runes, even if there are
indications of runes usage.
Set to `undefined` (the default) to infer runes mode from the component code.
Is always `true` for JS/TS modules compiled with Svelte.
Will be `true` by default in Svelte 6.
Note that setting this to `true` in your `svelte.config.js` will force runes mode
for your entire project, including components in `node_modules`,
which is likely not what you want. If you're using Vite, consider using
[dynamicCompileOptions](https://github.com/sveltejs/vite-plugin-svelte/blob/main/
docs/config.md#dynamiccompileoptions) instead.
</div>
</div>
<div class="ts-block-property">
```dts
discloseVersion?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, exposes the Svelte major version in the browser by adding it to a `Set`
stored in the global `window.__svelte.v`.
</div>
</div>
<div class="ts-block-property">
```dts
compatibility?: {/*…*/}
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children"><div class="ts-block-property">
```dts
componentApi?: 4 | 5;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Applies a transformation so that the default export of Svelte files can still be
instantiated the same way as in Svelte 4 —
as a class when compiling for the browser (as though using
`createClassComponent(MyComponent, {...})` from `svelte/legacy`)
or as an object with a `.render(...)` method when compiling for the server
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
sourcemap?: object | string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
An initial sourcemap that will be merged into the final output sourcemap.
This is usually the preprocessor sourcemap.
</div>
</div>
<div class="ts-block-property">
```dts
outputFilename?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
<div class="ts-block-property">
```dts
cssOutputFilename?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
hmr?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
modernAst?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, returns the modern version of the AST.
Will become `true` by default in Svelte 6, and the option will be removed in Svelte
7.
</div>
</div></div>
## CompileResult
<div class="ts-block">
```dts
interface CompileResult {/*…*/}
```
<div class="ts-block-property">
```dts
js: {/*…*/}
```
<div class="ts-block-property-details">
```dts
code: string;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
map: SourceMap;
```
<div class="ts-block-property-details">
A source map
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
css: null | {
/** The generated code */
code: string;
/** A source map */
map: SourceMap;
};
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
warnings: Warning[];
```
<div class="ts-block-property-details">
An array of warning objects that were generated during compilation. Each warning
has several properties:
- `code` is a string identifying the category of warning
- `message` describes the issue in human-readable terms
- `start` and `end`, if the warning relates to a specific location, are objects
with `line`, `column` and `character` properties
</div>
</div>
<div class="ts-block-property">
```dts
metadata: {/*…*/}
```
<div class="ts-block-property-details">
```dts
runes: boolean;
```
<div class="ts-block-property-details">
Whether the file was compiled in runes mode, either because of an explicit option
or inferred from usage.
For `compileModule`, this is always `true`
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
ast: any;
```
<div class="ts-block-property-details">
The AST
</div>
</div></div>
## MarkupPreprocessor
A markup preprocessor that takes a string of code and returns a processed version.
<div class="ts-block">
```dts
type MarkupPreprocessor = (options: {
/**
* The whole Svelte file content
*/
content: string;
/**
* The filename of the Svelte file
*/
filename?: string;
}) => Processed | void | Promise<Processed | void>;
```
</div>
## ModuleCompileOptions
<div class="ts-block">
```dts
interface ModuleCompileOptions {/*…*/}
```
<div class="ts-block-property">
```dts
dev?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, causes extra code to be added that will perform runtime checks and
provide debugging information during development.
</div>
</div>
<div class="ts-block-property">
```dts
generate?: 'client' | 'server' | false;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
filename?: string;
```
<div class="ts-block-property-details">
Used for debugging hints and sourcemaps. Your bundler plugin will set it
automatically.
</div>
</div>
<div class="ts-block-property">
```dts
rootDir?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Used for ensuring filenames don't leak filesystem information. Your bundler plugin
will set it automatically.
</div>
</div>
<div class="ts-block-property">
```dts
warningFilter?: (warning: Warning) => boolean;
```
<div class="ts-block-property-details">
</div>
</div></div>
## Preprocessor
<div class="ts-block">
```dts
type Preprocessor = (options: {
/**
* The script/style tag content
*/
content: string;
/**
* The attributes on the script/style tag
*/
attributes: Record<string, string | boolean>;
/**
* The whole Svelte file content
*/
markup: string;
/**
* The filename of the Svelte file
*/
filename?: string;
}) => Processed | void | Promise<Processed | void>;
```
</div>
## PreprocessorGroup
<div class="ts-block">
```dts
interface PreprocessorGroup {/*…*/}
```
<div class="ts-block-property">
```dts
name?: string;
```
<div class="ts-block-property-details">
Name of the preprocessor. Will be a required option in the next major version
</div>
</div>
<div class="ts-block-property">
```dts
markup?: MarkupPreprocessor;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
style?: Preprocessor;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
script?: Preprocessor;
```
<div class="ts-block-property-details"></div>
</div></div>
## Processed
The result of a preprocessor run. If the preprocessor does not return a result, it
is assumed that the code is unchanged.
<div class="ts-block">
```dts
interface Processed {/*…*/}
```
<div class="ts-block-property">
```dts
code: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property">
```dts
map?: string | object;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
dependencies?: string[];
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
attributes?: Record<string, string | boolean>;
```
<div class="ts-block-property-details">
Only for script/style preprocessors: The updated attributes to set on the tag. If
undefined, attributes stay unchanged.
</div>
</div>
<div class="ts-block-property">
```dts
toString?: () => string;
```
<div class="ts-block-property-details"></div>
</div></div>
## Warning
<div class="ts-block">
```dts
interface Warning extends ICompileDiagnostic {}
```
</div>
## docs/svelte/98-reference/21-svelte-easing.md
---
title: svelte/easing
---
```js
// @noErrors
import {
backIn,
backInOut,
backOut,
bounceIn,
bounceInOut,
bounceOut,
circIn,
circInOut,
circOut,
cubicIn,
cubicInOut,
cubicOut,
elasticIn,
elasticInOut,
elasticOut,
expoIn,
expoInOut,
expoOut,
linear,
quadIn,
quadInOut,
quadOut,
quartIn,
quartInOut,
quartOut,
quintIn,
quintInOut,
quintOut,
sineIn,
sineInOut,
sineOut
} from 'svelte/easing';
```
## backIn
<div class="ts-block">
```dts
function backIn(t: number): number;
```
</div>
## backInOut
<div class="ts-block">
```dts
function backInOut(t: number): number;
```
</div>
## backOut
<div class="ts-block">
```dts
function backOut(t: number): number;
```
</div>
## bounceIn
<div class="ts-block">
```dts
function bounceIn(t: number): number;
```
</div>
## bounceInOut
<div class="ts-block">
```dts
function bounceInOut(t: number): number;
```
</div>
## bounceOut
<div class="ts-block">
```dts
function bounceOut(t: number): number;
```
</div>
## circIn
<div class="ts-block">
```dts
function circIn(t: number): number;
```
</div>
## circInOut
<div class="ts-block">
```dts
function circInOut(t: number): number;
```
</div>
## circOut
<div class="ts-block">
```dts
function circOut(t: number): number;
```
</div>
## cubicIn
<div class="ts-block">
```dts
function cubicIn(t: number): number;
```
</div>
## cubicInOut
<div class="ts-block">
```dts
function cubicInOut(t: number): number;
```
</div>
## cubicOut
<div class="ts-block">
```dts
function cubicOut(t: number): number;
```
</div>
## elasticIn
<div class="ts-block">
```dts
function elasticIn(t: number): number;
```
</div>
## elasticInOut
<div class="ts-block">
```dts
function elasticInOut(t: number): number;
```
</div>
## elasticOut
<div class="ts-block">
```dts
function elasticOut(t: number): number;
```
</div>
## expoIn
<div class="ts-block">
```dts
function expoIn(t: number): number;
```
</div>
## expoInOut
<div class="ts-block">
```dts
function expoInOut(t: number): number;
```
</div>
## expoOut
<div class="ts-block">
```dts
function expoOut(t: number): number;
```
</div>
## linear
<div class="ts-block">
```dts
function linear(t: number): number;
```
</div>
## quadIn
<div class="ts-block">
```dts
function quadIn(t: number): number;
```
</div>
## quadInOut
<div class="ts-block">
```dts
function quadInOut(t: number): number;
```
</div>
## quadOut
<div class="ts-block">
```dts
function quadOut(t: number): number;
```
</div>
## quartIn
<div class="ts-block">
```dts
function quartIn(t: number): number;
```
</div>
## quartInOut
<div class="ts-block">
```dts
function quartInOut(t: number): number;
```
</div>
## quartOut
<div class="ts-block">
```dts
function quartOut(t: number): number;
```
</div>
## quintIn
<div class="ts-block">
```dts
function quintIn(t: number): number;
```
</div>
## quintInOut
<div class="ts-block">
```dts
function quintInOut(t: number): number;
```
</div>
## quintOut
<div class="ts-block">
```dts
function quintOut(t: number): number;
```
</div>
## sineIn
<div class="ts-block">
```dts
function sineIn(t: number): number;
```
</div>
## sineInOut
<div class="ts-block">
```dts
function sineInOut(t: number): number;
```
</div>
## sineOut
<div class="ts-block">
```dts
function sineOut(t: number): number;
```
</div>
## docs/svelte/98-reference/21-svelte-events.md
---
title: svelte/events
---
```js
// @noErrors
import { on } from 'svelte/events';
```
## on
Attaches an event handler to the window and returns a function that removes the
handler. Using this
rather than `addEventListener` will preserve the correct order relative to handlers
added declaratively
(with attributes like `onclick`), which use event delegation for performance
reasons
<div class="ts-block">
```dts
function on<Type extends keyof WindowEventMap>(
window: Window,
type: Type,
handler: (
this: Window,
event: WindowEventMap[Type]
) => any,
options?: AddEventListenerOptions | undefined
): () => void;
```
</div>
<div class="ts-block">
```dts
function on<Type extends keyof DocumentEventMap>(
document: Document,
type: Type,
handler: (
this: Document,
event: DocumentEventMap[Type]
) => any,
options?: AddEventListenerOptions | undefined
): () => void;
```
</div>
<div class="ts-block">
```dts
function on<
Element extends HTMLElement,
Type extends keyof HTMLElementEventMap
>(
element: Element,
type: Type,
handler: (
this: Element,
event: HTMLElementEventMap[Type]
) => any,
options?: AddEventListenerOptions | undefined
): () => void;
```
</div>
<div class="ts-block">
```dts
function on<
Element extends MediaQueryList,
Type extends keyof MediaQueryListEventMap
>(
element: Element,
type: Type,
handler: (
this: Element,
event: MediaQueryListEventMap[Type]
) => any,
options?: AddEventListenerOptions | undefined
): () => void;
```
</div>
<div class="ts-block">
```dts
function on(
element: EventTarget,
type: string,
handler: EventListener,
options?: AddEventListenerOptions | undefined
): () => void;
```
</div>
## docs/svelte/98-reference/21-svelte-legacy.md
---
title: svelte/legacy
---
This module provides various functions for use during the migration, since some
features can't be replaced one to one with new features. All imports are marked as
deprecated and should be migrated away from over time.
```js
// @noErrors
import {
asClassComponent,
createBubbler,
createClassComponent,
handlers,
nonpassive,
once,
passive,
preventDefault,
run,
self,
stopImmediatePropagation,
stopPropagation,
trusted
} from 'svelte/legacy';
```
## asClassComponent
Use this only as a temporary solution to migrate your imperative component code to
Svelte 5.
</blockquote>
<div class="ts-block">
```dts
function asClassComponent<
Props extends Record<string, any>,
Exports extends Record<string, any>,
Events extends Record<string, any>,
Slots extends Record<string, any>
>(
component:
| SvelteComponent<Props, Events, Slots>
| Component<Props>
): ComponentType<
SvelteComponent<Props, Events, Slots> & Exports
>;
```
</div>
## createBubbler
</blockquote>
<div class="ts-block">
```dts
function createBubbler(): (
type: string
) => (event: Event) => boolean;
```
</div>
## createClassComponent
Use this only as a temporary solution to migrate your imperative component code to
Svelte 5.
</blockquote>
Takes the same options as a Svelte 4 component and the component function and
returns a Svelte 4 compatible component.
<div class="ts-block">
```dts
function createClassComponent<
Props extends Record<string, any>,
Exports extends Record<string, any>,
Events extends Record<string, any>,
Slots extends Record<string, any>
>(
options: ComponentConstructorOptions<Props> & {
component:
| ComponentType<SvelteComponent<Props, Events, Slots>>
| Component<Props>;
}
): SvelteComponent<Props, Events, Slots> & Exports;
```
</div>
## handlers
Function to mimic the multiple listeners available in svelte 4
<div class="ts-block">
```dts
function handlers(
...handlers: EventListener[]
): EventListener;
```
</div>
## nonpassive
<div class="ts-block">
```dts
function nonpassive(
node: HTMLElement,
[event, handler]: [
event: string,
handler: () => EventListener
]
): void;
```
</div>
## once
<div class="ts-block">
```dts
function once(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## passive
<div class="ts-block">
```dts
function passive(
node: HTMLElement,
[event, handler]: [
event: string,
handler: () => EventListener
]
): void;
```
</div>
## preventDefault
<div class="ts-block">
```dts
function preventDefault(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## run
Use this only as a temporary solution to migrate your component code to Svelte 5.
</blockquote>
Runs the given function once immediately on the server, and works like
`$effect.pre` on the client.
<div class="ts-block">
```dts
function run(fn: () => void | (() => void)): void;
```
</div>
## self
<div class="ts-block">
```dts
function self(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## stopImmediatePropagation
<div class="ts-block">
```dts
function stopImmediatePropagation(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## stopPropagation
<div class="ts-block">
```dts
function stopPropagation(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## trusted
<div class="ts-block">
```dts
function trusted(
fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```
</div>
## LegacyComponentType
Support using the component as both a class and function during the transition
period
<div class="ts-block">
```dts
type LegacyComponentType = {
new (o: ComponentConstructorOptions): SvelteComponent;
(
...args: Parameters<Component<Record<string, any>>>
): ReturnType<
Component<Record<string, any>, Record<string, any>>
>;
};
```
</div>
## docs/svelte/98-reference/21-svelte-motion.md
---
title: svelte/motion
---
```js
// @noErrors
import {
Spring,
Tween,
prefersReducedMotion,
spring,
tweened
} from 'svelte/motion';
```
## Spring
</blockquote>
```svelte
<script>
import { Spring } from 'svelte/motion';
<div class="ts-block">
```dts
class Spring<T> {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(value: T, options?: SpringOpts);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
static of<U>(fn: () => U, options?: SpringOpts): Spring<U>;
```
<div class="ts-block-property-details">
Create a spring whose value is bound to the return value of `fn`. This must be
called
inside an effect root (for example, during component initialisation).
```svelte
<script>
import { Spring } from 'svelte/motion';
</div>
</div>
<div class="ts-block-property">
```dts
set(value: T, options?: SpringUpdateOpts): Promise<void>;
```
<div class="ts-block-property-details">
Sets `spring.target` to `value` and returns a `Promise` that resolves if and when
`spring.current` catches up to it.
</div>
</div>
<div class="ts-block-property">
```dts
damping: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
precision: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
stiffness: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
target: T;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
get current(): T;
```
<div class="ts-block-property-details">
</div>
</div></div>
## Tween
</blockquote>
A wrapper for a value that tweens smoothly to its target value. Changes to
`tween.target` will cause `tween.current` to
move towards it over time, taking account of the `delay`, `duration` and `easing`
options.
```svelte
<script>
import { Tween } from 'svelte/motion';
<div class="ts-block">
```dts
class Tween<T> {/*…*/}
```
<div class="ts-block-property">
```dts
static of<U>(fn: () => U, options?: TweenedOptions<U> | undefined): Tween<U>;
```
<div class="ts-block-property-details">
Create a tween whose value is bound to the return value of `fn`. This must be
called
inside an effect root (for example, during component initialisation).
```svelte
<script>
import { Tween } from 'svelte/motion';
</div>
</div>
<div class="ts-block-property">
```dts
constructor(value: T, options?: TweenedOptions<T>);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
set(value: T, options?: TweenedOptions<T> | undefined): Promise<void>;
```
<div class="ts-block-property-details">
Sets `tween.target` to `value` and returns a `Promise` that resolves if and when
`tween.current` catches up to it.
</div>
</div>
<div class="ts-block-property">
```dts
get current(): T;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
set target(v: T);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
get target(): T;
```
<div class="ts-block-property-details"></div>
</div></div>
## prefersReducedMotion
</blockquote>
```svelte
<script>
import { prefersReducedMotion } from 'svelte/motion';
import { fly } from 'svelte/transition';
{#if visible}
<p transition:fly={{ y: prefersReducedMotion.current ? 0 : 200 }}>
flies in, unless the user prefers reduced motion
</p>
{/if}
```
<div class="ts-block">
```dts
const prefersReducedMotion: MediaQuery;
```
</div>
## spring
</blockquote>
The spring function in Svelte creates a store whose value is animated, with a
motion that simulates the behavior of a spring. This means when the value changes,
instead of transitioning at a steady rate, it "bounces" like a spring would,
depending on the physics parameters provided. This adds a level of realism to the
transitions and can enhance the user experience.
<div class="ts-block">
```dts
function spring<T = any>(
value?: T | undefined,
opts?: SpringOpts | undefined
): Spring<T>;
```
</div>
## tweened
</blockquote>
<div class="ts-block">
```dts
function tweened<T>(
value?: T | undefined,
defaults?: TweenedOptions<T> | undefined
): Tweened<T>;
```
</div>
## Spring
<div class="ts-block">
```dts
interface Spring<T> extends Readable<T> {/*…*/}
```
<div class="ts-block-property">
```dts
set(new_value: T, opts?: SpringUpdateOpts): Promise<void>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
update: (fn: Updater<T>, opts?: SpringUpdateOpts) => Promise<void>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
subscribe(fn: (value: T) => void): Unsubscriber;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
precision: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
damping: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
stiffness: number;
```
<div class="ts-block-property-details"></div>
</div></div>
## Tweened
<div class="ts-block">
```dts
interface Tweened<T> extends Readable<T> {/*…*/}
```
<div class="ts-block-property">
```dts
set(value: T, opts?: TweenedOptions<T>): Promise<void>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
update(updater: Updater<T>, opts?: TweenedOptions<T>): Promise<void>;
```
<div class="ts-block-property-details"></div>
</div></div>
## docs/svelte/98-reference/21-svelte-reactivity-window.md
---
title: svelte/reactivity/window
---
This module exports reactive versions of various `window` values, each of which has
a reactive `current` property that you can reference in reactive contexts
(templates, [deriveds]($derived) and [effects]($effect)) without using
[`<svelte:window>`](svelte-window) bindings or manually creating your own event
listeners.
```svelte
<script>
import { innerWidth, innerHeight } from 'svelte/reactivity/window';
</script>
<p>{innerWidth.current}x{innerHeight.current}</p>
```
```js
// @noErrors
import {
devicePixelRatio,
innerHeight,
innerWidth,
online,
outerHeight,
outerWidth,
screenLeft,
screenTop,
scrollX,
scrollY
} from 'svelte/reactivity/window';
```
## devicePixelRatio
</blockquote>
`devicePixelRatio.current` is a reactive view of `window.devicePixelRatio`. On the
server it is `undefined`.
Note that behaviour differs between browsers — on Chrome it will respond to the
current zoom level,
on Firefox and Safari it won't.
<div class="ts-block">
```dts
const devicePixelRatio: {
get current(): number | undefined;
};
```
</div>
## innerHeight
</blockquote>
<div class="ts-block">
```dts
const innerHeight: ReactiveValue<number | undefined>;
```
</div>
## innerWidth
</blockquote>
<div class="ts-block">
```dts
const innerWidth: ReactiveValue<number | undefined>;
```
</div>
## online
</blockquote>
<div class="ts-block">
```dts
const online: ReactiveValue<boolean | undefined>;
```
</div>
## outerHeight
</blockquote>
<div class="ts-block">
```dts
const outerHeight: ReactiveValue<number | undefined>;
```
</div>
## outerWidth
</blockquote>
<div class="ts-block">
```dts
const outerWidth: ReactiveValue<number | undefined>;
```
</div>
## screenLeft
</blockquote>
<div class="ts-block">
```dts
const screenLeft: ReactiveValue<number | undefined>;
```
</div>
## screenTop
</blockquote>
<div class="ts-block">
```dts
const screenTop: ReactiveValue<number | undefined>;
```
</div>
## scrollX
</blockquote>
```dts
const scrollX: ReactiveValue<number | undefined>;
```
</div>
## scrollY
</blockquote>
<div class="ts-block">
```dts
const scrollY: ReactiveValue<number | undefined>;
```
</div>
## docs/svelte/98-reference/21-svelte-reactivity.md
---
title: svelte/reactivity
---
```svelte
<script>
import { SvelteURL } from 'svelte/reactivity';
<hr />
## MediaQuery
</blockquote>
Creates a media query and provides a `current` property that reflects whether or
not it matches.
Use it carefully — during server-side rendering, there is no way to know what the
correct value should be, potentially causing content to change upon hydration.
If you can use the media query in CSS to achieve the same effect, do that.
```svelte
<script>
import { MediaQuery } from 'svelte/reactivity';
<div class="ts-block">
```dts
class MediaQuery extends ReactiveValue<boolean> {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(query: string, fallback?: boolean | undefined);
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
## SvelteDate
<div class="ts-block">
```dts
class SvelteDate extends Date {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(...params: any[]);
```
<div class="ts-block-property-details"></div>
</div></div>
## SvelteMap
<div class="ts-block">
```dts
class SvelteMap<K, V> extends Map<K, V> {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(value?: Iterable<readonly [K, V]> | null | undefined);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
set(key: K, value: V): this;
```
<div class="ts-block-property-details"></div>
</div></div>
## SvelteSet
<div class="ts-block">
```dts
class SvelteSet<T> extends Set<T> {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(value?: Iterable<T> | null | undefined);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
add(value: T): this;
```
<div class="ts-block-property-details"></div>
</div></div>
## SvelteURL
<div class="ts-block">
```dts
class SvelteURL extends URL {/*…*/}
```
<div class="ts-block-property">
```dts
get searchParams(): SvelteURLSearchParams;
```
<div class="ts-block-property-details"></div>
</div></div>
## SvelteURLSearchParams
<div class="ts-block">
```dts
class SvelteURLSearchParams extends URLSearchParams {/*…*/}
```
<div class="ts-block-property">
```dts
[REPLACE](params: URLSearchParams): void;
```
<div class="ts-block-property-details"></div>
</div></div>
## createSubscriber
</blockquote>
```js
// @errors: 7031
import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';
constructor(query) {
this.#query = window.matchMedia(`(${query})`);
get current() {
this.#subscribe();
<div class="ts-block">
```dts
function createSubscriber(
start: (update: () => void) => (() => void) | void
): () => void;
```
</div>
## docs/svelte/98-reference/21-svelte-server.md
---
title: svelte/server
---
```js
// @noErrors
import { render } from 'svelte/server';
```
## render
Only available on the server and when compiling with the `server` option.
Takes a component and returns an object with `body` and `head` properties on it,
which you can use to populate the HTML when server-rendering your app.
<div class="ts-block">
```dts
function render<
Comp extends SvelteComponent<any> | Component<any>,
Props extends ComponentProps<Comp> = ComponentProps<Comp>
>(
...args: {} extends Props
? [
component: Comp extends SvelteComponent<any>
? ComponentType<Comp>
: Comp,
options?: {
props?: Omit<Props, '$$slots' | '$$events'>;
context?: Map<any, any>;
idPrefix?: string;
}
]
: [
component: Comp extends SvelteComponent<any>
? ComponentType<Comp>
: Comp,
options: {
props: Omit<Props, '$$slots' | '$$events'>;
context?: Map<any, any>;
idPrefix?: string;
}
]
): RenderOutput;
```
</div>
## docs/svelte/98-reference/21-svelte-store.md
---
title: svelte/store
---
```js
// @noErrors
import {
derived,
fromStore,
get,
readable,
readonly,
toStore,
writable
} from 'svelte/store';
```
## derived
<div class="ts-block">
```dts
function derived<S extends Stores, T>(
stores: S,
fn: (
values: StoresValues<S>,
set: (value: T) => void,
update: (fn: Updater<T>) => void
) => Unsubscriber | void,
initial_value?: T | undefined
): Readable<T>;
```
</div>
<div class="ts-block">
```dts
function derived<S extends Stores, T>(
stores: S,
fn: (values: StoresValues<S>) => T,
initial_value?: T | undefined
): Readable<T>;
```
</div>
## fromStore
<div class="ts-block">
```dts
function fromStore<V>(store: Writable<V>): {
current: V;
};
```
</div>
<div class="ts-block">
```dts
function fromStore<V>(store: Readable<V>): {
readonly current: V;
};
```
</div>
## get
Get the current value from a store by subscribing and immediately unsubscribing.
<div class="ts-block">
```dts
function get<T>(store: Readable<T>): T;
```
</div>
## readable
<div class="ts-block">
```dts
function readable<T>(
value?: T | undefined,
start?: StartStopNotifier<T> | undefined
): Readable<T>;
```
</div>
## readonly
Takes a store and returns a new one derived from the old one that is readable.
<div class="ts-block">
```dts
function readonly<T>(store: Readable<T>): Readable<T>;
```
</div>
## toStore
<div class="ts-block">
```dts
function toStore<V>(
get: () => V,
set: (v: V) => void
): Writable<V>;
```
</div>
<div class="ts-block">
```dts
function toStore<V>(get: () => V): Readable<V>;
```
</div>
## writable
Create a `Writable` store that allows both updating and reading by subscription.
<div class="ts-block">
```dts
function writable<T>(
value?: T | undefined,
start?: StartStopNotifier<T> | undefined
): Writable<T>;
```
</div>
## Readable
<div class="ts-block">
```dts
interface Readable<T> {/*…*/}
```
<div class="ts-block-property">
```dts
subscribe(this: void, run: Subscriber<T>, invalidate?: () => void): Unsubscriber;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
## StartStopNotifier
<div class="ts-block">
```dts
type StartStopNotifier<T> = (
set: (value: T) => void,
update: (fn: Updater<T>) => void
) => void | (() => void);
```
</div>
## Subscriber
<div class="ts-block">
```dts
type Subscriber<T> = (value: T) => void;
```
</div>
## Unsubscriber
<div class="ts-block">
```dts
type Unsubscriber = () => void;
```
</div>
## Updater
<div class="ts-block">
```dts
type Updater<T> = (value: T) => T;
```
</div>
## Writable
<div class="ts-block">
```dts
interface Writable<T> extends Readable<T> {/*…*/}
```
<div class="ts-block-property">
```dts
set(this: void, value: T): void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `value` to set
</div>
</div>
</div>
<div class="ts-block-property">
```dts
update(this: void, updater: Updater<T>): void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `updater` callback
</div>
</div>
</div></div>
## docs/svelte/98-reference/21-svelte-transition.md
---
title: svelte/transition
---
```js
// @noErrors
import {
blur,
crossfade,
draw,
fade,
fly,
scale,
slide
} from 'svelte/transition';
```
## blur
<div class="ts-block">
```dts
function blur(
node: Element,
{
delay,
duration,
easing,
amount,
opacity
}?: BlurParams | undefined
): TransitionConfig;
```
</div>
## crossfade
<div class="ts-block">
```dts
function crossfade({
fallback,
...defaults
}: CrossfadeParams & {
fallback?: (
node: Element,
params: CrossfadeParams,
intro: boolean
) => TransitionConfig;
}): [
(
node: any,
params: CrossfadeParams & {
key: any;
}
) => () => TransitionConfig,
(
node: any,
params: CrossfadeParams & {
key: any;
}
) => () => TransitionConfig
];
```
</div>
## draw
Animates the stroke of an SVG element, like a snake in a tube. `in` transitions
begin with the path invisible and draw the path to the screen over time. `out`
transitions start in a visible state and gradually erase the path. `draw` only
works with elements that have a `getTotalLength` method, like `<path>` and
`<polyline>`.
<div class="ts-block">
```dts
function draw(
node: SVGElement & {
getTotalLength(): number;
},
{
delay,
speed,
duration,
easing
}?: DrawParams | undefined
): TransitionConfig;
```
</div>
## fade
Animates the opacity of an element from 0 to the current opacity for `in`
transitions and from the current opacity to 0 for `out` transitions.
<div class="ts-block">
```dts
function fade(
node: Element,
{ delay, duration, easing }?: FadeParams | undefined
): TransitionConfig;
```
</div>
## fly
Animates the x and y positions and the opacity of an element. `in` transitions
animate from the provided values, passed as parameters to the element's default
values. `out` transitions animate from the element's default values to the provided
values.
<div class="ts-block">
```dts
function fly(
node: Element,
{
delay,
duration,
easing,
x,
y,
opacity
}?: FlyParams | undefined
): TransitionConfig;
```
</div>
## scale
Animates the opacity and scale of an element. `in` transitions animate from the
provided values, passed as parameters, to an element's current (default) values.
`out` transitions animate from an element's default values to the provided values.
<div class="ts-block">
```dts
function scale(
node: Element,
{
delay,
duration,
easing,
start,
opacity
}?: ScaleParams | undefined
): TransitionConfig;
```
</div>
## slide
<div class="ts-block">
```dts
function slide(
node: Element,
{
delay,
duration,
easing,
axis
}?: SlideParams | undefined
): TransitionConfig;
```
</div>
## BlurParams
<div class="ts-block">
```dts
interface BlurParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
amount?: number | string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
opacity?: number;
```
<div class="ts-block-property-details"></div>
</div></div>
## CrossfadeParams
<div class="ts-block">
```dts
interface CrossfadeParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number | ((len: number) => number);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div></div>
## DrawParams
<div class="ts-block">
```dts
interface DrawParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
speed?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number | ((len: number) => number);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div></div>
## EasingFunction
<div class="ts-block">
```dts
type EasingFunction = (t: number) => number;
```
</div>
## FadeParams
<div class="ts-block">
```dts
interface FadeParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div></div>
## FlyParams
<div class="ts-block">
```dts
interface FlyParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
x?: number | string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
y?: number | string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
opacity?: number;
```
<div class="ts-block-property-details"></div>
</div></div>
## ScaleParams
<div class="ts-block">
```dts
interface ScaleParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
start?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
opacity?: number;
```
<div class="ts-block-property-details"></div>
</div></div>
## SlideParams
<div class="ts-block">
```dts
interface SlideParams {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
axis?: 'x' | 'y';
```
<div class="ts-block-property-details"></div>
</div></div>
## TransitionConfig
<div class="ts-block">
```dts
interface TransitionConfig {/*…*/}
```
<div class="ts-block-property">
```dts
delay?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
duration?: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
easing?: EasingFunction;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
css?: (t: number, u: number) => string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
tick?: (t: number, u: number) => void;
```
<div class="ts-block-property-details"></div>
</div></div>
## docs/svelte/98-reference/30-compiler-errors.md
---
### animation_duplicate
```
An element can only have one 'animate' directive
```
### animation_invalid_placement
```
An element that uses the `animate:` directive must be the only child of a keyed
`{#each ...}` block
```
### animation_missing_key
```
An element that uses the `animate:` directive must be the only child of a keyed
`{#each ...}` block. Did you forget to add a key to your each block?
```
### attribute_contenteditable_dynamic
```
'contenteditable' attribute cannot be dynamic if element uses two-way binding
```
### attribute_contenteditable_missing
```
'contenteditable' attribute is required for textContent, innerHTML and innerText
two-way bindings
```
### attribute_duplicate
```
Attributes need to be unique
```
### attribute_empty_shorthand
```
Attribute shorthand cannot be empty
```
### attribute_invalid_event_handler
```
Event attribute must be a JavaScript expression, not a string
```
### attribute_invalid_multiple
```
'multiple' attribute must be static if select uses two-way binding
```
### attribute_invalid_name
```
'%name%' is not a valid attribute name
```
### attribute_invalid_sequence_expression
```
Sequence expressions are not allowed as attribute/directive values in runes mode,
unless wrapped in parentheses
```
### attribute_invalid_type
```
'type' attribute must be a static text value if input uses two-way binding
```
### attribute_unquoted_sequence
```
Attribute values containing `{...}` must be enclosed in quote marks, unless the
value only contains the expression
```
### bind_group_invalid_expression
```
`bind:group` can only bind to an Identifier or MemberExpression
```
### bind_group_invalid_snippet_parameter
```
Cannot `bind:group` to a snippet parameter
```
### bind_invalid_expression
```
Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
```
### bind_invalid_name
```
`bind:%name%` is not a valid binding
```
```
`bind:%name%` is not a valid binding. %explanation%
```
### bind_invalid_parens
```
`bind:%name%={get, set}` must not have surrounding parentheses
```
### bind_invalid_target
```
`bind:%name%` can only be used with %elements%
```
### bind_invalid_value
```
Can only bind to state or props
```
### bindable_invalid_location
```
`$bindable()` can only be used inside a `$props()` declaration
```
### block_duplicate_clause
```
%name% cannot appear more than once within a block
```
### block_invalid_continuation_placement
```
{:...} block is invalid at this position (did you forget to close the preceding
element or block?)
```
### block_invalid_elseif
```
'elseif' should be 'else if'
```
### block_invalid_placement
```
{#%name% ...} block cannot be %location%
```
### block_unclosed
```
Block was left open
```
### block_unexpected_character
```
Expected a `%character%` character immediately following the opening bracket
```
### block_unexpected_close
```
Unexpected block closing tag
```
### component_invalid_directive
```
This type of directive is not valid on components
```
### const_tag_cycle
```
Cyclical dependency detected: %cycle%
```
### const_tag_invalid_expression
```
{@const ...} must consist of a single variable declaration
```
### const_tag_invalid_placement
```
`{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`,
`{:else}`, `{#each}`, `{:then}`, `{:catch}`, `<svelte:fragment>`,
`<svelte:boundary` or `<Component>`
```
### constant_assignment
```
Cannot assign to %thing%
```
### constant_binding
```
Cannot bind to %thing%
```
### css_empty_declaration
```
Declaration cannot be empty
```
### css_expected_identifier
```
Expected a valid CSS identifier
```
### css_global_block_invalid_combinator
```
A `:global` selector cannot follow a `%name%` combinator
```
### css_global_block_invalid_declaration
```
A top-level `:global {...}` block can only contain rules, not declarations
```
### css_global_block_invalid_list
```
A `:global` selector cannot be part of a selector list with more than one item
```
### css_global_block_invalid_modifier
```
A `:global` selector cannot modify an existing selector
```
### css_global_block_invalid_modifier_start
```
A `:global` selector can only be modified if it is a descendant of other selectors
```
### css_global_invalid_placement
```
`:global(...)` can be at the start or end of a selector sequence, but not in the
middle
```
### css_global_invalid_selector
```
`:global(...)` must contain exactly one selector
```
### css_global_invalid_selector_list
```
`:global(...)` must not contain type or universal selectors when used in a compound
selector
```
### css_nesting_selector_invalid_placement
```
Nesting selectors can only be used inside a rule or as the first selector inside a
lone `:global(...)`
```
### css_selector_invalid
```
Invalid selector
```
### css_type_selector_invalid_placement
```
`:global(...)` must not be followed by a type selector
```
### debug_tag_invalid_arguments
```
{@debug ...} arguments must be identifiers, not arbitrary expressions
```
### declaration_duplicate
```
`%name%` has already been declared
```
### declaration_duplicate_module_import
```
Cannot declare a variable with the same name as an import inside `<script module>`
```
### derived_invalid_export
```
Cannot export derived state from a module. To expose the current derived value,
export a function returning its value
```
### directive_invalid_value
```
Directive value must be a JavaScript expression enclosed in curly braces
```
### directive_missing_name
```
`%type%` name cannot be empty
```
### dollar_binding_invalid
```
The $ name is reserved, and cannot be used for variables and imports
```
### dollar_prefix_invalid
```
The $ prefix is reserved, and cannot be used for variables and imports
```
### each_item_invalid_assignment
```
Cannot reassign or bind to each block argument in runes mode. Use the array and
index variables instead (e.g. `array[i] = value` instead of `entry = value`, or
`bind:value={array[i]}` instead of `bind:value={entry}`)
```
In legacy mode, it was possible to reassign or bind to the each block argument
itself:
```svelte
<script>
let array = [1, 2, 3];
</script>
This turned out to be buggy and unpredictable, particularly when working with
derived values (such as `array.map(...)`), and as such is forbidden in runes mode.
You can achieve the same outcome by using the index instead:
```svelte
<script>
let array = $state([1, 2, 3]);
</script>
### effect_invalid_placement
```
`$effect()` can only be used as an expression statement
```
### element_invalid_closing_tag
```
`</%name%>` attempted to close an element that was not open
```
### element_invalid_closing_tag_autoclosed
```
`</%name%>` attempted to close element that was already automatically closed by `<
%reason%>` (cannot nest `<%reason%>` inside `<%name%>`)
```
### element_unclosed
```
`<%name%>` was left open
```
### event_handler_invalid_component_modifier
```
Event modifiers other than 'once' can only be used on DOM elements
```
### event_handler_invalid_modifier
```
Valid event modifiers are %list%
```
### event_handler_invalid_modifier_combination
```
The '%modifier1%' and '%modifier2%' modifiers cannot be used together
```
### expected_attribute_value
```
Expected attribute value
```
### expected_block_type
```
Expected 'if', 'each', 'await', 'key' or 'snippet'
```
### expected_identifier
```
Expected an identifier
```
### expected_pattern
```
Expected identifier or destructure pattern
```
### expected_token
```
Expected token %token%
```
### expected_whitespace
```
Expected whitespace
```
### export_undefined
```
`%name%` is not defined
```
### global_reference_invalid
```
`%name%` is an illegal variable name. To reference a global variable called `%name
%`, use `globalThis.%name%`
```
### host_invalid_placement
```
`$host()` can only be used inside custom element component instances
```
### illegal_element_attribute
```
`<%name%>` does not support non-event attributes or spread attributes
```
### import_svelte_internal_forbidden
```
Imports of `svelte/internal/*` are forbidden. It contains private runtime code
which is subject to change without notice. If you're importing from
`svelte/internal/*` to work around a limitation of Svelte, please open an issue at
https://github.com/sveltejs/svelte and explain your use case
```
### inspect_trace_generator
```
`$inspect.trace(...)` cannot be used inside a generator function
```
### inspect_trace_invalid_placement
```
`$inspect.trace(...)` must be the first statement of a function body
```
### invalid_arguments_usage
```
The arguments keyword cannot be used within the template or at the top level of a
component
```
### js_parse_error
```
%message%
```
### legacy_export_invalid
```
Cannot use `export let` in runes mode — use `$props()` instead
```
### legacy_props_invalid
```
Cannot use `$$props` in runes mode
```
### legacy_reactive_statement_invalid
```
`$:` is not allowed in runes mode, use `$derived` or `$effect` instead
```
### legacy_rest_props_invalid
```
Cannot use `$$restProps` in runes mode
```
### let_directive_invalid_placement
```
`let:` directive at invalid position
```
### mixed_event_handler_syntaxes
```
Mixing old (on:%name%) and new syntaxes for event handling is not allowed. Use only
the on%name% syntax
```
### module_illegal_default_export
```
A component cannot have a default export
```
### node_invalid_placement
```
%message%. The browser will 'repair' the HTML (by moving, removing, or inserting
elements) which breaks Svelte's assumptions about the structure of your components.
```
HTML restricts where certain elements can appear. In case of a violation the
browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the
structure of your components. Some examples:
### options_invalid_value
```
Invalid compiler option: %details%
```
### options_removed
```
Invalid compiler option: %details%
```
### options_unrecognised
```
Unrecognised compiler option %keypath%
```
### props_duplicate
```
Cannot use `%rune%()` more than once
```
### props_id_invalid_placement
```
`$props.id()` can only be used at the top level of components as a variable
declaration initializer
```
### props_illegal_name
```
Declaring or accessing a prop starting with `$$` is illegal (they are reserved for
Svelte internals)
```
### props_invalid_identifier
```
`$props()` can only be used with an object destructuring pattern
```
### props_invalid_pattern
```
`$props()` assignment must not contain nested properties or computed keys
```
### props_invalid_placement
```
`$props()` can only be used at the top level of components as a variable
declaration initializer
```
### reactive_declaration_cycle
```
Cyclical dependency detected: %cycle%
```
### render_tag_invalid_call_expression
```
Calling a snippet function using apply, bind or call is not allowed
```
### render_tag_invalid_expression
```
`{@render ...}` tags can only contain call expressions
```
### render_tag_invalid_spread_argument
```
cannot use spread arguments in `{@render ...}` tags
```
### rune_invalid_arguments
```
`%rune%` cannot be called with arguments
```
### rune_invalid_arguments_length
```
`%rune%` must be called with %args%
```
### rune_invalid_computed_property
```
Cannot access a computed property of a rune
```
### rune_invalid_name
```
`%name%` is not a valid rune
```
### rune_invalid_spread
```
`%rune%` cannot be called with a spread argument
```
### rune_invalid_usage
```
Cannot use `%rune%` rune in non-runes mode
```
### rune_missing_parentheses
```
Cannot use rune without parentheses
```
### rune_removed
```
The `%name%` rune has been removed
```
### rune_renamed
```
`%name%` is now `%replacement%`
```
### runes_mode_invalid_import
```
%name% cannot be used in runes mode
```
### script_duplicate
```
A component can have a single top-level `<script>` element and/or a single top-
level `<script module>` element
```
### script_invalid_attribute_value
```
If the `%name%` attribute is supplied, it must be a boolean attribute
```
### script_invalid_context
```
If the context attribute is supplied, its value must be "module"
```
### script_reserved_attribute
```
The `%name%` attribute is reserved and cannot be used
```
### slot_attribute_duplicate
```
Duplicate slot name '%name%' in <%component%>
```
### slot_attribute_invalid
```
slot attribute must be a static value
```
### slot_attribute_invalid_placement
```
Element with a slot='...' attribute must be a child of a component or a descendant
of a custom element
```
### slot_default_duplicate
```
Found default slot content alongside an explicit slot="default"
```
### slot_element_invalid_attribute
```
`<slot>` can only receive attributes and (optionally) let directives
```
### slot_element_invalid_name
```
slot attribute must be a static value
```
### slot_element_invalid_name_default
```
`default` is a reserved word — it cannot be used as a slot name
```
### slot_snippet_conflict
```
Cannot use `<slot>` syntax and `{@render ...}` tags in the same component. Migrate
towards `{@render ...}` tags completely
```
### snippet_conflict
```
Cannot use explicit children snippet at the same time as implicit children content.
Remove either the non-whitespace content or the children snippet block
```
### snippet_invalid_export
```
An exported snippet can only reference things declared in a `<script module>`, or
other exportable snippets
```
It's possible to export a snippet from a `<script module>` block, but only if it
doesn't reference anything defined inside a non-module-level `<script>`. For
example you can't do this...
```svelte
<script module>
export { greeting };
</script>
<script>
let message = 'hello';
</script>
{#snippet greeting(name)}
<p>{message} {name}!</p>
{/snippet}
```
### snippet_invalid_rest_parameter
```
Snippets do not support rest parameters; use an array instead
```
### snippet_parameter_assignment
```
Cannot reassign or bind to snippet parameter
```
### snippet_shadowing_prop
```
This snippet is shadowing the prop `%prop%` with the same name
```
### state_invalid_export
```
Cannot export state from a module if it is reassigned. Either export a function
returning the state value or only mutate the state value's properties
```
### state_invalid_placement
```
`%rune%(...)` can only be used as a variable declaration initializer or a class
field
```
### store_invalid_scoped_subscription
```
Cannot subscribe to stores that are not declared at the top level of the component
```
### store_invalid_subscription
```
Cannot reference store value inside `<script module>`
```
### store_invalid_subscription_module
```
Cannot reference store value outside a `.svelte` file
```
Using a `$` prefix to refer to the value of a store is only possible inside
`.svelte` files, where Svelte can automatically create subscriptions when a
component is mounted and unsubscribe when the component is unmounted. Consider
migrating to runes instead.
### style_directive_invalid_modifier
```
`style:` directive can only use the `important` modifier
```
### style_duplicate
```
A component can have a single top-level `<style>` element
```
### svelte_body_illegal_attribute
```
`<svelte:body>` does not support non-event attributes or spread attributes
```
### svelte_boundary_invalid_attribute
```
Valid attributes on `<svelte:boundary>` are `onerror` and `failed`
```
### svelte_boundary_invalid_attribute_value
```
Attribute value must be a non-string expression
```
### svelte_component_invalid_this
```
Invalid component definition — must be an `{expression}`
```
### svelte_component_missing_this
```
`<svelte:component>` must have a 'this' attribute
```
### svelte_element_missing_this
```
`<svelte:element>` must have a 'this' attribute with a value
```
### svelte_fragment_invalid_attribute
```
`<svelte:fragment>` can only have a slot attribute and (optionally) a let:
directive
```
### svelte_fragment_invalid_placement
```
`<svelte:fragment>` must be the direct child of a component
```
### svelte_head_illegal_attribute
```
`<svelte:head>` cannot have attributes nor directives
```
### svelte_meta_duplicate
```
A component can only have one `<%name%>` element
```
### svelte_meta_invalid_content
```
<%name%> cannot have children
```
### svelte_meta_invalid_placement
```
`<%name%>` tags cannot be inside elements or blocks
```
### svelte_meta_invalid_tag
```
Valid `<svelte:...>` tag names are %list%
```
### svelte_options_deprecated_tag
```
"tag" option is deprecated — use "customElement" instead
```
### svelte_options_invalid_attribute
```
`<svelte:options>` can only receive static attributes
```
### svelte_options_invalid_attribute_value
```
Value must be %list%, if specified
```
### svelte_options_invalid_customelement
```
"customElement" must be a string literal defining a valid custom element name or an
object of the form { tag?: string; shadow?: "open" | "none"; props?: { [key:
string]: { attribute?: string; reflect?: boolean; type: .. } } }
```
### svelte_options_invalid_customelement_props
```
"props" must be a statically analyzable object literal of the form "{ [key:
string]: { attribute?: string; reflect?: boolean; type?: "String" | "Boolean" |
"Number" | "Array" | "Object" }"
```
### svelte_options_invalid_customelement_shadow
```
"shadow" must be either "open" or "none"
```
### svelte_options_invalid_tagname
```
Tag name must be lowercase and hyphenated
```
See https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-
element-name for more information on valid tag names
### svelte_options_reserved_tagname
```
Tag name is reserved
```
See https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-
element-name for more information on valid tag names
### svelte_options_unknown_attribute
```
`<svelte:options>` unknown attribute '%name%'
```
### svelte_self_invalid_placement
```
`<svelte:self>` components can only exist inside `{#if}` blocks, `{#each}` blocks,
`{#snippet}` blocks or slots passed to components
```
### tag_invalid_name
```
Expected a valid element or component name. Components must have a valid variable
name or dot notation expression
```
### tag_invalid_placement
```
{@%name% ...} tag cannot be %location%
```
### textarea_invalid_content
```
A `<textarea>` can have either a value attribute or (equivalently) child content,
but not both
```
### title_illegal_attribute
```
`<title>` cannot have attributes nor directives
```
### title_invalid_content
```
`<title>` can only contain text and {tags}
```
### transition_conflict
```
Cannot use `%type%:` alongside existing `%existing%:` directive
```
### transition_duplicate
```
Cannot use multiple `%type%:` directives on a single element
```
### typescript_invalid_feature
```
TypeScript language features like %feature% are not natively supported, and their
use is generally discouraged. Outside of `<script>` tags, these features are not
supported. For use within `<script>` tags, you will need to use a preprocessor to
convert it to JavaScript before it gets passed to the Svelte compiler. If you are
using `vitePreprocess`, make sure to specifically enable preprocessing script tags
(`vitePreprocess({ script: true })`)
```
### unexpected_eof
```
Unexpected end of input
```
### unexpected_reserved_word
```
'%word%' is a reserved word in JavaScript and cannot be used here
```
### unterminated_string_constant
```
Unterminated string constant
```
### void_element_invalid_content
```
Void elements cannot have children or closing tags
```
## docs/svelte/98-reference/30-compiler-warnings.md
---
Svelte warns you at compile time if it catches potential mistakes, such as writing
inaccessible markup.
Some warnings may be incorrect in your concrete use case. You can disable such
false positives by placing a `<!-- svelte-ignore <code> -->` comment above the line
that causes the warning. Example:
```svelte
<!-- svelte-ignore a11y_autofocus -->
<input autofocus />
```
You can list multiple rules in a single comment (separated by commas), and add an
explanatory note (in parentheses) alongside them:
```svelte
<!-- svelte-ignore a11y_click_events_have_key_events,
a11y_no_static_element_interactions (because of reasons) -->
<div onclick>...</div>
```
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
### a11y_accesskey
```
Avoid using accesskey
```
Enforce no `accesskey` on element. Access keys are HTML attributes that allow web
developers to assign keyboard shortcuts to elements. Inconsistencies between
keyboard shortcuts and keyboard commands used by screen reader and keyboard-only
users create accessibility complications. To avoid complications, access keys
should not be used.
```svelte
<!-- A11y: Avoid using accesskey -->
<div accesskey="z"></div>
```
### a11y_aria_activedescendant_has_tabindex
```
An element with an aria-activedescendant attribute should have a tabindex value
```
```svelte
<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value
-->
<div aria-activedescendant="some-id"></div>
```
### a11y_aria_attributes
```
`<%name%>` should not have aria-* attributes
```
Certain reserved DOM elements do not support ARIA roles, states and properties.
This is often because they are not visible, for example `meta`, `html`, `script`,
`style`. This rule enforces that these DOM elements do not contain the `aria-*`
props.
```svelte
<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false" />
```
### a11y_autocomplete_valid
```
'%value%' is an invalid value for 'autocomplete' on `<input type="%type%">`
```
### a11y_autofocus
```
Avoid using autofocus
```
Enforce that `autofocus` is not used on elements. Autofocusing elements can cause
usability issues for sighted and non-sighted users alike.
```svelte
<!-- A11y: Avoid using autofocus -->
<input autofocus />
```
### a11y_click_events_have_key_events
```
Visible, non-interactive elements with a click event must be accompanied by a
keyboard event handler. Consider whether an interactive element such as `<button
type="button">` or `<a>` might be more appropriate
```
```svelte
<!-- A11y: visible, non-interactive elements with an onclick event must be
accompanied by a keyboard event handler. -->
<div onclick={() => {}}></div>
```
Coding for the keyboard is important for users with physical disabilities who
cannot use a mouse, AT compatibility, and screenreader users.
### a11y_consider_explicit_label
```
Buttons and links should either contain text or have an `aria-label` or `aria-
labelledby` attribute
```
### a11y_distracting_elements
```
Avoid `<%name%>` elements
```
Enforces that no distracting elements are used. Elements that can be visually
distracting can cause accessibility issues with visually impaired users. Such
elements are most likely deprecated, and should be avoided.
```svelte
<!-- A11y: Avoid <marquee> elements -->
<marquee></marquee>
```
### a11y_figcaption_index
```
`<figcaption>` must be first or last child of `<figure>`
```
### a11y_figcaption_parent
```
`<figcaption>` must be an immediate child of `<figure>`
```
```svelte
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
<figcaption>Image caption</figcaption>
</div>
```
### a11y_hidden
```
`<%name%>` element should not be hidden
```
Certain DOM elements are useful for screen reader navigation and should not be
hidden.
```svelte
<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>
```
### a11y_img_redundant_alt
```
Screenreaders already announce `<img>` elements as an image
```
Enforce img alt attribute does not contain the word image, picture, or photo.
Screen readers already announce `img` elements as an image. There is no need to use
words such as _image_, _photo_, and/or _picture_.
```svelte
<img src="foo" alt="Foo eating a sandwich." />
<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />
```
### a11y_incorrect_aria_attribute_type
```
The value of '%attribute%' must be a %type%
```
Enforce that only the correct type of value is used for aria attributes. For
example, `aria-hidden`
should only receive a boolean.
```svelte
<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
<div aria-hidden="yes"></div>
```
### a11y_incorrect_aria_attribute_type_boolean
```
The value of '%attribute%' must be either 'true' or 'false'. It cannot be empty
```
### a11y_incorrect_aria_attribute_type_id
```
The value of '%attribute%' must be a string that represents a DOM element ID
```
### a11y_incorrect_aria_attribute_type_idlist
```
The value of '%attribute%' must be a space-separated list of strings that represent
DOM element IDs
```
### a11y_incorrect_aria_attribute_type_integer
```
The value of '%attribute%' must be an integer
```
### a11y_incorrect_aria_attribute_type_token
```
The value of '%attribute%' must be exactly one of %values%
```
### a11y_incorrect_aria_attribute_type_tokenlist
```
The value of '%attribute%' must be a space-separated list of one or more of %values
%
```
### a11y_incorrect_aria_attribute_type_tristate
```
The value of '%attribute%' must be exactly one of true, false, or mixed
```
### a11y_interactive_supports_focus
```
Elements with the '%role%' interactive role must have a tabindex value
```
Enforce that elements with an interactive role and interactive handlers (mouse or
key press) must be focusable or tabbable.
```svelte
<!-- A11y: Elements with the 'button' interactive role must have a tabindex value.
-->
<div role="button" onkeypress={() => {}} />
```
### a11y_invalid_attribute
```
'%href_value%' is not a valid %href_attribute% attribute
```
Enforce that attributes important for accessibility have a valid value. For
example, `href` should not be empty, `'#'`, or `javascript:`.
```svelte
<!-- A11y: '' is not a valid href attribute -->
<a href="">invalid</a>
```
### a11y_label_has_associated_control
```
A form label must be associated with a control
```
Enforce that a label tag has a text label and an associated control.
```svelte
<label for="id">B</label>
### a11y_media_has_caption
```
`<video>` elements must have a `<track kind="captions">`
```
Providing captions for media is essential for deaf users to follow along. Captions
should be a transcription or translation of the dialogue, sound effects, relevant
musical cues, and other relevant audio information. Not only is this important for
accessibility, but can also be useful for all users in the case that the media is
unavailable (similar to `alt` text on an image when an image is unable to load).
The captions should contain all important and relevant information to understand
the corresponding media. This may mean that the captions are not a 1:1 mapping of
the dialogue in the media content. However, captions are not necessary for video
components with the `muted` attribute.
```svelte
<video><track kind="captions" /></video>
<audio muted></audio>
### a11y_misplaced_role
```
`<%name%>` should not have role attribute
```
Certain reserved DOM elements do not support ARIA roles, states and properties.
This is often because they are not visible, for example `meta`, `html`, `script`,
`style`. This rule enforces that these DOM elements do not contain the `role`
props.
```svelte
<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip" />
```
### a11y_misplaced_scope
```
The scope attribute should only be used with `<th>` elements
```
```svelte
<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />
```
### a11y_missing_attribute
```
`<%name%>` element should have %article% %sequence% attribute
```
Enforce that attributes required for accessibility are present on an element. This
includes the following checks:
```svelte
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-
labelledby attribute -->
<input type="image" />
### a11y_missing_content
```
`<%name%>` element should contain text
```
Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that
the content is accessible to screen readers
```svelte
<!-- A11y: <a> element should have child content -->
<a href="/foo"></a>
### a11y_mouse_events_have_key_events
```
'%event%' event must be accompanied by '%accompanied_by%' event
```
```svelte
<!-- A11y: onmouseover must be accompanied by onfocus -->
<div onmouseover={handleMouseover} />
### a11y_no_abstract_role
```
Abstract role '%role%' is forbidden
```
### a11y_no_interactive_element_to_noninteractive_role
```
`<%element%>` cannot have role '%role%'
```
```svelte
<!-- A11y: <textarea> cannot have role 'listitem' -->
<textarea role="listitem"></textarea>
```
### a11y_no_noninteractive_element_interactions
```
Non-interactive element `<%element%>` should not be assigned mouse or keyboard
event listeners
```
A non-interactive element does not support event handlers (mouse and key handlers).
Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<p>`,
`<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA
roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`,
`banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
```sv
<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard
event listeners.` -->
<li onclick={() => {}}></li>
<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard
event listeners.` -->
<div role="listitem" onclick={() => {}}></div>
```
### a11y_no_noninteractive_element_to_interactive_role
```
Non-interactive element `<%element%>` cannot have interactive role '%role%'
```
```svelte
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' --
>
<h3 role="searchbox">Button</h3>
```
### a11y_no_noninteractive_tabindex
```
noninteractive element cannot have nonnegative tabIndex value
```
Tab key navigation should be limited to elements on the page that can be interacted
with.
```svelte
<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->
<div tabindex="0"></div>
```
### a11y_no_redundant_roles
```
Redundant role '%role%'
```
Some HTML elements have default ARIA roles. Giving these elements an ARIA role that
is already set by the browser [has no
effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.
```svelte
<!-- A11y: Redundant role 'button' -->
<button role="button">...</button>
### a11y_no_static_element_interactions
```
`<%element%>` with a %handler% handler must have an ARIA role
```
Elements like `<div>` with interactive handlers like `click` must have an ARIA
role.
```svelte
<!-- A11y: <div> with click handler must have an ARIA role -->
<div onclick={() => ''}></div>
```
### a11y_positive_tabindex
```
Avoid tabindex values above zero
```
Avoid positive `tabindex` property values. This will move elements out of the
expected tab order, creating a confusing experience for keyboard users.
```svelte
<!-- A11y: avoid tabindex values above zero -->
<div tabindex="1"></div>
```
### a11y_role_has_required_aria_props
```
Elements with the ARIA role "%role%" must have the following attributes defined:
%props%
```
Elements with ARIA roles must have all required attributes for that role.
```svelte
<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following
attributes defined: "aria-checked" -->
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>
```
### a11y_role_supports_aria_props
```
The attribute '%attribute%' is not supported by the role '%role%'
```
Elements with explicit or implicit roles defined contain only `aria-*` properties
supported by that role.
```svelte
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>
<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'.
This role is implicit on the element <li>. -->
<li aria-required></li>
```
### a11y_role_supports_aria_props_implicit
```
The attribute '%attribute%' is not supported by the role '%role%'. This role is
implicit on the element `<%name%>`
```
Elements with explicit or implicit roles defined contain only `aria-*` properties
supported by that role.
```svelte
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>
<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'.
This role is implicit on the element <li>. -->
<li aria-required></li>
```
### a11y_unknown_aria_attribute
```
Unknown aria attribute 'aria-%attribute%'
```
```
Unknown aria attribute 'aria-%attribute%'. Did you mean '%suggestion%'?
```
Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA
States and Properties
spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).
```svelte
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo" />
```
### a11y_unknown_role
```
Unknown role '%role%'
```
```
Unknown role '%role%'. Did you mean '%suggestion%'?
```
Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to
role definitions can be found at
[WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.
```svelte
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>
```
### attribute_avoid_is
```
The "is" attribute is not supported cross-browser and should be avoided
```
### attribute_global_event_reference
```
You are referencing `globalThis.%name%`. Did you forget to declare a variable with
that name?
```
### attribute_illegal_colon
```
Attributes should not contain ':' characters to prevent ambiguity with Svelte
directives
```
### attribute_invalid_property_name
```
'%wrong%' is not a valid HTML attribute. Did you mean '%right%'?
```
### attribute_quoted
```
Quoted attributes on components and custom elements will be stringified in a future
version of Svelte. If this isn't what you want, remove the quotes
```
### bind_invalid_each_rest
```
The rest operator (...) will create a new object and binding '%name%' with the
original object will not work
```
### block_empty
```
Empty block
```
### component_name_lowercase
```
`<%name%>` will be treated as an HTML element unless it begins with a capital
letter
```
### css_unused_selector
```
Unused CSS selector "%name%"
```
Svelte traverses both the template and the `<style>` tag to find out which of the
CSS selectors are not used within the template, so it can remove them.
In some situations a selector may target an element that is not 'visible' to the
compiler, for example because it is part of an `{@html ...}` tag or you're
overriding styles in a child component. In these cases, use
[`:global`](/docs/svelte/global-styles) to preserve the selector as-is:
```svelte
<div class="post">{@html content}</div>
<style>
.post :global {
p {...}
}
</style>
```
### element_invalid_self_closing_tag
```
Self-closing HTML tags for non-void elements are ambiguous — use `<%name%
...></%name%>` rather than `<%name% ... />`
```
```html
<div>
<span class="icon" /> some text!
</div>
```
...a spec-compliant HTML parser (such as a browser) will in fact parse it like
this, with the text _inside_ the icon:
```html
<div>
<span class="icon"> some text! </span>
</div>
```
Some templating languages (including Svelte) will 'fix' HTML by turning `<span />`
into `<span></span>`. Others adhere to the spec. Both result in ambiguity and
confusion when copy-pasting code between different contexts, and as such Svelte
prompts you to resolve the ambiguity directly by having an explicit closing tag.
```bash
npx sv migrate self-closing-tags
```
### event_directive_deprecated
```
Using `on:%name%` to listen to the %name% event is deprecated. Use the event
attribute `on%name%` instead
```
### export_let_unused
```
Component has unused export property '%name%'. If it is for external reference
only, please consider using `export const %name%`
```
### legacy_code
```
`%code%` is no longer valid — please use `%suggestion%` instead
```
### legacy_component_creation
```
Svelte 5 components are no longer classes. Instantiate them using `mount` or
`hydrate` (imported from 'svelte') instead.
```
### node_invalid_placement_ssr
```
%message%. When rendering this component on the server, the resulting HTML will be
modified by the browser (by moving, removing, or inserting elements), likely
resulting in a `hydration_mismatch` warning
```
HTML restricts where certain elements can appear. In case of a violation the
browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the
structure of your components. Some examples:
This code will work when the component is rendered on the client (which is why this
is a warning rather than an error), but if you use server rendering it will cause
hydration to fail.
### non_reactive_update
```
`%name%` is updated, but is not declared with `$state(...)`. Changing its value
will not correctly trigger updates
```
In this case, changing the value will not correctly trigger updates. Example:
```svelte
<script>
let reactive = $state('reactive');
let stale = 'stale';
</script>
### options_deprecated_accessors
```
The `accessors` option has been deprecated. It will have no effect in runes mode
```
### options_deprecated_immutable
```
The `immutable` option has been deprecated. It will have no effect in runes mode
```
### options_missing_custom_element
```
The `customElement` option is used when generating a custom element. Did you forget
the `customElement: true` compile option?
```
### options_removed_enable_sourcemap
```
The `enableSourcemap` option has been removed. Source maps are always generated
now, and tooling can choose to ignore them
```
### options_removed_hydratable
```
The `hydratable` option has been removed. Svelte components are always hydratable
now
```
### options_removed_loop_guard_timeout
```
The `loopGuardTimeout` option has been removed
```
### options_renamed_ssr_dom
```
`generate: "dom"` and `generate: "ssr"` options have been renamed to "client" and
"server" respectively
```
### perf_avoid_inline_class
```
Avoid 'new class' — instead, declare the class at the top level scope
```
### perf_avoid_nested_class
```
Avoid declaring classes below the top level scope
```
### reactive_declaration_invalid_placement
```
Reactive declarations only exist at the top level of the instance script
```
### reactive_declaration_module_script_dependency
```
Reassignments of module-level declarations will not cause reactive statements to
update
```
### script_context_deprecated
```
`context="module"` is deprecated, use the `module` attribute instead
```
```svelte
<scriptcontext="module"module>
let foo = 'bar';
</script>
```
### script_unknown_attribute
```
Unrecognized attribute — should be one of `generics`, `lang` or `module`. If this
exists for a preprocessor, ensure that the preprocessor removes it
```
### slot_element_deprecated
```
Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags
instead
```
### state_referenced_locally
```
State referenced in its own scope will never update. Did you mean to reference it
inside a closure?
```
In this case, the state reassignment will not be noticed by whatever you passed it
to. For example, if you pass the state to a function, that function will not notice
the updates:
```svelte
<!file: Parent.svelte>
<script>
import { setContext } from 'svelte';
// warning: state_referenced_locally
setContext('count', count);
</script>
```svelte
<!file: Child.svelte>
<script>
import { getContext } from 'svelte';
To fix this, reference the variable such that it is lazily evaluated. For the above
example, this can be achieved by wrapping `count` in a function:
```svelte
<!file: Parent.svelte>
<script>
import { setContext } from 'svelte';
```svelte
<!file: Child.svelte>
<script>
import { getContext } from 'svelte';
### store_rune_conflict
```
It looks like you're using the `$%name%` rune, but there is a local binding called
`%name%`. Referencing a local variable with a `$` prefix will create a store
subscription. Please rename `%name%` to avoid the ambiguity
```
### svelte_component_deprecated
```
`<svelte:component>` is deprecated in runes mode — components are dynamic by
default
```
In previous versions of Svelte, the component constructor was fixed when the
component was rendered. In other words, if you wanted `<X>` to re-render when `X`
changed, you would either have to use `<svelte:component this={X}>` or put the
component inside a `{#key X}...{/key}` block.
```svelte
{#each items as item}
<svelte:component this={item.condition ? Y : Z} />
{@const Component = item.condition ? Y : Z}
<Component />
{/each}
```
```svelte
<script>
// ...
let condition = $state(false);
const Component = $derived(condition ? Y : Z);
</script>
<svelte:component this={condition ? Y : Z} />
<Component />
```
### svelte_element_invalid_this
```
`this` should be an `{expression}`. Using a string attribute value will cause an
error in future versions of Svelte
```
### svelte_self_deprecated
```
`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from
'./%basename%'`) instead
```
### unknown_code
```
`%code%` is not a recognised code
```
```
`%code%` is not a recognised code (did you mean `%suggestion%`?)
```
## docs/svelte/98-reference/30-runtime-errors.md
---
## Client errors
### bind_invalid_checkbox_value
```
Using `bind:value` together with a checkbox input is not allowed. Use
`bind:checked` instead
```
### bind_invalid_export
```
Component %component% has an export named `%key%` that a consumer component is
trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this`
(e.g. `<%name% bind:this={component} />`) and then access the property on the bound
component instance (e.g. `component.%key%`)
```
### bind_not_bindable
```
A component is attempting to bind to a non-bindable property `%key%` belonging to
%component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable:
`let { %key% = $bindable() } = $props()`
```
### component_api_changed
```
%parent% called `%method%` on an instance of %component%, which is no longer valid
in Svelte 5
```
### component_api_invalid_new
```
Attempted to instantiate %component% with `new %name%`, which is no longer valid in
Svelte 5. If this component is not under your control, set the
`compatibility.componentApi` compiler option to `4` to keep it working.
```
### derived_references_self
```
A derived value cannot reference itself recursively
```
### each_key_duplicate
```
Keyed each block has duplicate key at indexes %a% and %b%
```
```
Keyed each block has duplicate key `%value%` at indexes %a% and %b%
```
### effect_in_teardown
```
`%rune%` cannot be used inside an effect cleanup function
```
### effect_in_unowned_derived
```
Effect cannot be created inside a `$derived` value that was not itself created
inside an effect
```
### effect_orphan
```
`%rune%` can only be used inside an effect (e.g. during component initialisation)
```
### effect_update_depth_exceeded
```
Maximum update depth exceeded. This can happen when a reactive block or effect
repeatedly sets a new value. Svelte limits the number of nested updates to prevent
infinite loops
```
### hydration_failed
```
Failed to hydrate the application
```
### invalid_snippet
```
Could not `{@render}` snippet due to the expression being `null` or `undefined`.
Consider using optional chaining `{@render snippet?.()}`
```
### lifecycle_legacy_only
```
`%name%(...)` cannot be used in runes mode
```
### props_invalid_value
```
Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value
```
### props_rest_readonly
```
Rest element properties of `$props()` such as `%property%` are readonly
```
### rune_outside_svelte
```
The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
```
### state_descriptors_fixed
```
Property descriptors defined on `$state` objects must contain `value` and always be
`enumerable`, `configurable` and `writable`.
```
### state_prototype_fixed
```
Cannot set prototype of `$state` object
```
### state_unsafe_mutation
```
Updating state inside a derived or a template expression is forbidden. If the value
should not be reactive, declare it without `$state`
```
This error occurs when state is updated while evaluating a `$derived`. You might
encounter it while trying to 'derive' two pieces of state in one go:
```svelte
<script>
let count = $state(0);
```js
let count = 0;
//cut
let even = $derived(count % 2 === 0);
let odd = $derived(!even);
```
## Server errors
### lifecycle_function_unavailable
```
`%name%(...)` is not available on the server
```
## Shared errors
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
### invalid_default_snippet
```
Cannot use `{@render children(...)}` if the parent component uses `let:`
directives. Consider using a named snippet instead
```
```svelte
<!file: Parent.svelte>
<List {items} let:entry>
<span>{entry}</span>
</List>
```
```svelte
<!file: List.svelte>
<script>
let { items, children } = $props();
</script>
<ul>
{#each items as item}
<li>{@render children(item)}</li>
{/each}
</ul>
```
### lifecycle_outside_component
```
`%name%(...)` can only be used during component initialisation
```
Certain lifecycle methods can only be used during component initialisation. To fix
this, make sure you're invoking the method inside the _top level of the instance
script_ of your component.
```svelte
<script>
import { onMount } from 'svelte';
function handleClick() {
// This is wrong
onMount(() => {})
}
// This is correct
onMount(() => {})
</script>
<button onclick={handleClick}>click me</button>
```
### store_invalid_shape
```
`%name%` is not a store with a `subscribe` method
```
### svelte_element_invalid_this_value
```
The `this` prop on `<svelte:element>` must be a string, if defined
```
## docs/svelte/98-reference/30-runtime-warnings.md
---
## Client warnings
### assignment_value_stale
```
Assignment to `%property%` property (%location%) will evaluate to the right-hand
side, not the value of `%property%` following the assignment. This may result in
unexpected behaviour.
```
```svelte
<script>
let object = $state({ array: null });
function add() {
(object.array ??= []).push(object.array.length);
}
</script>
<button onclick={add}>add</button>
<p>items: {JSON.stringify(object.items)}</p>
```
...the array being pushed to when the button is first clicked is the `[]` on the
right-hand side of the assignment, but the resulting value of `object.array` is an
empty state proxy. As a result, the pushed value will be discarded.
```js
let object = { array: [0] };
//cut
function add() {
object.array ??= [];
object.array.push(object.array.length);
}
```
### binding_property_non_reactive
```
`%binding%` is binding to a non-reactive property
```
```
`%binding%` (%location%) is binding to a non-reactive property
```
### console_log_state
```
Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)`
or `$state.snapshot(...)` instead
```
When logging a
[proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/Proxy), browser devtools will log the proxy itself rather than the
value it represents. In the case of Svelte, the 'target' of a `$state` proxy might
not resemble its current value, which can be confusing.
The easiest way to log a value as it changes over time is to use the [`$inspect`]
(/docs/svelte/$inspect) rune. Alternatively, to log things on a one-off basis (for
example, inside an event handler) you can use
[`$state.snapshot`](/docs/svelte/$state#$state.snapshot) to take a snapshot of the
current value.
### event_handler_invalid
```
%handler% should be a function. Did you mean to %suggestion%?
```
### hydration_attribute_changed
```
The `%attribute%` attribute on `%html%` changed its value between server and client
renders. The client value, `%value%`, will be ignored in favour of the server value
```
Certain attributes like `src` on an `<img>` element will not be repaired during
hydration, i.e. the server value will be kept. That's because updating these
attributes can cause the image to be refetched (or in the case of an `<iframe>`,
for the frame to be reloaded), even if they resolve to the same resource.
```svelte
<script>
let { src } = $props();
// unset it...
src = undefined;
$effect(() => {
// ...and reset after we've mounted
src = initial;
});
}
</script>
### hydration_html_changed
```
The value of an `{@html ...}` block changed between server and client renders. The
client value will be ignored in favour of the server value
```
```
The value of an `{@html ...}` block %location% changed between server and client
renders. The client value will be ignored in favour of the server value
```
If the `{@html ...}` value changes between the server and the client, it will not
be repaired during hydration, i.e. the server value will be kept. That's because
change detection during hydration is expensive and usually unnecessary.
```svelte
<script>
let { markup } = $props();
// unset it...
markup = undefined;
$effect(() => {
// ...and reset after we've mounted
markup = initial;
});
}
</script>
{@html markup}
```
### hydration_mismatch
```
Hydration failed because the initial UI does not match what was rendered on the
server
```
```
Hydration failed because the initial UI does not match what was rendered on the
server. The error occurred near %location%
```
This warning is thrown when Svelte encounters an error while hydrating the HTML
from the server. During hydration, Svelte walks the DOM, expecting a certain
structure. If that structure is different (for example because the HTML was
repaired by the DOM because of invalid HTML), then Svelte will run into issues,
resulting in this warning.
### invalid_raw_snippet_render
```
The `render` function passed to `createRawSnippet` should return HTML for a single
element
```
### legacy_recursive_reactive_block
```
Detected a migrated `$:` reactive block in `%filename%` that both accesses and
updates the same reactive value. This may cause recursive updates when converted to
an `$effect`.
```
### lifecycle_double_unmount
```
Tried to unmount a component that was not mounted
```
### ownership_invalid_binding
```
%parent% passed a value to %child% with `bind:`, but the value is owned by %owner%.
Consider creating a binding between %owner% and %parent%
```
To fix it, `bind:` to the value instead of just passing a property (i.e. in this
example do `<Parent bind:value />`).
### ownership_invalid_mutation
```
Mutating a value outside the component that created it is strongly discouraged.
Consider passing values to child components with `bind:`, or use a callback instead
```
```
%component% mutated a value owned by %owner%. This is strongly discouraged.
Consider passing values to child components with `bind:`, or use a callback instead
```
```svelte
<!file: App.svelte>
<script>
import Child from './Child.svelte';
let person = $state({ name: 'Florida', surname: 'Man' });
</script>
```svelte
<!file: Child.svelte>
<script>
let { person } = $props();
</script>
<input bind:value={person.name}>
<input bind:value={person.surname}>
```
To fix it, either create callback props to communicate changes, or mark `person` as
[`$bindable`]($bindable).
### state_proxy_equality_mismatch
```
Reactive `$state(...)` proxies and the values they proxy have different identities.
Because of this, comparisons with `%operator%` will produce unexpected results
```
`$state(...)` creates a
[proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/Proxy) of the value it is passed. The proxy and the value have
different identities, meaning equality checks will always return `false`:
```svelte
<script>
let value = { foo: 'bar' };
let proxy = $state(value);
To resolve this, ensure you're comparing values where both values were created with
`$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a
state proxy.
### transition_slide_display
```
The `slide` transition does not work correctly for elements with `display: %value%`
```
- `display: inline` (which is the default for elements like `<span>`), and its
variants like `inline-block`, `inline-flex` and `inline-grid`
- `display: table` and `table-[name]`, which are the defaults for elements like
`<table>` and `<tr>`
- `display: contents`
## Shared warnings
### dynamic_void_element_content
```
`<svelte:element this="%tag%">` is a void element — it cannot have content
```
Elements such as `<input>` cannot have content, any children passed to these
elements will be ignored.
### state_snapshot_uncloneable
```
Value cannot be cloned with `$state.snapshot` — the original value was returned
```
```
The following properties cannot be cloned with `$state.snapshot` — the return value
contains the originals:
%properties%
```
```js
const object = $state({ property: 'this is cloneable', window })
const snapshot = $state.snapshot(object);
```
## docs/svelte/99-legacy/index.md
---
## docs/svelte/99-legacy/00-legacy-overview.md
---
title: Overview
---
Since Svelte 3/4 syntax still works in Svelte 5, we will distinguish between
_legacy mode_ and _runes mode_. Once a component is in runes mode (which you can
opt into by using runes, or by explicitly setting the `runes: true` compiler
option), legacy mode features are no longer available.
If you're exclusively interested in the Svelte 3/4 syntax, you can browse its
documentation at [v4.svelte.dev](https://v4.svelte.dev).
## docs/svelte/99-legacy/01-legacy-let.md
---
In runes mode, reactive state is explicitly declared with the [`$state` rune]
($state).
```svelte
<script>
let count = 0;
</script>
```svelte
<script>
let numbers = [1, 2, 3, 4];
function addNumber() {
// this method call does not trigger an update
numbers.push(numbers.length + 1);
## docs/svelte/99-legacy/02-legacy-reactive-assignments.md
---
In runes mode, reactions to state updates are handled with the [`$derived`]
($derived) and [`$effect`]($effect) runes.
In legacy mode, any top-level statement (i.e. not inside a block or a function) can
be made reactive by prefixing it with a `$:`
[label](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Statements/label). These statements run after other code in the `<script>` and
before the component markup is rendered, then whenever the values that they depend
on change.
```svelte
<script>
let a = 1;
let b = 2;
```js
// @noErrors
$: {
// recalculate `total` when `items` changes
total = 0;
```js
// @noErrors
$: ({ larry, moe, curly } = stooges);
```
## Understanding dependencies
The dependencies of a `$:` statement are determined at compile time — they are
whichever variables are referenced (but not assigned to) inside the statement.
In other words, a statement like this will _not_ re-run when `count` changes,
because the compiler cannot 'see' the dependency:
```js
// @noErrors
let count = 0;
let double = () => count * 2;
$: doubled = double();
```
```svelte
<script>
let x = 0;
let y = 0;
$: z = y;
$: setY(x);
function setY(value) {
y = value;
}
</script>
```
## Browser-only code
```js
// @noErrors
$: if (browser) {
document.title = title;
}
```
## docs/svelte/99-legacy/03-legacy-export-let.md
---
In legacy mode, props are marked with the `export` keyword, and can have a default
value:
```svelte
<script>
export let foo;
export let bar = 'default value';
The default value is used if it would otherwise be `undefined` when the component
is created.
Props without default values are considered _required_, and Svelte will print a
warning during development if no value is provided, which you can squelch by
specifying `undefined` as the default value:
```js
export let foo= undefined;
```
## Component exports
```svelte
<!file: Greeter.svelte>
<script>
export function greet(name) {
alert(`hello ${name}!`);
}
</script>
```
```svelte
<!file: App.svelte>
<script>
import Greeter from './Greeter.svelte';
let greeter;
</script>
## Renaming props
The `export` keyword can appear separately from the declaration. This is useful for
renaming props, for example in the case of a reserved word:
```svelte
<!file: App.svelte>
<script>
/** @type {string} */
let className;
## docs/svelte/99-legacy/04-legacy-$$props-and-$$restProps.md
---
In runes mode, getting an object containing all the props that were passed in is
easy, using the [`$props`]($props) rune.
- `$$props` contains all the props that were passed in, including ones that are not
individually declared with the `export` keyword
- `$$restProps` contains all the props that were passed in _except_ the ones that
were individually declared
For example, a `<Button>` component might need to pass along all its props to its
own `<button>` element, except the `variant` prop:
```svelte
<script>
export let variant;
</script>
<style>
.variant-danger {
background: red;
}
</style>
```
## docs/svelte/99-legacy/10-legacy-on.md
---
title: on:
---
In runes mode, event handlers are just like any other attribute or prop.
```svelte
<!file: App.svelte>
<script>
let count = 0;
<button on:click={handleClick}>
count: {count}
</button>
```
```svelte
<button on:click={() => (count += 1)}>
count: {count}
</button>
```
```svelte
<form on:submit|preventDefault={handleSubmit}>
<!-- the `submit` event's default is prevented,
so the page won't reload -->
</form>
```
If the `on:` directive is used without a value, the component will _forward_ the
event, meaning that a consumer of the component can listen for it.
```svelte
<button on:click>
The component itself will emit the click event
</button>
```
It's possible to have multiple event listeners for the same event:
```svelte
<!file: App.svelte>
<script>
let count = 0;
function increment() {
count += 1;
}
## Component events
```svelte
<!file: Stepper.svelte -->
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
```svelte
<script>
import Stepper from './Stepper.svelte';
let n = 0;
</script>
<Stepper
on:decrement={() => n -= 1}
on:increment={() => n += 1}
/>
<p>n: {n}</p>
```
Component events do not bubble — a parent component can only listen for events on
its immediate children.
Other than `once`, modifiers are not valid on component event handlers.
> If you're planning an eventual migration to Svelte 5, use callback props instead.
This will make upgrading easier as `createEventDispatcher` is deprecated:
>
> ```svelte
> <!--- file: Stepper.svelte --->
> <script>
> export let decrement;
> export let increment;
> </script>
>
> <button on:click={decrement}>decrement</button>
> <button on:click={increment}>increment</button>
> ```
## docs/svelte/99-legacy/20-legacy-slots.md
---
title: <slot>
---
```svelte
<!file: App.svelte>
<script>
import Modal from './Modal.svelte';
</script>
<Modal>This is some slotted content</Modal>
```
```svelte
<!file: Modal.svelte>
<div class="modal">
<slot></slot>
</div>
```
## Named slots
A component can have _named_ slots in addition to the default slot. On the parent
side, add a `slot="..."` attribute to an element, component or
[`<svelte:fragment>`](legacy-svelte-fragment) directly inside the component tags.
```svelte
<!file: App.svelte>
<script>
import Modal from './Modal.svelte';
{#if open}
<Modal>
This is some slotted content
<div slot="buttons">
<button on:click={() => open = false}>
close
</button>
</div>
</Modal>
{/if}
```
```svelte
<!file: Modal.svelte>
<div class="modal">
<slot></slot>
<hr>
<slot name="buttons"></slot>
</div>
```
## Fallback content
```svelte
<slot>
This will be rendered if no slotted content is provided
</slot>
```
Slots can be rendered zero or more times and can pass values _back_ to the parent
using props. The parent exposes the values to the slot template using the `let:`
directive.
```svelte
<!file: FancyList.svelte>
<ul>
{#each items as data}
<li class="fancy">
<!-- 'item' here... -->
<slot item={process(data)} />
</li>
{/each}
</ul>
```
```svelte
<!file: App.svelte>
<!-- ...corresponds to 'item' here: -->
<FancyList {items} let:item={processed}>
<div>{processed.text}</div>
</FancyList>
```
Named slots can also expose values. The `let:` directive goes on the element with
the `slot` attribute.
```svelte
<!file: FancyList.svelte>
<ul>
{#each items as item}
<li class="fancy">
<slot name="item" item={process(data)} />
</li>
{/each}
</ul>
```svelte
<!file: App.svelte>
<FancyList {items}>
<div slot="item" let:item>{item.text}</div>
<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>
```
## docs/svelte/99-legacy/21-legacy-$$slots.md
---
title: $$slots
---
In legacy mode, the way to know if content was provided for a given slot is with
the `$$slots` object, whose keys are the names of the slots passed into the
component by the parent.
```svelte
<!file: Card.svelte>
<div>
<slot name="title" />
{#if $$slots.description}
<!-- This <hr> and slot will render only if `slot="description"` is
provided. -->
<hr />
<slot name="description" />
{/if}
</div>
```
```svelte
<!file: App.svelte>
<Card>
<h1 slot="title">Blog Post Title</h1>
<!-- No slot named "description" was provided so the optional slot will not
be rendered. -->
</Card>
```
## docs/svelte/99-legacy/22-legacy-svelte-fragment.md
---
title: <svelte:fragment>
---
```svelte
<!file: Widget.svelte>
<div>
<slot name="header">No header was provided</slot>
<p>Some content between header and footer</p>
<slot name="footer" />
</div>
```
```svelte
<!file: App.svelte>
<script>
import Widget from './Widget.svelte';
</script>
<Widget>
<h1 slot="header">Hello</h1>
<svelte:fragment slot="footer">
<p>All rights reserved.</p>
<p>Copyright (c) 2019 Svelte Industries</p>
</svelte:fragment>
</Widget>
```
> In Svelte 5+, this concept is obsolete, as snippets don't create a wrapping
element
## docs/svelte/99-legacy/30-legacy-svelte-component.md
---
title: <svelte:component>
---
```svelte
<svelte:component this={MyComponent} />
```
## docs/svelte/99-legacy/31-legacy-svelte-self.md
---
title: <svelte:self>
---
It cannot appear at the top level of your markup; it must be inside an if or each
block or passed to a component's slot to prevent an infinite loop.
```svelte
<script>
export let count;
</script>
## docs/svelte/99-legacy/40-legacy-component-api.md
---
In Svelte 3 and 4, the API for interacting with a component is different than in
Svelte 5. Note that this page does _not_ apply to legacy mode components in a
Svelte 5 application.
## Creating a component
```ts
// @noErrors
const component = new Component(options);
```
A client-side component — that is, a component compiled with `generate: 'dom'` (or
the `generate` option left unspecified) is a JavaScript class.
```ts
// @noErrors
import App from './App.svelte';
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-
side rendering) rather than creating new elements. It will only work if the
component was compiled with the [`hydratable: true` option](/docs/svelte-
compiler#compile). Hydration of `<head>` elements only works properly if the
server-side rendering code was also compiled with `hydratable: true`, which adds a
marker to each element in the `<head>` so that the component knows which elements
it's responsible for removing during hydration.
Whereas children of `target` are normally left alone, `hydrate: true` will cause
any children to be removed. For that reason, the `anchor` option cannot be used
alongside `hydrate: true`.
The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM
as it goes.
```ts
/// file: index.js
// @noErrors
import App from './App.svelte';
## `$set`
```ts
// @noErrors
component.$set(props);
```
Calling this method schedules an update for the next microtask — the DOM is _not_
updated synchronously.
```ts
// @noErrors
component.$set({ answer: 42 });
```
> In Svelte 5+, use `$state` instead to create a component props and update that
>
> ```js
> // @noErrors
> let props = $state({ answer: 42 });
> const component = mount(Component, { props });
> // ...
> props.answer = 24;
> ```
## `$on`
```ts
// @noErrors
component.$on(ev, callback);
```
A function is returned that will remove the event listener when called.
```ts
// @noErrors
const off = component.$on('selected', (event) => {
console.log(event.detail.selection);
});
off();
```
## `$destroy`
```js
// @noErrors
component.$destroy();
```
Removes a component from the DOM and triggers any `onDestroy` handlers.
## Component props
```js
// @noErrors
component.prop;
```
```js
// @noErrors
component.prop = value;
```
If a component is compiled with `accessors: true`, each instance will have getters
and setters corresponding to each of the component's props. Setting a value will
cause a _synchronous_ update, rather than the default async update caused by
`component.$set(...)`.
By default, `accessors` is `false`, unless you're compiling as a custom element.
```js
// @noErrors
console.log(component.count);
component.count += 1;
```
> In Svelte 5+, this concept is obsolete. If you want to make properties accessible
from the outside, `export` them
```js
// @noErrors
const result = Component.render(...)
```
A server-side component exposes a `render` method that can be called with optional
props. It returns an object with `head`, `html`, and `css` properties, where `head`
contains the contents of any `<svelte:head>` elements encountered.
You can import a Svelte component directly into Node using `svelte/register`.
```js
// @noErrors
require('svelte/register');
```js
// @noErrors
const { head, html, css } = App.render(
// props
{ answer: 42 },
// options
{
context: new Map([['context-key', 'context-value']])
}
);
```
Instructions for LLMs: <SYSTEM>Always use Svelte 5 runes and Svelte 5 syntax. Runes
do not need to be imported, they are globals. $state() runes are always declared
using `let`, never with `const`. When passing a function to $derived, you must
always use $derived.by(() => ...). Error boundaries can only catch errors during
component rendering and at the top level of an $effect inside the error boundary.
Error boundaries do not catch errors in onclick or other event handlers.</SYSTEM>
---
## docs/kit/index.md
---
title: SvelteKit
---
## docs/kit/10-getting-started/index.md
---
## docs/kit/10-getting-started/10-introduction.md
---
title: Introduction
---
## Before we begin
>
> If you get stuck, reach out for help in the [Discord chatroom](/chat).
## What is SvelteKit?
To learn more about the kinds of applications you can build with SvelteKit, see the
[documentation regarding project types](project-types).
## What is Svelte?
## SvelteKit vs Svelte
Svelte renders UI components. You can compose these components and render an entire
page with just Svelte, but you need more than just Svelte to write an entire app.
SvelteKit helps you build web apps while following modern best practices and
providing solutions to common development challenges. It offers everything from
basic functionalities — like a [router](glossary#Routing) that updates your UI when
a link is clicked — to more advanced capabilities. Its extensive list of features
includes [build optimizations](https://vitejs.dev/guide/features.html#build-
optimizations) to load only the minimal required code; [offline support](service-
workers); [preloading](link-options#data-sveltekit-preload-data) pages before user
navigation; [configurable rendering](page-options) to handle different parts of
your app on the server via [SSR](glossary#SSR), in the browser through [client-side
rendering](glossary#CSR), or at build-time with [prerendering]
(glossary#Prerendering); [image optimization](images); and much more. Building an
app with all the modern best practices is fiendishly complicated, but SvelteKit
does all the boring stuff for you so that you can get on with the creative part.
## docs/kit/10-getting-started/20-creating-a-project.md
---
The easiest way to start building a SvelteKit app is to run `npx sv create`:
```bash
npx sv create my-app
cd my-app
npm install
npm run dev
```
The first command will scaffold a new project in the `my-app` directory asking you
if you'd like to set up some basic tooling such as TypeScript. See [integrations]
(./integrations) for pointers on setting up additional tooling. The subsequent
commands will then install its dependencies and start a server on [localhost:5173]
(http://localhost:5173).
## Editor setup
## docs/kit/10-getting-started/25-project-types.md
---
SvelteKit offers configurable rendering, which allows you to build and deploy your
project in several different ways. You can build all of the below types of
applications and more with SvelteKit. Rendering settings are not mutually exclusive
and you may choose the optimal manner with which to render different parts of your
application.
If you don't have a particular way you'd like to build your application in mind,
don't worry! The way your application is built, deployed, and rendered is
controlled by which adapter you've chosen and a small amount of configuration and
these can always be changed later. The [project structure](project-structure) and
[routing](glossary#Routing) will be the same regardless of the project type that
you choose.
## Default rendering
By default, when a user visits a site, SvelteKit will render the first page with
[server-side rendering (SSR)](glossary#SSR) and subsequent pages with [client-side
rendering (CSR)](glossary#CSR). Using SSR for the initial render improves SEO and
perceived performance of the initial page load. Client-side rendering then takes
over and updates the page without having to rerender common components, which is
typically faster and eliminates a flash when navigating between pages. Apps built
with this hybrid rendering approach have also been called [transitional apps]
(https://www.youtube.com/watch?v=860d8usGC0o).
You can use SvelteKit as a [static site generator (SSG)](glossary#SSG) that fully
[prerenders](glossary#Prerendering) your site with static rendering using
[`adapter-static`](adapter-static). You may also use [the prerender option](page-
options#prerender) to prerender only some pages and then choose a different adapter
with which to dynamically server-render other pages.
Tools built solely to do static site generation may scale the prerendering process
more efficiently during build when rendering a very large number of pages. When
working with very large statically generated sites, you can avoid long build times
with [Incremental Static Regeneration (ISR) if using `adapter-vercel`](adapter-
vercel#Incremental-Static-Regeneration). And in contrast to purpose-built SSGs,
SvelteKit allows for nicely mixing and matching different rendering types on
different pages.
## Single-page app
[Single-page apps (SPAs)](glossary#SPA) exclusively use [client-side rendering
(CSR)](glossary#CSR). You can [build single-page apps (SPAs)](single-page-apps)
with SvelteKit. As with all types of SvelteKit applications, you can write your
backend in SvelteKit or [another language or framework](#Separate-backend). If you
are building an application with no backend or a [separate backend](#Separate-
backend), you can simply skip over and ignore the parts of the docs talking about
`server` files.
## Multi-page app
## Separate backend
If your backend is written in another language such as Go, Java, PHP, Ruby, Rust,
or C#, there are a couple of ways that you can deploy your application. The most
recommended way would be to deploy your SvelteKit frontend separately from your
backend utilizing `adapter-node` or a serverless adapter. Some users prefer not to
have a separate process to manage and decide to deploy their application as a
[single-page app (SPA)](single-page-apps) served by their backend server, but note
that single-page apps have worse SEO and performance characteristics.
If you are using an external backend, you can simply skip over and ignore the parts
of the docs talking about `server` files. You may also want to reference [the FAQ
about how to make calls to a separate backend](faq#How-do-I-use-a-different-
backend-API-server).
## Serverless app
SvelteKit apps are simple to run on serverless platforms. [The default zero config
adapter](adapter-auto) will automatically run your app on a number of supported
platforms or you can use [`adapter-vercel`](adapter-vercel), [`adapter-netlify`]
(adapter-netlify), or [`adapter-cloudflare`](adapter-cloudflare) to provide
platform-specific configuration. And [community
adapters](https://sveltesociety.dev/packages?category=sveltekit-adapters) allow you
to deploy your application to almost any serverless environment. Some of these
adapters such as [`adapter-vercel`](adapter-vercel) and [`adapter-netlify`]
(adapter-netlify) offer an `edge` option, to support [edge rendering]
(glossary#Edge) for improved latency.
## Container
## Library
You can create a library to be used by other Svelte apps with the
[`@sveltejs/package`](packaging) add-on to SvelteKit by choosing the library option
when running [`sv create`](/docs/cli/sv-create).
## Offline app
## Mobile app
You can turn a [SvelteKit SPA](single-page-apps) into a mobile app with [Tauri]
(https://v2.tauri.app/start/frontend/sveltekit/) or
[Capacitor](https://capacitorjs.com/solution/svelte). Mobile features like the
camera, geolocation, and push notifications are available via plugins for both
platforms.
These mobile development platforms work by starting a local web server and then
serving your application like a static host on your phone. You may find
[`bundleStrategy: 'single'`](configuration#output) to be a helpful option to limit
the number of requests made. E.g. at the time of writing, the Capacitor local
server uses HTTP/1, which limits the number of concurrent connections.
## Desktop app
You can turn a [SvelteKit SPA](single-page-apps) into a desktop app with [Tauri]
(https://v2.tauri.app/start/frontend/sveltekit/),
[Wails](https://wails.io/docs/guides/sveltekit/), or
[Electron](https://www.electronjs.org/).
## Browser extension
## Embedded device
Because of its efficient rendering, Svelte can be run on low power devices.
Embedded devices like microcontrollers and TVs may limit the number of concurrent
connections. In order to reduce the number of concurrent requests, you may find
[`bundleStrategy: 'single'`](configuration#output) to be a helpful option in this
deployment configuration.
## docs/kit/10-getting-started/30-project-structure.md
---
```bash
my-project/
├ src/
│ ├ lib/
│ │ ├ server/
│ │ │ └ [your server-only lib files]
│ │ └ [your lib files]
│ ├ params/
│ │ └ [your param matchers]
│ ├ routes/
│ │ └ [your routes]
│ ├ app.html
│ ├ error.html
│ ├ hooks.client.js
│ ├ hooks.server.js
│ └ service-worker.js
├ static/
│ └ [your static assets]
├ tests/
│ └ [your tests]
├ package.json
├ svelte.config.js
├ tsconfig.json
└ vite.config.js
```
You'll also find common files like `.gitignore` and `.npmrc` (and `.prettierrc` and
`eslint.config.js` and so on, if you chose those options when running `npx sv
create`).
## Project files
### src
The `src` directory contains the meat of your project. Everything except
`src/routes` and `src/app.html` is optional.
- `lib` contains your library code (utilities and components), which can be
imported via the [`$lib`]($lib) alias, or packaged up for distribution using
[`svelte-package`](packaging)
- `server` contains your server-only library code. It can be imported by using
the [`$lib/server`](server-only-modules) alias. SvelteKit will prevent you from
importing these in client code.
- `params` contains any [param matchers](advanced-routing#Matching) your app needs
- `routes` contains the [routes](routing) of your application. You can also
colocate other components that are only used within a single route here
- `app.html` is your page template — an HTML document containing the following
placeholders:
- `%sveltekit.head%` — `<link>` and `<script>` elements needed by the app, plus
any `<svelte:head>` content
- `%sveltekit.body%` — the markup for a rendered page. This should live inside a
`<div>` or other element, rather than directly inside `<body>`, to prevent bugs
caused by browser extensions injecting elements that are then destroyed by the
hydration process. SvelteKit will warn you in development if this is not the case
- `%sveltekit.assets%` — either [`paths.assets`](configuration#paths), if
specified, or a relative path to [`paths.base`](configuration#paths)
- `%sveltekit.nonce%` — a [CSP](configuration#csp) nonce for manually included
links and scripts, if used
- `%sveltekit.env.[NAME]%` - this will be replaced at render time with the
`[NAME]` environment variable, which must begin with the [`publicPrefix`]
(configuration#env) (usually `PUBLIC_`). It will fallback to `''` if not matched.
- `error.html` is the page that is rendered when everything else fails. It can
contain the following placeholders:
- `%sveltekit.status%` — the HTTP status
- `%sveltekit.error.message%` — the error message
- `hooks.client.js` contains your client [hooks](hooks)
- `hooks.server.js` contains your server [hooks](hooks)
- `service-worker.js` contains your [service worker](service-workers)
(Whether the project contains `.js` or `.ts` files depends on whether you opt to
use TypeScript when you create your project. You can switch between JavaScript and
TypeScript in the documentation using the toggle at the bottom of this page.)
If you added [Vitest](https://vitest.dev) when you set up your project, your unit
tests will live in the `src` directory with a `.test.js` extension.
### static
Any static assets that should be served as-is, like `robots.txt` or `favicon.png`,
go in here.
### tests
### package.json
When you create a project with `npx sv create`, you'll also notice that
`package.json` includes `"type": "module"`. This means that `.js` files are
interpreted as native JavaScript modules with `import` and `export` keywords.
Legacy CommonJS files need a `.cjs` file extension.
### svelte.config.js
### tsconfig.json
This file (or `jsconfig.json`, if you prefer type-checked `.js` files over `.ts`
files) configures TypeScript, if you added typechecking during `npx sv create`.
Since SvelteKit relies on certain configuration being set a specific way, it
generates its own `.svelte-kit/tsconfig.json` file which your own config `extends`.
### vite.config.js
## Other files
### .svelte-kit
As you develop and build your project, SvelteKit will generate files in a `.svelte-
kit` directory (configurable as [`outDir`](configuration#outDir)). You can ignore
its contents, and delete them at any time (they will be regenerated when you next
`dev` or `build`).
## docs/kit/10-getting-started/40-web-standards.md
---
Throughout this documentation, you'll see references to the standard [Web APIs]
(https://developer.mozilla.org/en-US/docs/Web/API) that SvelteKit builds on top of.
Rather than reinventing the wheel, we _use the platform_, which means your existing
web development skills are applicable to SvelteKit. Conversely, time spent learning
SvelteKit will help you be a better web developer elsewhere.
These APIs are available in all modern browsers and in many non-browser
environments like Cloudflare Workers, Deno, and Vercel Functions. During
development, and in [adapters](adapters) for Node-based environments (including AWS
Lambda), they're made available via polyfills where necessary (for now, that is —
Node is rapidly adding support for more web standards).
## Fetch APIs
### Request
An instance of
[`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) is accessible
in [hooks](hooks) and [server routes](routing#server) as `event.request`. It
contains useful methods like `request.json()` and `request.formData()` for getting
data that was posted to an endpoint.
### Response
An instance of
[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) is returned
from `await fetch(...)` and handlers in `+server.js` files. Fundamentally, a
SvelteKit app is a machine for turning a `Request` into a `Response`.
### Headers
```js
// @errors: 2461
/// file: src/routes/what-is-my-user-agent/+server.js
import { json } from '@sveltejs/kit';
## FormData
When dealing with HTML native form submissions you'll be working with [`FormData`]
(https://developer.mozilla.org/en-US/docs/Web/API/FormData) objects.
```js
// @errors: 2461
/// file: src/routes/hello/+server.js
import { json } from '@sveltejs/kit';
return json({
// get a specific field's value
name: body.get('name') ?? 'world'
});
}
```
## Stream APIs
Most of the time, your endpoints will return complete data, as in the `userAgent`
example above. Sometimes, you may need to return a response that's too large to fit
in memory in one go, or is delivered in chunks, and for this the platform provides
[streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) —
[ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream),
[WritableStream](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream)
and [TransformStream](https://developer.mozilla.org/en-US/docs/Web/API/
TransformStream).
## URL APIs
### URLSearchParams
Wherever you encounter a URL, you can access query parameters via
`url.searchParams`, which is an instance of
[`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/
URLSearchParams):
```js
// @filename: ambient.d.ts
declare global {
const url: URL;
}
export {};
// @filename: index.js
//cut
const foo = url.searchParams.get('foo');
```
## Web Crypto
```js
const uuid = crypto.randomUUID();
```
## docs/kit/20-core-concepts/index.md
---
## docs/kit/20-core-concepts/10-routing.md
---
title: Routing
---
Each route directory contains one or more _route files_, which can be identified by
their `+` prefix.
We'll introduce these files in a moment in more detail, but here are a few simple
rules to help you remember how SvelteKit's routing works:
* All files can run on the server
* All files run on the client except `+server` files
* `+layout` and `+error` files apply to subdirectories as well as the directory
they live in
## +page
### +page.svelte
```svelte
<!file: src/routes/+page.svelte>
<h1>Hello and welcome to my site!</h1>
<a href="/about">About my site</a>
```
```svelte
<!file: src/routes/about/+page.svelte>
<h1>About this site</h1>
<p>TODO...</p>
<a href="/">Home</a>
```
Pages can receive data from `load` functions via the `data` prop.
```svelte
<!file: src/routes/blog/[slug]/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
<h1>{data.title}</h1>
<div>{@html data.content}</div>
```
> [!LEGACY]
> `PageProps` was added in 2.16.0. In earlier versions, you had to type the `data`
property manually with `PageData` instead, see [$types](#\$types).
>
> In Svelte 4, you'd use `export let data` instead.
### +page.js
Often, a page will need to load some data before it can be rendered. For this, we
add a `+page.js` module that exports a `load` function:
```js
/// file: src/routes/blog/[slug]/+page.js
import { error } from '@sveltejs/kit';
This function runs alongside `+page.svelte`, which means it runs on the server
during server-side rendering and in the browser during client-side navigation. See
[`load`](load) for full details of the API.
As well as `load`, `+page.js` can export values that configure the page's
behaviour:
### +page.server.js
If your `load` function can only run on the server — for example, if it needs to
fetch data from a database or you need to access private [environment variables]
($env-static-private) like API keys — then you can rename `+page.js` to
`+page.server.js` and change the `PageLoad` type to `PageServerLoad`.
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare global {
const getPostFromDatabase: (slug: string) => {
title: string;
content: string;
}
}
export {};
// @filename: index.js
//cut
import { error } from '@sveltejs/kit';
if (post) {
return post;
}
During client-side navigation, SvelteKit will load this data from the server, which
means that the returned value must be serializable using
[devalue](https://github.com/rich-harris/devalue). See [`load`](load) for full
details of the API.
A `+page.server.js` file can also export _actions_. If `load` lets you read data
from the server, `actions` let you write data _to_ the server using the `<form>`
element. To learn how to use them, see the [form actions](form-actions) section.
## +error
If an error occurs during `load`, SvelteKit will render a default error page. You
can customise this error page on a per-route basis by adding an `+error.svelte`
file:
```svelte
<!file: src/routes/blog/[slug]/+error.svelte>
<script>
import { page } from '$app/state';
</script>
<h1>{page.status}: {page.error.message}</h1>
```
> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or
are using Svelte 4, use `$app/stores` instead.
SvelteKit will 'walk up the tree' looking for the closest error boundary — if the
file above didn't exist it would try `src/routes/blog/+error.svelte` and then
`src/routes/+error.svelte` before rendering the default error page. If _that_ fails
(or if the error was thrown from the `load` function of the root `+layout`, which
sits 'above' the root `+error`), SvelteKit will bail out and render a static
fallback error page, which you can customise by creating a `src/error.html` file.
## +layout
But in many apps, there are elements that should be visible on _every_ page, such
as top-level navigation or a footer. Instead of repeating them in every
`+page.svelte`, we can put them in _layouts_.
### +layout.svelte
To create a layout that applies to every page, make a file called
`src/routes/+layout.svelte`. The default layout (the one that SvelteKit uses if you
don't bring your own) looks like this...
```svelte
<script>
let { children } = $props();
</script>
{@render children()}
```
...but we can add whatever markup, styles and behaviour we want. The only
requirement is that the component includes a `@render` tag for the page content.
For example, let's add a nav bar:
```svelte
<!file: src/routes/+layout.svelte>
<script>
let { children } = $props();
</script>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
{@render children()}
```
```html
/// file: src/routes/+page.svelte
<h1>Home</h1>
```
```html
/// file: src/routes/about/+page.svelte
<h1>About</h1>
```
```html
/// file: src/routes/settings/+page.svelte
<h1>Settings</h1>
```
...the nav will always be visible, and clicking between the three pages will only
result in the `<h1>` being replaced.
Layouts can be _nested_. Suppose we don't just have a single `/settings` page, but
instead have nested pages like `/settings/profile` and `/settings/notifications`
with a shared submenu (for a real-life example, see
[github.com/settings](https://github.com/settings)).
We can create a layout that only applies to pages below `/settings` (while
inheriting the root layout with the top-level nav):
```svelte
<!file: src/routes/settings/+layout.svelte>
<script>
/** @type {import('./$types').LayoutProps} */
let { data, children } = $props();
</script>
<h1>Settings</h1>
<div class="submenu">
{#each data.sections as section}
<a href="/settings/{section.slug}">{section.title}</a>
{/each}
</div>
{@render children()}
```
> [!LEGACY]
> `LayoutProps` was added in 2.16.0. In earlier versions, you had to [type the
properties manually instead](#\$types).
You can see how `data` is populated by looking at the `+layout.js` example in the
next section just below.
By default, each layout inherits the layout above it. Sometimes that isn't what you
want - in this case, [advanced layouts](advanced-routing#Advanced-layouts) can help
you.
### +layout.js
```js
/// file: src/routes/settings/+layout.js
/** @type {import('./$types').LayoutLoad} */
export function load() {
return {
sections: [
{ slug: 'profile', title: 'Profile' },
{ slug: 'notifications', title: 'Notifications' }
]
};
}
```
Data returned from a layout's `load` function is also available to all its child
pages:
```svelte
<!file: src/routes/settings/profile/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script>
```
### +layout.server.js
## +server
As well as pages, you can define routes with a `+server.js` file (sometimes
referred to as an 'API route' or an 'endpoint'), which gives you full control over
the response. Your `+server.js` file exports functions corresponding to HTTP verbs
like `GET`, `POST`, `PATCH`, `PUT`, `DELETE`, `OPTIONS`, and `HEAD` that take a
`RequestEvent` argument and return a [`Response`](https://developer.mozilla.org/en-
US/docs/Web/API/Response) object.
```js
/// file: src/routes/api/random-number/+server.js
import { error } from '@sveltejs/kit';
if (isNaN(d) || d < 0) {
error(400, 'min and max must be numbers, and min must be less than
max');
}
```svelte
<!file: src/routes/add/+page.svelte>
<script>
let a = 0;
let b = 0;
let total = 0;
<button onclick={add}>Calculate</button>
```
```js
/// file: src/routes/api/add/+server.js
import { json } from '@sveltejs/kit';
Exporting the `fallback` handler will match any unhandled request methods,
including methods like `MOVE` which have no dedicated export from `+server.js`.
```js
/// file: src/routes/api/add/+server.js
import { json, text } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function POST({ request }) {
const { a, b } = await request.json();
return json(a + b);
}
`+server.js` files can be placed in the same directory as `+page` files, allowing
the same route to be either a page or an API endpoint. To determine which,
SvelteKit applies the following rules:
## $types
Throughout the examples above, we've been importing types from a `$types.d.ts`
file. This is a file SvelteKit creates for you in a hidden directory if you're
using TypeScript (or JavaScript with JSDoc type annotations) to give you type
safety when working with your root files.
```svelte
<!file: src/routes/blog/[slug]/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
```
> The `PageProps` and `LayoutProps` types, added in 2.16.0, are a shortcut for
typing the `data` prop as `PageData` or `LayoutData`, as well as other props, such
as `form` for pages, or `children` for layouts. In earlier versions, you had to
type these properties manually. For example, for a page:
>
> ```js
> /// file: +page.svelte
> /** @type {{ data: import('./$types').PageData, form:
import('./$types').ActionData }} */
> let { data, form } = $props();
> ```
>
> Or, for a layout:
>
> ```js
> /// file: +layout.svelte
> /** @type {{ data: import('./$types').LayoutData, children: Snippet }} */
> let { data, children } = $props();
> ```
If you're using VS Code or any IDE that supports the language server protocol and
TypeScript plugins then you can omit these types _entirely_! Svelte's IDE tooling
will insert the correct types for you, so you'll get type checking without writing
them yourself. It also works with our command line tool `svelte-check`.
You can read more about omitting `$types` in our [blog post](/blog/zero-config-
type-safety) about it.
## Other files
Any other files inside a route directory are ignored by SvelteKit. This means you
can colocate components and utility modules with the routes that need them.
If components and modules are needed by multiple routes, it's a good idea to put
them in [`$lib`]($lib).
## Further reading
- [Tutorial: Routing](/tutorial/kit/pages)
- [Tutorial: API routes](/tutorial/kit/get-handlers)
- [Docs: Advanced routing](advanced-routing)
## docs/kit/20-core-concepts/20-load.md
---
## Page data
A `+page.svelte` file can have a sibling `+page.js` that exports a `load` function,
the return value of which is available to the page via the `data` prop:
```js
/// file: src/routes/blog/[slug]/+page.js
/** @type {import('./$types').PageLoad} */
export function load({ params }) {
return {
post: {
title: `Title for ${params.slug} goes here`,
content: `Content for ${params.slug} goes here`
}
};
}
```
```svelte
<!file: src/routes/blog/[slug]/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
```
> [!LEGACY]
> Before version 2.16.0, the props of a page and layout had to be typed
individually:
> ```js
> /// file: +page.svelte
> /** @type {{ data: import('./$types').PageData }} */
> let { data } = $props();
> ```
>
> In Svelte 4, you'd use `export let data` instead.
A `load` function in a `+page.js` file runs both on the server and in the browser
(unless combined with `export const ssr = false`, in which case it will [only run
in the browser](page-options#ssr)). If your `load` function should _always_ run on
the server (because it uses private environment variables, for example, or accesses
a database) then it would go in a `+page.server.js` instead.
A more realistic version of your blog post's `load` function, that only runs on the
server and pulls data from a database, might look like this:
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content:
string }>
}
// @filename: index.js
//cut
import * as db from '$lib/server/database';
Notice that the type changed from `PageLoad` to `PageServerLoad`, because server
`load` functions can access additional arguments. To understand when to use
`+page.js` and when to use `+page.server.js`, see [Universal vs server]
(load#Universal-vs-server).
## Layout data
```js
/// file: src/routes/blog/[slug]/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPostSummaries(): Promise<Array<{ title: string, slug:
string }>>
}
// @filename: index.js
//cut
import * as db from '$lib/server/database';
```svelte
<!file: src/routes/blog/[slug]/+layout.svelte>
<script>
/** @type {import('./$types').LayoutProps} */
let { data, children } = $props();
</script>
<main>
<!-- +page.svelte is `@render`ed here -->
{@render children()}
</main>
<aside>
<h2>More posts</h2>
<ul>
{#each data.posts as post}
<li>
<a href="/blog/{post.slug}">
{post.title}
</a>
</li>
{/each}
</ul>
</aside>
```
> [!LEGACY]
> `LayoutProps` was added in 2.16.0. In earlier versions, properties had to be
typed individually:
> ```js
> /// file: +layout.svelte
> /** @type {{ data: import('./$types').LayoutData, children: Snippet }} */
> let { data, children } = $props();
> ```
```svelte
/// file: src/routes/blog/[slug]/+page.svelte
<script>
import { page } from '$app/state';
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
{#if next}
<p>Next post: <a href="/blog/{next.slug}">{next.title}</a></p>
{/if}
```
## page.data
The `+page.svelte` component, and each `+layout.svelte` component above it, has
access to its own data plus all the data from its parents.
In some cases, we might need the opposite — a parent layout might need to access
page data or data from a child layout. For example, the root layout might want to
access a `title` property returned from a `load` function in `+page.js` or
`+page.server.js`. This can be done with `page.data`:
```svelte
<!file: src/routes/+layout.svelte>
<script>
import { page } from '$app/state';
</script>
<svelte:head>
<title>{page.data.title}</title>
</svelte:head>
```
> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or
are using Svelte 4, use `$app/stores` instead.
> It provides a `page` store with the same interface that you can subscribe to,
e.g. `$page.data.title`.
## Universal vs server
* `+page.js` and `+layout.js` files export _universal_ `load` functions that run
both on the server and in the browser
* `+page.server.js` and `+layout.server.js` files export _server_ `load` functions
that only run server-side
Conceptually, they're the same thing, but there are some important differences to
be aware of.
By default, universal `load` functions run on the server during SSR when the user
first visits your page. They will then run again during hydration, reusing any
responses from [fetch requests](#Making-fetch-requests). All subsequent invocations
of universal `load` functions happen in the browser. You can customize the behavior
through [page options](page-options). If you disable [server side rendering](page-
options#ssr), you'll get an SPA and universal `load` functions _always_ run on the
client.
If a route contains both universal and server `load` functions, the server `load`
runs first.
### Input
Both universal and server `load` functions have access to properties describing the
request (`params`, `route` and `url`) and various functions (`fetch`, `setHeaders`,
`parent`, `depends` and `untrack`). These are described in the following sections.
Universal `load` functions are called with a `LoadEvent`, which has a `data`
property. If you have `load` functions in both `+page.js` and `+page.server.js` (or
`+layout.js` and `+layout.server.js`), the return value of the server `load`
function is the `data` property of the universal `load` function's argument.
### Output
A universal `load` function can return an object containing any values, including
things like custom classes and component constructors.
A server `load` function must return data that can be serialized with [devalue]
(https://github.com/rich-harris/devalue) — anything that can be represented as JSON
plus things like `BigInt`, `Date`, `Map`, `Set` and `RegExp`, or repeated/cyclical
references — so that it can be transported over the network. Your data can include
[promises](#Streaming-with-promises), in which case it will be streamed to
browsers.
### When to use which
Server `load` functions are convenient when you need to access data directly from a
database or filesystem, or need to use private environment variables.
Universal `load` functions are useful when you need to `fetch` data from an
external API and don't need private credentials, since SvelteKit can get the data
directly from the API rather than going via your server. They are also useful when
you need to return something that can't be serialized, such as a Svelte component
constructor.
In rare cases, you might need to use both together — for example, you might need to
return an instance of a custom class that was initialised with data from your
server. When using both, the server `load` return value is _not_ passed directly to
the page, but to the universal `load` function (as the `data` property):
```js
/// file: src/routes/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export async function load() {
return {
serverMessage: 'hello from server load function'
};
}
```
```js
/// file: src/routes/+page.js
// @errors: 18047
/** @type {import('./$types').PageLoad} */
export async function load({ data }) {
return {
serverMessage: data.serverMessage,
universalMessage: 'hello from universal load function'
};
}
```
Often the `load` function depends on the URL in one way or another. For this, the
`load` function provides you with `url`, `route` and `params`.
### url
An instance of [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL),
containing properties like the `origin`, `hostname`, `pathname` and `searchParams`
(which contains the parsed query string as a
[`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/
URLSearchParams) object). `url.hash` cannot be accessed during `load`, since it is
unavailable on the server.
### route
```js
/// file: src/routes/a/[b]/[...c]/+page.js
/** @type {import('./$types').PageLoad} */
export function load({ route }) {
console.log(route.id); // '/a/[b]/[...c]'
}
```
### params
```json
{
"b": "x",
"c": "y/z"
}
```
To get data from an external API or a `+server.js` handler, you can use the
provided `fetch` function, which behaves identically to the [native `fetch` web
API](https://developer.mozilla.org/en-US/docs/Web/API/fetch) with a few additional
features:
```js
/// file: src/routes/items/[id]/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, params }) {
const res = await fetch(`/api/items/${params.id}`);
const item = await res.json();
return { item };
}
```
## Cookies
```js
/// file: src/routes/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getUser(sessionid: string | undefined): Promise<{ name:
string, avatar: string }>
}
// @filename: index.js
//cut
import * as db from '$lib/server/database';
return {
user: await db.getUser(sessionid)
};
}
```
Cookies will only be passed through the provided `fetch` function if the target
host is the same as the SvelteKit application or a more specific subdomain of it.
Other cookies will not be passed when `credentials: 'include'` is set, because
SvelteKit does not know which domain which cookie belongs to (the browser does not
pass this information along), so it's not safe to forward any of them. Use the
[handleFetch hook](hooks#Server-hooks-handleFetch) to work around it.
## Headers
Both server and universal `load` functions have access to a `setHeaders` function
that, when running on the server, can set headers for the response. (When running
in the browser, `setHeaders` has no effect.) This is useful if you want the page to
be cached, for example:
```js
// @errors: 2322 1360
/// file: src/routes/products/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, setHeaders }) {
const url = `https://cms.example.com/products.json`;
const response = await fetch(url);
// Headers are only set during SSR, caching the page's HTML
// for the same length of time as the underlying data.
setHeaders({
age: response.headers.get('age'),
'cache-control': response.headers.get('cache-control')
});
return response.json();
}
```
Setting the same header multiple times (even in separate `load` functions) is an
error. You can only set a given header once using the `setHeaders` function. You
cannot add a `set-cookie` header with `setHeaders` — use `cookies.set(name, value,
options)` instead.
Occasionally it's useful for a `load` function to access data from a parent `load`
function, which can be done with `await parent()`:
```js
/// file: src/routes/+layout.js
/** @type {import('./$types').LayoutLoad} */
export function load() {
return { a: 1 };
}
```
```js
/// file: src/routes/abc/+layout.js
/** @type {import('./$types').LayoutLoad} */
export async function load({ parent }) {
const { a } = await parent();
return { b: a + 1 };
}
```
```js
/// file: src/routes/abc/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ parent }) {
const { a, b } = await parent();
return { c: a + b };
}
```
```svelte
<!file: src/routes/abc/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
Take care not to introduce waterfalls when using `await parent()`. Here, for
example, `getData(params)` does not depend on the result of calling `parent()`, so
we should call it first to avoid a delayed render.
```js
/// file: +page.js
// @filename: ambient.d.ts
declare function getData(params: Record<string, string>): Promise<{ meta: any }>
// @filename: index.js
//cut
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
const parentData = await parent();
const data = await getData(params);
const parentData = await parent();
return {
...data,
meta: { ...parentData.meta, ...data.meta }
};
}
```
## Errors
```js
/// file: src/routes/admin/+layout.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user?: {
name: string;
isAdmin: boolean;
}
}
}
// @filename: index.js
//cut
import { error } from '@sveltejs/kit';
if (!locals.user.isAdmin) {
error(403, 'not an admin');
}
}
```
Calling `error(...)` will throw an exception, making it easy to stop execution from
inside helper functions.
If an [_unexpected_](errors#Unexpected-errors) error is thrown, SvelteKit will
invoke [`handleError`](hooks#Shared-hooks-handleError) and treat it as a 500
Internal Error.
## Redirects
To redirect users, use the `redirect` helper from `@sveltejs/kit` to specify the
location to which they should be redirected alongside a `3xx` status code. Like
`error(...)`, calling `redirect(...)` will throw an exception, making it easy to
stop execution from inside helper functions.
```js
/// file: src/routes/user/+layout.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user?: {
name: string;
}
}
}
// @filename: index.js
//cut
import { redirect } from '@sveltejs/kit';
In the browser, you can also navigate programmatically outside of a `load` function
using [`goto`]($app-navigation#goto) from [`$app.navigation`]($app-navigation).
When using a server `load`, promises will be streamed to the browser as they
resolve. This is useful if you have slow, non-essential data, since you can start
rendering the page before all the data is available:
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare global {
const loadPost: (slug: string) => Promise<{ title: string, content:
string }>;
const loadComments: (slug: string) => Promise<{ content: string }>;
}
export {};
// @filename: index.js
//cut
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
return {
// make sure the `await` happens at the end, otherwise we
// can't start loading comments until we've loaded the post
comments: loadComments(params.slug),
post: await loadPost(params.slug)
};
}
```
```svelte
<!file: src/routes/blog/[slug]/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
{#await data.comments}
Loading comments...
{:then comments}
{#each comments as comment}
<p>{comment.content}</p>
{/each}
{:catch error}
<p>error loading comments: {error.message}</p>
{/await}
```
```js
/// file: src/routes/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export function load({ fetch }) {
const ok_manual = Promise.reject();
ok_manual.catch(() => {});
return {
ok_manual,
ok_fetch: fetch('/fetch/that/could/fail'),
dangerous_unhandled: Promise.reject()
};
}
```
## Parallel loading
When rendering (or navigating to) a page, SvelteKit runs all `load` functions
concurrently, avoiding a waterfall of requests. During client-side navigation, the
result of calling multiple server `load` functions are grouped into a single
response. Once all `load` functions have returned, the page is rendered.
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content:
string }>
}
// @filename: index.js
//cut
import * as db from '$lib/server/database';
```js
/// file: src/routes/blog/[slug]/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPostSummaries(): Promise<Array<{ title: string, slug:
string }>>
}
// @filename: index.js
//cut
import * as db from '$lib/server/database';
A `load` function that calls `await parent()` will also rerun if a parent `load`
function is rerun.
Dependency tracking does not apply _after_ the `load` function has returned — for
example, accessing `params.x` inside a nested [promise](#Streaming-with-promises)
will not cause the function to rerun when `params.x` changes. (Don't worry, you'll
get a warning in development if you accidentally do this.) Instead, access the
parameter in the main body of your `load` function.
Search parameters are tracked independently from the rest of the url. For example,
accessing `event.url.searchParams.get("x")` inside a `load` function will make that
`load` function re-run when navigating from `?x=1` to `?x=2`, but not when
navigating from `?x=1&y=1` to `?x=1&y=2`.
In rare cases, you may wish to exclude something from the dependency tracking
mechanism. You can do this with the provided `untrack` function:
```js
/// file: src/routes/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ untrack, url }) {
// Untrack url.pathname so that path changes don't trigger a rerun
if (untrack(() => url.pathname === '/')) {
return { message: 'Welcome!' };
}
}
```
You can also rerun `load` functions that apply to the current page using
[`invalidate(url)`]($app-navigation#invalidate), which reruns all `load` functions
that depend on `url`, and [`invalidateAll()`]($app-navigation#invalidateAll), which
reruns every `load` function. Server load functions will never automatically depend
on a fetched `url` to avoid leaking secrets to the client.
```js
/// file: src/routes/random-number/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, depends }) {
// load reruns when `invalidate('https://api.example.com/random-number')` is
called...
const response = await fetch('https://api.example.com/random-number');
return {
number: await response.json()
};
}
```
```svelte
<!file: src/routes/random-number/+page.svelte>
<script>
import { invalidate, invalidateAll } from '$app/navigation';
function rerunLoadFunction() {
// any of these will cause the `load` function to rerun
invalidate('app:random');
invalidate('https://api.example.com/random-number');
invalidate(url => url.href.includes('random-number'));
invalidateAll();
}
</script>
`params` and `url` can change in response to a `<a href="..">` link click, a
[`<form>` interaction](form-actions#GET-vs-POST), a [`goto`]($app-navigation#goto)
invocation, or a [`redirect`](@sveltejs-kit#redirect).
Note that rerunning a `load` function will update the `data` prop inside the
corresponding `+layout.svelte` or `+page.svelte`; it does _not_ cause the component
to be recreated. As a result, internal state is preserved. If this isn't what you
want, you can reset whatever you need to reset inside an [`afterNavigate`]($app-
navigation#afterNavigate) callback, and/or wrap your component in a [`{#key ...}`]
(../svelte/key) block.
A couple features of loading data have important implications for auth checks:
- Layout `load` functions do not run on every request, such as during client side
navigation between child routes. [(When do load functions rerun?)](load#Rerunning-
load-functions-When-do-load-functions-rerun)
- Layout and page `load` functions run concurrently unless `await parent()` is
called. If a layout `load` throws, the page `load` function runs, but the client
will not receive the returned data.
There are a few possible strategies to ensure an auth check occurs before protected
code.
## Using `getRequestEvent`
When running server `load` functions, the `event` object passed to the function as
an argument can also be retrieved with [`getRequestEvent`]($app-
server#getRequestEvent). This allows shared logic (such as authentication guards)
to access information about the current request without it needing to be passed
around.
For example, you might have a function that requires users to be logged in, and
redirects them to `/login` if not:
```js
/// file: src/lib/server/auth.js
// @filename: ambient.d.ts
interface User {
name: string;
}
// @filename: index.ts
//cut
import { redirect } from '@sveltejs/kit';
import { getRequestEvent } from '$app/server';
redirect(307, `/login?${params}`);
}
return locals.user;
}
```
Now, you can call `requireLogin` in any `load` function (or [form action](form-
actions), for example) to guarantee that the user is logged in:
```js
/// file: +page.server.js
// @filename: ambient.d.ts
// @filename: index.ts
//cut
import { requireLogin } from '$lib/server/auth';
## Further reading
## docs/kit/20-core-concepts/30-form-actions.md
---
A `+page.server.js` file can export _actions_, which allow you to `POST` data to
the server using the `<form>` element.
When using `<form>`, client-side JavaScript is optional, but you can easily
_progressively enhance_ your form interactions with JavaScript to provide the best
user experience.
## Default actions
```js
/// file: src/routes/login/+page.server.js
/** @satisfies {import('./$types').Actions} */
export const actions = {
default: async (event) => {
// TODO log the user in
}
};
```
To invoke this action from the `/login` page, just add a `<form>` — no JavaScript
needed:
```svelte
<!file: src/routes/login/+page.svelte>
<form method="POST">
<label>
Email
<input name="email" type="email">
</label>
<label>
Password
<input name="password" type="password">
</label>
<button>Log in</button>
</form>
```
If someone were to click the button, the browser would send the form data via
`POST` request to the server, running the default action.
We can also invoke the action from other pages (for example if there's a login
widget in the nav in the root layout) by adding the `action` attribute, pointing to
the page:
```html
/// file: src/routes/+layout.svelte
<form method="POST" action="/login">
<!-- content -->
</form>
```
## Named actions
Instead of one `default` action, a page can have as many named actions as it needs:
```js
/// file: src/routes/login/+page.server.js
/** @satisfies {import('./$types').Actions} */
export const actions = {
default: async (event) => {
login: async (event) => {
// TODO log the user in
},
register: async (event) => {
// TODO register the user
}
};
```
To invoke a named action, add a query parameter with the name prefixed by a `/`
character:
```svelte
<!file: src/routes/login/+page.svelte>
<form method="POST" action="?/register">
```
```svelte
<!file: src/routes/+layout.svelte>
<form method="POST" action="/login?/register">
```
```svelte
/// file: src/routes/login/+page.svelte
<form method="POST"action="?/login">
<label>
Email
<input name="email" type="email">
</label>
<label>
Password
<input name="password" type="password">
</label>
<button>Log in</button>
<button formaction="?/register">Register</button>
</form>
```
## Anatomy of an action
Each action receives a `RequestEvent` object, allowing you to read the data with
`request.formData()`. After processing the request (for example, logging the user
in by setting a cookie), the action can respond with data that will be available
through the `form` property on the corresponding page and through `page.form` app-
wide until the next update.
```js
/// file: src/routes/login/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/db';
// @filename: index.js
//cut
import * as db from '$lib/server/db';
```svelte
<!file: src/routes/login/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data, form } = $props();
</script>
{#if form?.success}
<!-- this message is ephemeral; it exists because the page was rendered in
response to a form submission. it will vanish if the user reloads -->
<p>Successfully logged in! Welcome back, {data.user.name}</p>
{/if}
```
> [!LEGACY]
> `PageProps` was added in 2.16.0. In earlier versions, you had to type the `data`
and `form` properties individually:
> ```js
> /// file: +page.svelte
> /** @type {{ data: import('./$types').PageData, form:
import('./$types').ActionData }} */
> let { data, form } = $props();
> ```
>
> In Svelte 4, you'd use `export let data` and `export let form` instead to declare
properties.
If the request couldn't be processed because of invalid data, you can return
validation errors — along with the previously submitted form values — back to the
user so that they can try again. The `fail` function lets you return an HTTP status
code (typically 400 or 422, in the case of validation errors) along with the data.
The status code is available through `page.status` and the data through `form`:
```js
/// file: src/routes/login/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/db';
// @filename: index.js
//cut
import { fail } from '@sveltejs/kit';
import * as db from '$lib/server/db';
/** @satisfies {import('./$types').Actions} */
export const actions = {
login: async ({ cookies, request }) => {
const data = await request.formData();
const email = data.get('email');
const password = data.get('password');
if (!email) {
return fail(400, { email, missing: true });
}
```svelte
/// file: src/routes/login/+page.svelte
<form method="POST" action="?/login">
{#if form?.missing}<p class="error">The email field is required</p>{/if}
{#if form?.incorrect}<p class="error">Invalid credentials!</p>{/if}
<label>
Email
<input name="email" type="email"value={form?.email ?? ''}>
</label>
<label>
Password
<input name="password" type="password">
</label>
<button>Log in</button>
<button formaction="?/register">Register</button>
</form>
```
The returned data must be serializable as JSON. Beyond that, the structure is
entirely up to you. For example, if you had multiple forms on the page, you could
distinguish which `<form>` the returned `form` data referred to with an `id`
property or similar.
### Redirects
```js
// @errors: 2345
/// file: src/routes/login/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/db';
// @filename: index.js
//cut
import { fail,redirect} from '@sveltejs/kit';
import * as db from '$lib/server/db';
if (url.searchParams.has('redirectTo')) {
redirect(303, url.searchParams.get('redirectTo'));
}
## Loading data
Note that `handle` runs before the action is invoked, and does not rerun before the
`load` functions. This means that if, for example, you use `handle` to populate
`event.locals` based on a cookie, you must update `event.locals` when you set or
delete the cookie in an action:
```js
/// file: src/hooks.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user: {
name: string;
} | null
}
}
// @filename: global.d.ts
declare global {
function getUser(sessionid: string | undefined): {
name: string;
};
}
export {};
// @filename: index.js
//cut
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
event.locals.user = await getUser(event.cookies.get('sessionid'));
return resolve(event);
}
```
```js
/// file: src/routes/account/+page.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user: {
name: string;
} | null
}
}
// @filename: index.js
//cut
/** @type {import('./$types').PageServerLoad} */
export function load(event) {
return {
user: event.locals.user
};
}
## Progressive enhancement
In the preceding sections we built a `/login` action that [works without client-
side JavaScript](https://kryogenix.org/code/browser/everyonehasjs.html) — not a
`fetch` in sight. That's great, but when JavaScript _is_ available we can
progressively enhance our form interactions to provide a better user experience.
### use:enhance
The easiest way to progressively enhance a form is to add the `use:enhance` action:
```svelte
/// file: src/routes/login/+page.svelte
<script>
import { enhance } from '$app/forms';
<form method="POST"use:enhance>
```
```svelte
<form
method="POST"
use:enhance={({ formElement, formData, action, cancel, submitter }) => {
// `formElement` is this `<form>` element
// `formData` is its `FormData` object that's about to be submitted
// `action` is the URL to which the form is posted
// calling `cancel()` will prevent the submission
// `submitter` is the `HTMLElement` that caused the form to be
submitted
You can use these functions to show and hide loading UI, and so on.
If you return a callback, you may need to reproduce part of the default
`use:enhance` behaviour, but without invalidating all data on a successful
response. You can do so with `applyAction`:
```svelte
/// file: src/routes/login/+page.svelte
<script>
import { enhance,applyAction} from '$app/forms';
<form
method="POST"
use:enhance={({ formElement, formData, action, cancel }) => {
return async ({ result }) => {
// `result` is an `ActionResult` object
if (result.type === 'redirect') {
goto(result.location);
} else {
await applyAction(result);
}
};
}}
>
```
```svelte
<!file: src/routes/login/+page.svelte>
<script>
import { invalidateAll, goto } from '$app/navigation';
import { applyAction, deserialize } from '$app/forms';
applyAction(result);
}
</script>
Note that you need to `deserialize` the response before processing it further using
the corresponding method from `$app/forms`. `JSON.parse()` isn't enough because
form actions - like `load` functions - also support returning `Date` or `BigInt`
objects.
```js
const response = await fetch(this.action, {
method: 'POST',
body: data,
headers: {
'x-sveltekit-action': 'true'
}
});
```
## Alternatives
Form actions are the preferred way to send data to the server, since they can be
progressively enhanced, but you can also use [`+server.js`](routing#server) files
to expose (for example) a JSON API. Here's how such an interaction could look like:
```svelte
<!file: src/routes/send-message/+page.svelte>
<script>
function rerun() {
fetch('/api/ci', {
method: 'POST'
});
}
</script>
## GET vs POST
Some forms don't need to `POST` data to the server — search inputs, for example.
For these you can use `method="GET"` (or, equivalently, no `method` at all), and
SvelteKit will treat them like `<a>` elements, using the client-side router instead
of a full page navigation:
```html
<form action="/search">
<label>
Search
<input name="q">
</label>
</form>
```
Submitting this form will navigate to `/search?q=...` and invoke your load function
but will not invoke an action. As with `<a>` elements, you can set the [`data-
sveltekit-reload`](link-options#data-sveltekit-reload), [`data-sveltekit-
replacestate`](link-options#data-sveltekit-replacestate), [`data-sveltekit-
keepfocus`](link-options#data-sveltekit-keepfocus) and [`data-sveltekit-noscroll`]
(link-options#data-sveltekit-noscroll) attributes on the `<form>` to control the
router's behaviour.
## Further reading
- [Tutorial: Forms](/tutorial/kit/the-form-element)
## docs/kit/20-core-concepts/40-page-options.md
---
You can control each of these on a page-by-page basis by exporting options from
[`+page.js`](routing#page-page.js) or [`+page.server.js`](routing#page-
page.server.js), or for groups of pages using a shared [`+layout.js`]
(routing#layout-layout.js) or [`+layout.server.js`](routing#layout-
layout.server.js). To define an option for the whole app, export it from the root
layout. Child layouts and pages override values set in parent layouts, so — for
example — you can enable prerendering for your entire app then disable it for pages
that need to be dynamically rendered.
You can mix and match these options in different areas of your app. For example,
you could prerender your marketing page for maximum speed, server-render your
dynamic pages for SEO and accessibility and turn your admin section into an SPA by
rendering it on the client only. This makes SvelteKit very versatile.
## prerender
It's likely that at least some routes of your app can be represented as a simple
HTML file generated at build time. These routes can be [_prerendered_]
(glossary#Prerendering).
```js
/// file: +page.js/+page.server.js/+server.js
export const prerender = true;
```
Alternatively, you can set `export const prerender = true` in your root
`+layout.js` or `+layout.server.js` and prerender everything except pages that are
explicitly marked as _not_ prerenderable:
```js
/// file: +page.js/+page.server.js/+server.js
export const prerender = false;
```
Routes with `prerender = true` will be excluded from manifests used for dynamic
SSR, making your server (or serverless/edge functions) smaller. In some cases you
might want to prerender a route but also include it in the manifest (for example,
with a route like `/blog/[slug]` where you want to prerender your most
recent/popular content but server-render the long tail) — for these cases, there's
a third option, 'auto':
```js
/// file: +page.js/+page.server.js/+server.js
export const prerender = 'auto';
```
The prerenderer will start at the root of your app and generate files for any
prerenderable pages or `+server.js` routes it finds. Each page is scanned for `<a>`
elements that point to other pages that are candidates for prerendering — because
of this, you generally don't need to specify which pages should be accessed. If you
_do_ need to specify which pages should be accessed by the prerenderer, you can do
so with [`config.kit.prerender.entries`](configuration#prerender), or by exporting
an [`entries`](#entries) function from your dynamic route.
Unlike the other page options, `prerender` also applies to `+server.js` files.
These files are _not_ affected by layouts, but will inherit default values from the
pages that fetch data from them, if any. For example if a `+page.js` contains this
`load` function...
```js
/// file: +page.js
export const prerender = true;
The basic rule is this: for a page to be prerenderable, any two users hitting it
directly must get the same content from the server.
Note that you can still prerender pages that load data based on the page's
parameters, such as a `src/routes/blog/[slug]/+page.svelte` route.
For that reason among others, it's recommended that you always include a file
extension — `src/routes/foo.json/+server.js` and
`src/routes/foo/bar.json/+server.js` would result in `foo.json` and `foo/bar.json`
files living harmoniously side-by-side.
### Troubleshooting
If you encounter an error like 'The following routes were marked as prerenderable,
but were not prerendered' it's because the route in question (or a parent layout,
if it's a page) has `export const prerender = true` but the page wasn't reached by
the prerendering crawler and thus wasn't prerendered.
Since these routes cannot be dynamically server-rendered, this will cause errors
when people try to access the route in question. There are a few ways to fix it:
* Ensure that SvelteKit can find the route by following links from
[`config.kit.prerender.entries`](configuration#prerender) or the [`entries`]
(#entries) page option. Add links to dynamic routes (i.e. pages with `[parameters]`
) to this option if they are not found through crawling the other entry points,
else they are not prerendered because SvelteKit doesn't know what value the
parameters should have. Pages not marked as prerenderable will be ignored and their
links to other pages will not be crawled, even if some of them would be
prerenderable.
* Ensure that SvelteKit can find the route by discovering a link to it from one of
your other prerendered pages that have server-side rendering enabled.
* Change `export const prerender = true` to `export const prerender = 'auto'`.
Routes with `'auto'` can be dynamically server rendered
## entries
```bash
/ # non-dynamic
/blog # non-dynamic
/blog/[slug] # dynamic, because of `[slug]`
```
...SvelteKit will prerender `/` and `/blog`, and in the process discover links like
`<a href="/blog/hello-world">` which give it new pages to prerender.
Most of the time, that's enough. In some situations, links to pages like
`/blog/hello-world` might not exist (or might not exist on prerendered pages), in
which case we need to tell SvelteKit about their existence.
```js
/// file: src/routes/blog/[slug]/+page.server.js
/** @type {import('./$types').EntryGenerator} */
export function entries() {
return [
{ slug: 'hello-world' },
{ slug: 'another-blog-post' }
];
}
`entries` can be an `async` function, allowing you to (for example) retrieve a list
of posts from a CMS or database, in the example above.
## ssr
Normally, SvelteKit renders your page on the server first and sends that HTML to
the client where it's [hydrated](glossary#Hydration). If you set `ssr` to `false`,
it renders an empty 'shell' page instead. This is useful if your page is unable to
be rendered on the server (because you use browser-only globals like `document` for
example), but in most situations it's not recommended ([see appendix]
(glossary#SSR)).
```js
/// file: +page.js
export const ssr = false;
// If both `ssr` and `csr` are `false`, nothing will be rendered!
```
If you add `export const ssr = false` to your root `+layout.js`, your entire app
will only be rendered on the client — which essentially means you turn your app
into an SPA.
## csr
```js
/// file: +page.js
export const csr = false;
// If both `csr` and `ssr` are `false`, nothing will be rendered!
```
Disabling CSR does not ship any JavaScript to the client. This means:
You can enable `csr` during development (for example to take advantage of HMR) like
so:
```js
/// file: +page.js
import { dev } from '$app/environment';
## trailingSlash
By default, SvelteKit will remove trailing slashes from URLs — if you visit
`/about/`, it will respond with a redirect to `/about`. You can change this
behaviour with the `trailingSlash` option, which can be one of `'never'` (the
default), `'always'`, or `'ignore'`.
As with other page options, you can export this value from a `+layout.js` or a
`+layout.server.js` and it will apply to all child pages. You can also export the
configuration from `+server.js` files.
```js
/// file: src/routes/+layout.js
export const trailingSlash = 'always';
```
## config
`config` is an object with key-value pairs at the top level. Beyond that, the
concrete shape is dependent on the adapter you're using. Every adapter should
provide a `Config` interface to import for type safety. Consult the documentation
of your adapter for more information.
```js
// @filename: ambient.d.ts
declare module 'some-adapter' {
export interface Config { runtime: string }
}
// @filename: index.js
//cut
/// file: src/routes/+page.js
/** @type {import('some-adapter').Config} */
export const config = {
runtime: 'edge'
};
```
`config` objects are merged at the top level (but _not_ deeper levels). This means
you don't need to repeat all the values in a `+page.js` if you want to only
override some of the values in the upper `+layout.js`. For example this layout
configuration...
```js
/// file: src/routes/+layout.js
export const config = {
runtime: 'edge',
regions: 'all',
foo: {
bar: true
}
}
```
```js
/// file: src/routes/+page.js
export const config = {
regions: ['us1', 'us2'],
foo: {
baz: true
}
}
```
...which results in the config value `{ runtime: 'edge', regions: ['us1', 'us2'],
foo: { baz: true } }` for that page.
## Further reading
## docs/kit/20-core-concepts/50-state-management.md
---
If you're used to building client-only apps, state management in an app that spans
server and client might seem intimidating. This section provides tips for avoiding
some common gotchas.
Browsers are _stateful_ — state is stored in memory as the user interacts with the
application. Servers, on the other hand, are _stateless_ — the content of the
response is determined entirely by the content of the request.
Conceptually, that is. In reality, servers are often long-lived and shared by
multiple users. For that reason it's important not to store data in shared
variables. For example, consider this code:
```js
// @errors: 7034 7005
/// file: +page.server.js
let user;
// NEVER DO THIS!
user = {
name: data.get('name'),
embarrassingSecret: data.get('secret')
};
}
}
```
The `user` variable is shared by everyone who connects to this server. If Alice
submitted an embarrassing secret, and Bob visited the page after her, Bob would
know Alice's secret. In addition, when Alice returns to the site later in the day,
the server may have restarted, losing her data.
For the same reason, your `load` functions should be _pure_ — no side-effects
(except maybe the occasional `console.log(...)`). For example, you might be tempted
to write to a store or global state inside a `load` function so that you can use
the value in your components:
```js
/// file: +page.js
// @filename: ambient.d.ts
declare module '$lib/user' {
export const user: { set: (value: any) => void };
}
// @filename: index.js
//cut
import { user } from '$lib/user';
// NEVER DO THIS!
user.set(await response.json());
}
```
As with the previous example, this puts one user's information in a place that is
shared by _all_ users. Instead, just return the data...
```js
/// file: +page.js
/** @type {import('./$types').PageServerLoad} */
export async function load({ fetch }) {
const response = await fetch('/api/user');
return {
user: await response.json()
};
}
```
...and pass it around to the components that need it, or use [`page.data`]
(load#page.data).
If you're not using SSR, then there's no risk of accidentally exposing one user's
data to another. But you should still avoid side-effects in your `load` functions —
your application will be much easier to reason about without them.
You might wonder how we're able to use `page.data` and other [app state]($app-
state) (or [app stores]($app-stores)) if we can't use global state. The answer is
that app state and app stores on the server use Svelte's [context
API](/tutorial/svelte/context-api) — the state (or store) is attached to the
component tree with `setContext`, and when you subscribe you retrieve it with
`getContext`. We can do the same thing with our own state:
```svelte
<!file: src/routes/+layout.svelte>
<script>
import { setContext } from 'svelte';
```svelte
<!file: src/routes/user/+page.svelte>
<script>
import { getContext } from 'svelte';
<p>Welcome {user().name}</p>
```
> [!LEGACY]
> You also use stores from `svelte/store` for this, but when using Svelte 5 it is
recommended to make use of universal reactivity instead.
If you're not using SSR (and can guarantee that you won't need to use SSR in
future) then you can safely keep state in a shared module, without using the
context API.
When you navigate around your application, SvelteKit reuses existing layout and
page components. For example, if you have a route like this...
```svelte
<!file: src/routes/blog/[slug]/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
<div>{@html data.content}</div>
```
```svelte
/// file: src/routes/blog/[slug]/+page.svelte
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
Reusing components like this means that things like sidebar scroll state are
preserved, and you can easily animate between changing values. In the case that you
do need to completely destroy and remount a component on navigation, you can use
this pattern:
```svelte
<script>
import { page } from '$app/state';
</script>
{#key page.url.pathname}
<BlogPost title={data.title} content={data.title} />
{/key}
```
If you have state that should survive a reload and/or affect SSR, such as filters
or sorting rules on a table, URL search parameters (like `?
sort=price&order=ascending`) are a good place to put them. You can put them in `<a
href="...">` or `<form action="...">` attributes, or set them programmatically via
`goto('?key=value')`. They can be accessed inside `load` functions via the `url`
parameter, and inside components via `page.url.searchParams`.
Some UI state, such as 'is the accordion open?', is disposable — if the user
navigates away or refreshes the page, it doesn't matter if the state is lost. In
some cases, you _do_ want the data to persist if the user navigates to a different
page and comes back, but storing the state in the URL or in a database would be
overkill. For this, SvelteKit provides [snapshots](snapshots), which let you
associate component state with a history entry.
## docs/kit/25-build-and-deploy/index.md
---
## docs/kit/25-build-and-deploy/10-building-your-app.md
---
Building a SvelteKit app happens in two stages, which both happen when you run
`vite build` (usually via `npm run build`).
Firstly, Vite creates an optimized production build of your server code, your
browser code, and your service worker (if you have one). [Prerendering](page-
options#prerender) is executed at this stage, if appropriate.
Secondly, an _adapter_ takes this production build and tunes it for your target
environment — more on this on the following pages.
SvelteKit will load your `+page/layout(.server).js` files (and all files they
import) for analysis during the build. Any code that should _not_ be executed at
this stage must check that `building` from [`$app/environment`]($app-environment)
is `false`:
```js
import { building } from '$app/environment';
import { setupMyDatabase } from '$lib/server/database';
if (!building) {
setupMyDatabase();
}
After building, you can view your production build locally with `vite preview` (via
`npm run preview`). Note that this will run the app in Node, and so is not a
perfect reproduction of your deployed app — adapter-specific adjustments like the
[`platform` object](adapters#Platform-specific-context) do not apply to previews.
## docs/kit/25-build-and-deploy/20-adapters.md
---
title: Adapters
---
Before you can deploy your SvelteKit app, you need to _adapt_ it for your
deployment target. Adapters are small plugins that take the built app as input and
generate output for deployment.
Official adapters exist for a variety of platforms — these are documented on the
following pages:
## Using adapters
```js
/// file: svelte.config.js
// @filename: ambient.d.ts
declare module 'svelte-adapter-foo' {
const adapter: (opts: any) => import('@sveltejs/kit').Adapter;
export default adapter;
}
// @filename: index.js
//cut
import adapter from 'svelte-adapter-foo';
## Platform-specific context
Some adapters may have access to additional information about the request. For
example, Cloudflare Workers can access an `env` object containing KV namespaces
etc. This can be passed to the `RequestEvent` used in [hooks](hooks) and [server
routes](routing#server) as the `platform` property — consult each adapter's
documentation to learn more.
## docs/kit/25-build-and-deploy/30-adapter-auto.md
---
title: Zero-config deployments
---
When you create a new SvelteKit project with `npx sv create`, it installs
[`adapter-auto`](https://github.com/sveltejs/kit/tree/main/packages/adapter-auto)
by default. This adapter automatically installs and uses the correct adapter for
supported environments when you deploy:
## Environment-specific configuration
You can add zero-config support for additional adapters by editing [adapters.js]
(https://github.com/sveltejs/kit/blob/main/packages/adapter-auto/adapters.js) and
opening a pull request.
## docs/kit/25-build-and-deploy/40-adapter-node.md
---
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter()
}
};
```
## Deploying
First, build your app with `npm run build`. This will create the production server
in the output directory specified in the adapter options, defaulting to `build`.
You will need the output directory, the project's `package.json`, and the
production dependencies in `node_modules` to run the application. Production
dependencies can be generated by copying the `package.json` and `package-lock.json`
and then running `npm ci --omit dev` (you can skip this step if your app doesn't
have any dependencies). You can then start your app with this command:
```bash
node build
```
You will typically want to compress responses coming from the server. If you are
already deploying your server behind a reverse proxy for SSL or load balancing, it
typically results in better performance to also handle compression at that layer
since Node.js is single-threaded.
## Environment variables
In `dev` and `preview`, SvelteKit will read environment variables from your `.env`
file (or `.env.local`, or `.env.[mode]`, [as determined by
Vite](https://vitejs.dev/guide/env-and-mode.html#env-files).)
```bash
npm install dotenv
```
```bash
node-r dotenv/configbuild
```
```bash
node--env-file=.envbuild
```
By default, the server will accept connections on `0.0.0.0` using port 3000. These
can be customised with the `PORT` and `HOST` environment variables:
```
HOST=127.0.0.1 PORT=4000 node build
```
```
SOCKET_PATH=/tmp/socket node build
```
HTTP doesn't give SvelteKit a reliable way to know the URL that is currently being
requested. The simplest way to tell SvelteKit where the app is being served is to
set the `ORIGIN` environment variable:
```
ORIGIN=https://my.site node build
With this, a request for the `/stuff` pathname will correctly resolve to
`https://my.site/stuff`. Alternatively, you can specify headers that tell SvelteKit
about the request protocol and host, from which it can construct the origin URL:
```
PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build
```
>
> If you're hosting your proxy on a non-standard port and your reverse proxy
supports `x-forwarded-port`, you can also set `PORT_HEADER=x-forwarded-port`.
If `adapter-node` can't correctly determine the URL of your deployment, you may
experience this error when using [form actions](form-actions):
```
ADDRESS_HEADER=True-Client-IP node build
```
```
<client address>, <proxy 1 address>, <proxy 2 address>
```
Some guides will tell you to read the left-most address, but this leaves you
[vulnerable to spoofing](https://adam-p.ca/blog/2022/03/x-forwarded-for/):
```
<spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>
```
We instead read from the _right_, accounting for the number of trusted proxies. In
this case, we would use `XFF_DEPTH=3`.
### `BODY_SIZE_LIMIT`
The maximum request body size to accept in bytes including while streaming. The
body size can also be specified with a unit suffix for kilobytes (`K`), megabytes
(`M`), or gigabytes (`G`). For example, `512K` or `1M`. Defaults to 512kb. You can
disable this option with a value of `Infinity` (0 in older versions of the adapter)
and implement a custom check in [`handle`](hooks#Server-hooks-handle) if you need
something more advanced.
### `SHUTDOWN_TIMEOUT`
The number of seconds to wait before forcefully closing any remaining connections
after receiving a `SIGTERM` or `SIGINT` signal. Defaults to `30`. Internally the
adapter calls
[`closeAllConnections`](https://nodejs.org/api/http.html#servercloseallconnections)
. See [Graceful shutdown](#Graceful-shutdown) for more details.
### `IDLE_TIMEOUT`
## Options
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter({
// default options are shown
out: 'build',
precompress: true,
envPrefix: ''
})
}
};
```
### out
The directory to build the server to. It defaults to `build` — i.e. `node build`
would start the server locally after it has been created.
### precompress
Enables precompressing using gzip and brotli for assets and prerendered pages. It
defaults to `true`.
### envPrefix
If you need to change the name of the environment variables used to configure the
deployment (for example, to deconflict with environment variables you don't
control), you can specify a prefix:
```js
envPrefix: 'MY_CUSTOM_';
```
```sh
MY_CUSTOM_HOST=127.0.0.1 \
MY_CUSTOM_PORT=4000 \
MY_CUSTOM_ORIGIN=https://my.site \
node build
```
## Graceful shutdown
By default `adapter-node` gracefully shuts down the HTTP server when a `SIGTERM` or
`SIGINT` signal is received. It will:
You can listen to the `sveltekit:shutdown` event which is emitted after the HTTP
server has closed all connections. Unlike Node's `exit` event, the
`sveltekit:shutdown` event supports asynchronous operations and is always emitted
when all connections are closed even if the server has dangling work such as open
database connections.
```js
// @errors: 2304
process.on('sveltekit:shutdown', async (reason) => {
await jobs.stop();
await db.close();
});
```
## Socket activation
Most Linux operating systems today use a modern process manager called systemd to
start the server and run and manage services. You can configure your server to
allocate a socket and start and scale your app on demand. This is called [socket
activation](http://0pointer.de/blog/projects/socket-activated-containers.html). In
this case, the OS will pass two environment variables to your app — `LISTEN_PID`
and `LISTEN_FDS`. The adapter will then listen on file descriptor 3 which refers to
a systemd socket unit that you will have to create.
```ini
/// file: /etc/systemd/system/myapp.service
[Service]
Environment=NODE_ENV=production IDLE_TIMEOUT=60
ExecStart=/usr/bin/node /usr/bin/myapp/build
```
```ini
/// file: /etc/systemd/system/myapp.socket
[Socket]
ListenStream=3000
[Install]
WantedBy=sockets.target
```
3. Make sure systemd has recognised both units by running `sudo systemctl daemon-
reload`. Then enable the socket on boot and start it immediately using `sudo
systemctl enable --now myapp.socket`. The app will then automatically start once
the first request is made to `localhost:3000`.
## Custom server
The adapter creates two files in your build directory — `index.js` and
`handler.js`. Running `index.js` — e.g. `node build`, if you use the default build
directory — will start a server on the configured port.
Alternatively, you can import the `handler.js` file, which exports a handler
suitable for use with [Express](https://github.com/expressjs/express), [Connect]
(https://github.com/senchalabs/connect) or [Polka](https://github.com/lukeed/polka)
(or even just the built-in
[`http.createServer`](https://nodejs.org/dist/latest/docs/api/http.html#httpcreates
erveroptions-requestlistener)) and set up your own server:
```js
// @errors: 2307 7006
/// file: my-server.js
import { handler } from './build/handler.js';
import express from 'express';
// let SvelteKit handle everything else, including serving prerendered pages and
static assets
app.use(handler);
app.listen(3000, () => {
console.log('listening on port 3000');
});
```
## docs/kit/25-build-and-deploy/50-adapter-static.md
---
This will prerender your entire site as a collection of static files. If you'd like
to prerender only some pages and dynamically server-render others, you will need to
use a different adapter together with [the `prerender` option](page-
options#prerender).
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
// default options are shown. On some platforms
// these options are set automatically — see below
pages: 'build',
assets: 'build',
fallback: undefined,
precompress: false,
strict: true
})
}
};
```
```js
/// file: src/routes/+layout.js
// This can be false if you're using a fallback (i.e. SPA mode)
export const prerender = true;
```
## Zero-config support
- [Vercel](https://vercel.com)
On these platforms, you should omit the adapter options so that `adapter-static`
can provide the optimal configuration:
```js
// @errors: 2304
/// file: svelte.config.js
export default {
kit: {
adapter: adapter({...})
}
};
```
## Options
### pages
The directory to write static assets (the contents of `static`, plus client-side JS
and CSS generated by SvelteKit) to. Ordinarily this should be the same as `pages`,
and it will default to whatever the value of `pages` is, but in rare circumstances
you might need to output pages and assets to separate locations.
### fallback
### precompress
If `true`, precompresses files with brotli and gzip. This will generate `.br` and
`.gz` files.
### strict
By default, `adapter-static` checks that either all pages and endpoints (if any) of
your app were prerendered, or you have the `fallback` option set. This check exists
to prevent you from accidentally publishing an app where some parts of it are not
accessible, because they are not contained in the final output. If you know this is
ok (for example when a certain page only exists conditionally), you can set
`strict` to `false` to turn off this check.
## GitHub Pages
You'll also want to generate a fallback `404.html` page to replace the default 404
page shown by GitHub Pages.
```js
// @errors: 2307 2322
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-static';
```yaml
### file: .github/workflows/deploy.yml
name: Deploy to GitHub Pages
on:
push:
branches: 'main'
jobs:
build_site:
runs-on: ubuntu-latest
steps:
name: Checkout
uses: actions/checkout@v4
# If you're using pnpm, add this step then change the commands and cache key
below to use `pnpm`
# - name: Install pnpm
# uses: pnpm/action-setup@v3
# with:
# version: 8
name: build
env:
BASE_PATH: '/${{ github.event.repository.name }}'
run: |
npm run build
deploy:
needs: build_site
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
name: Deploy
id: deployment
uses: actions/deploy-pages@v4
```
If you're not using GitHub actions to deploy your site (for example, you're pushing
the built site to its own repo), add an empty `.nojekyll` file in your `static`
directory to prevent Jekyll from interfering.
## docs/kit/25-build-and-deploy/55-single-page-apps.md
---
You can turn any SvelteKit app, using any adapter, into a fully client-rendered
single-page app (SPA) by disabling SSR at the root layout:
```js
/// file: src/routes/+layout.js
export const ssr = false;
```
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
fallback: '200.html' // may differ from host to host
})
}
};
```
The `fallback` page is an HTML page created by SvelteKit from your page template
(e.g. `app.html`) that loads your app and navigates to the correct route. For
example [Surge](https://surge.sh/help/adding-a-200-page-for-client-side-routing), a
static web host, lets you add a `200.html` file that will handle any requests that
don't correspond to static assets or prerendered pages.
```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^200\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /200.html [L]
</IfModule>
```
If you want certain pages to be prerendered, you can re-enable `ssr` alongside
`prerender` for just those parts of your app:
```js
/// file: src/routes/my-prerendered-page/+page.js
export const prerender = true;
export const ssr = true;
```
## docs/kit/25-build-and-deploy/60-adapter-cloudflare.md
---
## Comparisons
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-cloudflare';
export default {
kit: {
adapter: adapter({
// See below for an explanation of these options
routes: {
include: ['/*'],
exclude: ['<all>']
},
platformProxy: {
configPath: undefined,
environment: undefined,
persist: undefined
}
})
}
};
```
## Options
### routes
- `include` defines routes that will invoke a function, and defaults to `['/*']`
- `exclude` defines routes that will _not_ invoke a function — this is a faster and
cheaper way to serve your app's static assets. This array can include the following
special values:
- `<build>` contains your app's build artifacts (the files generated by Vite)
- `<files>` contains the contents of your `static` directory
- `<prerendered>` contains a list of prerendered pages
- `<all>` (the default) contains all of the above
You can have up to 100 `include` and `exclude` rules combined. Generally you can
omit the `routes` options, but if (for example) your `<prerendered>` paths exceed
that limit, you may find it helpful to manually create an `exclude` list that
includes `'/articles/*'` instead of the auto-generated `['/articles/foo',
'/articles/bar', '/articles/baz', ...]`.
### platformProxy
## Deployment
When configuring your project settings, you must use the following settings:
## Runtime APIs
The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-
event#parameters) object contains your project's
[bindings](https://developers.cloudflare.com/pages/functions/bindings/), which
consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform`
property, along with [`context`](https://developers.cloudflare.com/workers/runtime-
apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/
cache/), and
[`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/
#incomingrequestcfproperties), meaning that you can access it in hooks and
endpoints:
```js
// @errors: 7031
export async function POST({ request, platform }) {
const x = platform.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x');
}
```
```ts
/// file: src/app.d.ts
import { KVNamespace, DurableObjectNamespace } from '@cloudflare/workers-types';
declare global {
namespace App {
interface Platform {
env?: {
YOUR_KV_NAMESPACE: KVNamespace;
YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;
};
}
}
}
export {};
```
Cloudflare Workers specific values in the `platform` property are emulated during
dev and preview modes. Local
[bindings](https://developers.cloudflare.com/pages/functions/bindings/) are created
based on your [Wrangler configuration
file](https://developers.cloudflare.com/pages/functions/wrangler-configuration/
#local-development) and are used to populate `platform.env` during development and
preview. Use the adapter config [`platformProxy` option](#Options-platformProxy) to
change your preferences for the bindings.
## Notes
The [`_headers`](https://developers.cloudflare.com/pages/configuration/headers/)
and [`_redirects`](https://developers.cloudflare.com/pages/configuration/
redirects/) files specific to Cloudflare Pages can be used for static asset
responses (like images) by putting them into the project root folder.
## Troubleshooting
```jsonc
/// file: wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat"]
}
```
When deploying your application, the server generated by SvelteKit is bundled into
a single file. Wrangler will fail to publish your worker if it exceeds [the size
limits](https://developers.cloudflare.com/workers/platform/limits/#worker-size)
after minification. You're unlikely to hit this limit usually, but some large
libraries can cause this to happen. In that case, you can try to reduce the size of
your worker by only importing such libraries on the client side. See [the
FAQ](./faq#How-do-I-use-a-client-side-library-accessing-document-or-window) for
more information.
## docs/kit/25-build-and-deploy/70-adapter-cloudflare-workers.md
---
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-cloudflare-workers';
export default {
kit: {
adapter: adapter({
// see below for options that can be set here
})
}
};
```
## Options
### config
### platformProxy
## Basic Configuration
```jsonc
/// file: wrangler.jsonc
{
"name": "<your-service-name>",
"account_id": "<your-account-id>",
"main": "./.cloudflare/worker.js",
"site": {
"bucket": "./.cloudflare/public"
},
"build": {
"command": "npm run build"
},
"compatibility_date": "2021-11-12"
}
```
```
https://dash.cloudflare.com/<your-account-id>/home
```
```sh
npm i -D wrangler
wrangler login
```
```sh
wrangler deploy
```
## Runtime APIs
The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-
event#parameters) object contains your project's
[bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), which
consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform`
property, along with [`context`](https://developers.cloudflare.com/workers/runtime-
apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/
cache/), and
[`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/
#incomingrequestcfproperties), meaning that you can access it in hooks and
endpoints:
```js
// @errors: 7031
export async function POST({ request, platform }) {
const x = platform.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x');
}
```
```ts
/// file: src/app.d.ts
import { KVNamespace, DurableObjectNamespace } from '@cloudflare/workers-types';
declare global {
namespace App {
interface Platform {
env?: {
YOUR_KV_NAMESPACE: KVNamespace;
YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;
};
}
}
}
export {};
```
Cloudflare Workers specific values in the `platform` property are emulated during
dev and preview modes. Local
[bindings](https://developers.cloudflare.com/workers/wrangler/configuration/
#bindings) are created based on your [Wrangler configuration
file](https://developers.cloudflare.com/workers/wrangler/) and are used to populate
`platform.env` during development and preview. Use the adapter config
[`platformProxy` option](#Options-platformProxy) to change your preferences for the
bindings.
## Troubleshooting
```jsonc
/// file: wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat"]
}
```
When deploying your application, the server generated by SvelteKit is bundled into
a single file. Wrangler will fail to publish your worker if it exceeds [the size
limits](https://developers.cloudflare.com/workers/platform/limits/#worker-size)
after minification. You're unlikely to hit this limit usually, but some large
libraries can cause this to happen. In that case, you can try to reduce the size of
your worker by only importing such libraries on the client side. See [the
FAQ](./faq#How-do-I-use-a-client-side-library-accessing-document-or-window) for
more information.
## docs/kit/25-build-and-deploy/80-adapter-netlify.md
---
title: Netlify
---
## Usage
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-netlify';
export default {
kit: {
// default options are shown
adapter: adapter({
// if true, will create a Netlify Edge Function rather
// than using standard Node-based functions
edge: false,
```toml
[build]
command = "npm run build"
publish = "build"
```
New projects will use the current Node LTS version by default. However, if you're
upgrading a project you created a while ago it may be stuck on an older version.
See [the Netlify docs](https://docs.netlify.com/configure-builds/manage-
dependencies/#node-js-and-javascript) for details on manually specifying a current
Node version.
```js
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-netlify';
export default {
kit: {
adapter: adapter({
// will create a Netlify Edge Function using Deno-based
// rather than using standard Node-based functions
edge: true
})
}
};
```
You may build your app using functionality provided directly by SvelteKit without
relying on any Netlify functionality. Using the SvelteKit versions of these
features will allow them to be used in dev mode, tested with integration tests, and
to work with other adapters should you ever decide to switch away from Netlify.
However, in some scenarios you may find it beneficial to use the Netlify versions
of these features. One example would be if you're migrating an app that's already
hosted on Netlify to SvelteKit.
The [`_headers`](https://docs.netlify.com/routing/headers/#syntax-for-the-headers-
file) and [`_redirects`](https://docs.netlify.com/routing/redirects/redirect-
options/) files specific to Netlify can be used for static asset responses (like
images) by putting them into the project root folder.
```js
// @errors: 2705 7006
/// file: +page.server.js
export const load = async (event) => {
const context = event.platform.context;
console.log(context); // shows up in your functions log in the Netlify app
};
```
Additionally, you can add your own Netlify functions by creating a directory for
them and adding the configuration to your `netlify.toml` file. For example:
```toml
[build]
command = "npm run build"
publish = "build"
[functions]
directory = "functions"
```
## Troubleshooting
You _can_ use it in serverless deployments, but it won't work as expected, since
files are not copied from your project into your deployment. Instead, use the
[`read`]($app-server#read) function from `$app/server` to access your files. `read`
does not work inside edge deployments (this may change in future).
## docs/kit/25-build-and-deploy/90-adapter-vercel.md
---
title: Vercel
---
## Usage
```js
// @errors: 2307 2345
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-vercel';
export default {
kit: {
adapter: adapter({
// see below for options that can be set here
})
}
};
```
## Deployment configuration
To control how your routes are deployed to Vercel as functions, you can specify
deployment configuration, either through the option shown above or with [`export
const config`](page-options#config) inside `+server.js`, `+page(.server).js` and
`+layout(.server).js` files.
For example you could deploy some parts of your app as [Edge
Functions](https://vercel.com/docs/concepts/functions/edge-functions)...
```js
/// file: about/+page.js
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const config = {
runtime: 'edge'
};
```
...and others as [Serverless
Functions](https://vercel.com/docs/concepts/functions/serverless-functions) (note
that by specifying `config` inside a layout, it applies to all child pages):
```js
/// file: admin/+layout.js
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const config = {
runtime: 'nodejs22.x'
};
```
If your functions need to access data in a specific region, it's recommended that
they be deployed in the same region (or close to it) for optimal performance.
## Image Optimization
You may set the `images` config to control how Vercel builds your images. See the
[image configuration
reference](https://vercel.com/docs/build-output-api/v3/configuration#images) for
full details. As an example, you may set:
```js
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-vercel';
export default {
kit: {
adapter: adapter({
images: {
sizes: [640, 828, 1200, 1920, 3840],
formats: ['image/avif', 'image/webp'],
minimumCacheTTL: 300,
domains: ['example-app.vercel.app'],
}
})
}
};
```
> Use ISR only on routes where every visitor should see the same content (much like
when you prerender). If there's anything user-specific happening (like session
cookies), they should happen on the client via JavaScript only to not leak
sensitive information across visits
To add ISR to a route, include the `isr` property in your `config` object:
```js
// @errors: 2664
import { BYPASS_TOKEN } from '$env/static/private';
> Using ISR on a route with `export const prerender = true` will have no effect,
since the route is prerendered at build time
The `expiration` property is required; all others are optional. The properties are
discussed in more detail below.
### expiration
The expiration time (in seconds) before the cached asset will be re-generated by
invoking the Serverless Function. Setting the value to `false` means it will never
expire. In that case, you likely want to define a bypass token to re-generate on
demand.
### bypassToken
A random token that can be provided in the URL to bypass the cached version of the
asset, by requesting the asset with a `__prerender_bypass=<token>` cookie.
```js
crypto.randomUUID();
```
To get this key known about for local development, you can use the [Vercel CLI]
(https://vercel.com/docs/cli/env) by running the `vercel env pull` command locally
like so:
```sh
vercel env pull .env.development.local
```
### allowQuery
A list of valid query parameters that contribute to the cache key. Other parameters
(such as utm tracking codes) will be ignored, ensuring that they do not result in
content being re-generated unnecessarily. By default, query parameters are ignored.
## Environment variables
```js
// @errors: 2305
/// file: +layout.server.js
import { VERCEL_COMMIT_REF } from '$env/static/private';
```svelte
<!file: +layout.svelte>
<script>
/** @type {import('./$types').LayoutProps} */
let { data } = $props();
</script>
## Skew protection
When a new version of your app is deployed, assets belonging to the previous
version may no longer be accessible. If a user is actively using your app when this
happens, it can cause errors when they navigate — this is known as _version skew_.
SvelteKit mitigates this by detecting errors resulting from version skew and
causing a hard reload to get the latest version of the app, but this will cause any
client-side state to be lost. (You can also proactively mitigate it by observing
the [`updated`]($app-stores#updated) store value, which tells clients when a new
version has been deployed.)
Cookie-based skew protection comes with one caveat: if a user has multiple versions
of your app open in multiple tabs, requests from older versions will be routed to
the newer one, meaning they will fall back to SvelteKit's built-in skew protection.
## Notes
If you have Vercel functions contained in the `api` directory at the project's
root, any requests for `/api/*` will _not_ be handled by SvelteKit. You should
implement these as [API routes](routing#server) in your SvelteKit app instead,
unless you need to use a non-JavaScript language in which case you will need to
ensure that you don't have any `/api/*` routes in your SvelteKit app.
Projects created before a certain date may default to using an older Node version
than what SvelteKit currently requires. You can [change the Node version in your
project settings](https://vercel.com/docs/concepts/functions/serverless-functions/
runtimes/node-js#node.js-version).
## Troubleshooting
You _can_ use it in serverless functions, but it won't work as expected, since
files are not copied from your project into your deployment. Instead, use the
[`read`]($app-server#read) function from `$app/server` to access your files. `read`
does not work inside routes deployed as edge functions (this may change in future).
---
If an adapter for your preferred environment doesn't yet exist, you can build your
own. We recommend [looking at the source for an
adapter](https://github.com/sveltejs/kit/tree/main/packages) to a platform similar
to yours and copying it as a starting point.
```js
// @errors: 2322
// @filename: ambient.d.ts
type AdapterSpecificOptions = any;
// @filename: index.js
//cut
/** @param {AdapterSpecificOptions} options */
export default function (options) {
/** @type {import('@sveltejs/kit').Adapter} */
const adapter = {
name: 'adapter-package-name',
async adapt(builder) {
// adapter implementation
},
async emulate() {
return {
async platform({ config, prerender }) {
// the returned object becomes `event.platform`
during dev, build and
// preview. Its shape is that of `App.Platform`
}
}
},
supports: {
read: ({ config, route }) => {
// Return `true` if the route with the given `config` can
use `read`
// from `$app/server` in production, return `false` if it
can't.
// Or throw a descriptive error describing how to configure
the deployment
}
}
};
return adapter;
}
```
Of these, `name` and `adapt` are required. `emulate` and `supports` are optional.
Within the `adapt` method, there are a number of things that an adapter should do:
- Clear out the build directory
- Write SvelteKit output with `builder.writeClient`, `builder.writeServer`, and
`builder.writePrerendered`
- Output code that:
- Imports `Server` from `${builder.getServerDirectory()}/index.js`
- Instantiates the app with a manifest generated with
`builder.generateManifest({ relativePath })`
- Listens for requests from the platform, converts them to a standard
[Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) if necessary,
calls the `server.respond(request, { getClientAddress })` function to generate a
[Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) and responds
with it
- expose any platform-specific information to SvelteKit via the `platform`
option passed to `server.respond`
- Globally shims `fetch` to work on the target platform, if necessary.
SvelteKit provides a `@sveltejs/kit/node/polyfills` helper for platforms that can
use `undici`
- Bundle the output to avoid needing to install dependencies on the target
platform, if necessary
- Put the user's static files and the generated JS/CSS in the correct location for
the target platform
Where possible, we recommend putting the adapter output under the `build/`
directory with any intermediate output placed under `.svelte-kit/[adapter-name]`.
## docs/kit/30-advanced/index.md
---
title: Advanced
---
## docs/kit/30-advanced/10-advanced-routing.md
---
## Rest parameters
If the number of route segments is unknown, you can use rest syntax — for example
you might implement GitHub's file viewer like so...
```bash
/[org]/[repo]/tree/[branch]/[...file]
```
```js
// @noErrors
{
org: 'sveltejs',
repo: 'kit',
branch: 'main',
file: 'documentation/docs/04-advanced-routing.md'
}
```
Rest parameters also allow you to render custom 404s. Given these routes...
```tree
src/routes/
├ marx-brothers/
│ ├ chico/
│ ├ harpo/
│ ├ groucho/
│ └ +error.svelte
└ +error.svelte
```
```tree
src/routes/
├ marx-brothers/
| ├ [...path]/
│ ├ chico/
│ ├ harpo/
│ ├ groucho/
│ └ +error.svelte
└ +error.svelte
```
```js
/// file: src/routes/marx-brothers/[...path]/+page.js
import { error } from '@sveltejs/kit';
## Optional parameters
## Matching
```js
/// file: src/params/fruit.js
/**
* @param {string} param
* @return {param is ('apple' | 'orange')}
* @satisfies {import('@sveltejs/kit').ParamMatcher}
*/
export function match(param) {
return param === 'apple' || param === 'orange';
}
```
```
src/routes/fruits/[page=fruit]
```
If the pathname doesn't match, SvelteKit will try to match other routes (using the
sort order specified below), before eventually returning a 404.
Each module in the `params` directory corresponds to a matcher, with the exception
of `*.test.js` and `*.spec.js` files which may be used to unit test your matchers.
## Sorting
It's possible for multiple routes to match a given path. For example each of these
routes would match `/foo-abc`:
```bash
src/routes/[...catchall]/+page.svelte
src/routes/[[a=x]]/+page.svelte
src/routes/[b]/+page.svelte
src/routes/foo-[c]/+page.svelte
src/routes/foo-abc/+page.svelte
```
SvelteKit needs to know which route is being requested. To do so, it sorts them
according to the following rules...
- More specific routes are higher priority (e.g. a route with no parameters is more
specific than a route with one dynamic parameter, and so on)
- Parameters with [matchers](#Matching) (`[name=type]`) are higher priority than
those without (`[name]`)
- `[[optional]]` and `[...rest]` parameters are ignored unless they are the final
part of the route, in which case they are treated with lowest priority. In other
words `x/[[y]]/z` is treated equivalently to `x/z` for the purposes of sorting
- Ties are resolved alphabetically
## Encoding
Some characters can't be used on the filesystem — `/` on Linux and Mac, `\ / : * ?
" < > |` on Windows. The `#` and `%` characters have special meaning in URLs, and
the `[ ] ( )` characters have special meaning to SvelteKit, so these also can't be
used directly as part of your route.
To use these characters in your routes, you can use hexadecimal escape sequences,
which have the format `[x+nn]` where `nn` is a hexadecimal character code:
- `\` — `[x+5c]`
- `/` — `[x+2f]`
- `:` — `[x+3a]`
- `*` — `[x+2a]`
- `?` — `[x+3f]`
- `"` — `[x+22]`
- `<` — `[x+3c]`
- `>` — `[x+3e]`
- `|` — `[x+7c]`
- `#` — `[x+23]`
- `%` — `[x+25]`
- `[` — `[x+5b]`
- `]` — `[x+5d]`
- `(` — `[x+28]`
- `)` — `[x+29]`
You can determine the hexadecimal code for a character with JavaScript:
```js
':'.charCodeAt(0).toString(16); // '3a', hence '[x+3a]'
```
You can also use Unicode escape sequences. Generally you won't need to as you can
use the unencoded character directly, but if — for some reason — you can't have a
filename with an emoji in it, for example, then you can use the escaped characters.
In other words, these are equivalent:
```
src/routes/[u+d83e][u+dd2a]/+page.svelte
src/routes/🤪/+page.svelte
```
The format for a Unicode escape sequence is `[u+nnnn]` where `nnnn` is a valid
value between `0000` and `10ffff`. (Unlike JavaScript string escaping, there's no
need to use surrogate pairs to represent code points above `ffff`.) To learn more
about Unicode encodings, consult [Programming with
Unicode](https://unicodebook.readthedocs.io/unicode_encodings.html).
## Advanced layouts
By default, the _layout hierarchy_ mirrors the _route hierarchy_. In some cases,
that might not be what you want.
### (group)
Perhaps you have some routes that are 'app' routes that should have one layout
(e.g. `/dashboard` or `/item`), and others that are 'marketing' routes that should
have a different layout (`/about` or `/testimonials`). We can group these routes
with a directory whose name is wrapped in parentheses — unlike normal directories,
`(app)` and `(marketing)` do not affect the URL pathname of the routes inside them:
```tree
src/routes/
│ (app)/
│ ├ dashboard/
│ ├ item/
│ └ +layout.svelte
│ (marketing)/
│ ├ about/
│ ├ testimonials/
│ └ +layout.svelte
├ admin/
└ +layout.svelte
```
You can also put a `+page` directly inside a `(group)`, for example if `/` should
be an `(app)` or a `(marketing)` page.
The root layout applies to every page of your app — if omitted, it defaults to
`{@render children()}`. If you want some pages to have a different layout hierarchy
than the rest, then you can put your entire app inside one or more groups _except_
the routes that should not inherit the common layouts.
In the example above, the `/admin` route does not inherit either the `(app)` or
`(marketing)` layouts.
### +page@
Pages can break out of the current layout hierarchy on a route-by-route basis.
Suppose we have an `/item/[id]/embed` route inside the `(app)` group from the
previous example:
```tree
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page.svelte
│ │ │ └ +layout.svelte
│ │ └ +layout.svelte
│ └ +layout.svelte
└ +layout.svelte
```
Ordinarily, this would inherit the root layout, the `(app)` layout, the `item`
layout and the `[id]` layout. We can reset to one of those layouts by appending `@`
followed by the segment name — or, for the root layout, the empty string. In this
example, we can choose from the following options:
```tree
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page@(app).svelte
│ │ │ └ +layout.svelte
│ │ └ +layout.svelte
│ └ +layout.svelte
└ +layout.svelte
```
### +layout@
Like pages, layouts can _themselves_ break out of their parent layout hierarchy,
using the same technique. For example, a `+layout@.svelte` component would reset
the hierarchy for all its child routes.
```
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page.svelte // uses (app)/item/[id]/+layout.svelte
│ │ │ ├ +layout.svelte // inherits from (app)/item/+layout@.svelte
│ │ │ └ +page.svelte // uses (app)/item/+layout@.svelte
│ │ └ +layout@.svelte // inherits from root layout, skipping (app)/+layout.svelte
│ └ +layout.svelte
└ +layout.svelte
```
Not all use cases are suited for layout grouping, nor should you feel compelled to
use them. It might be that your use case would result in complex `(group)` nesting,
or that you don't want to introduce a `(group)` for a single outlier. It's
perfectly fine to use other means such as composition (reusable `load` functions or
Svelte components) or if-statements to achieve what you want. The following example
shows a layout that rewinds to the root layout and reuses components and functions
that other layouts can also use:
```svelte
<!file: src/routes/nested/route/+layout@.svelte>
<script>
import ReusableLayout from '$lib/ReusableLayout.svelte';
let { data, children } = $props();
</script>
<ReusableLayout {data}>
{@render children()}
</ReusableLayout>
```
```js
/// file: src/routes/nested/route/+layout.js
// @filename: ambient.d.ts
declare module "$lib/reusable-load-function" {
export function reusableLoad(event: import('@sveltejs/kit').LoadEvent):
Promise<Record<string, any>>;
}
// @filename: index.js
//cut
import { reusableLoad } from '$lib/reusable-load-function';
## Further reading
## docs/kit/30-advanced/20-hooks.md
---
title: Hooks
---
'Hooks' are app-wide functions you declare that SvelteKit will call in response to
specific events, giving you fine-grained control over the framework's behaviour.
Code in these modules will run when the application starts up, making them useful
for initializing database clients and so on.
## Server hooks
### handle
This function runs every time the SvelteKit server receives a [request](web-
standards#Fetch-APIs-Request) — whether that happens while the app is running, or
during [prerendering](page-options#prerender) — and determines the [response](web-
standards#Fetch-APIs-Response). It receives an `event` object representing the
request and a function called `resolve`, which renders the route and generates a
`Response`. This allows you to modify response headers or bodies, or bypass
SvelteKit entirely (for implementing routes programmatically, for example).
```js
/// file: src/hooks.server.js
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
if (event.url.pathname.startsWith('/custom')) {
return new Response('custom response');
}
During prerendering, SvelteKit crawls your pages for links and renders each route
it finds. Rendering the route invokes the `handle` function (and all other route
dependencies, like `load`). If you need to exclude some code from running during
this phase, check that the app is not [`building`]($app-environment#building)
beforehand.
### locals
To add custom data to the request, which is passed to handlers in `+server.js` and
server `load` functions, populate the `event.locals` object, as shown below.
```js
/// file: src/hooks.server.js
// @filename: ambient.d.ts
type User = {
name: string;
}
// @filename: index.js
//cut
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
event.locals.user = await getUserInformation(event.cookies.get('sessionid'));
return response;
}
```
You can define multiple `handle` functions and execute them with [the `sequence`
helper function](@sveltejs-kit-hooks).
`resolve` also supports a second, optional parameter that gives you more control
over how the response will be rendered. That parameter is an object that can have
the following fields:
```js
/// file: src/hooks.server.js
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
const response = await resolve(event, {
transformPageChunk: ({ html }) => html.replace('old', 'new'),
filterSerializedResponseHeaders: (name) => name.startsWith('x-'),
preload: ({ type, path }) => type === 'js' ||
path.includes('/important/')
});
return response;
}
```
Note that `resolve(...)` will never throw an error, it will always return a
`Promise<Response>` with the appropriate status code. If an error is thrown
elsewhere during `handle`, it is treated as fatal, and SvelteKit will respond with
a JSON representation of the error or a fallback error page — which can be
customised via `src/error.html` — depending on the `Accept` header. You can read
more about error handling [here](errors).
### handleFetch
This function allows you to modify (or replace) a `fetch` request that happens
inside a `load` or `action` function that runs on the server (or during pre-
rendering).
For example, your `load` function might make a request to a public URL like
`https://api.yourapp.com` when the user performs a client-side navigation to the
respective page, but during SSR it might make sense to hit the API directly
(bypassing whatever proxies and load balancers sit between it and the public
internet).
```js
/// file: src/hooks.server.js
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function handleFetch({ request, fetch }) {
if (request.url.startsWith('https://api.yourapp.com/')) {
// clone the original request, but change the URL
request = new Request(
request.url.replace('https://api.yourapp.com/',
'http://localhost:9999/'),
request
);
}
return fetch(request);
}
```
**Credentials**
For cross-origin requests, `cookie` will be included if the request URL belongs to
a subdomain of the app — for example if your app is on `my-domain.com`, and your
API is on `api.my-domain.com`, cookies will be included in the request.
If your app and your API are on sibling subdomains — `www.my-domain.com` and
`api.my-domain.com` for example — then a cookie belonging to a common parent domain
like `my-domain.com` will _not_ be included, because SvelteKit has no way to know
which domain the cookie belongs to. In these cases you will need to manually
include the cookie using `handleFetch`:
```js
/// file: src/hooks.server.js
// @errors: 2345
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function handleFetch({ event, request, fetch }) {
if (request.url.startsWith('https://api.my-domain.com/')) {
request.headers.set('cookie', event.request.headers.get('cookie'));
}
return fetch(request);
}
```
## Shared hooks
### handleError
If an [unexpected error](errors#Unexpected-errors) is thrown during loading or
rendering, this function will be called with the `error`, `event`, `status` code
and `message`. This allows for two things:
For errors thrown from your code (or library code called by your code) the status
will be 500 and the message will be "Internal Error". While `error.message` may
contain sensitive information that should not be exposed to users, `message` is
safe (albeit meaningless to the average user).
To add more information to the `$page.error` object in a type-safe way, you can
customize the expected shape by declaring an `App.Error` interface (which must
include `message: string`, to guarantee sensible fallback behavior). This allows
you to — for example — append a tracking ID for users to quote in correspondence
with your technical support staff:
```ts
/// file: src/app.d.ts
declare global {
namespace App {
interface Error {
message: string;
errorId: string;
}
}
}
export {};
```
```js
/// file: src/hooks.server.js
// @errors: 2322 2353
// @filename: ambient.d.ts
declare module '@sentry/sveltekit' {
export const init: (opts: any) => void;
export const captureException: (error: any, opts: any) => void;
}
// @filename: index.js
//cut
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
```js
/// file: src/hooks.client.js
// @errors: 2322 2353
// @filename: ambient.d.ts
declare module '@sentry/sveltekit' {
export const init: (opts: any) => void;
export const captureException: (error: any, opts: any) => void;
}
// @filename: index.js
//cut
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
return {
message: 'Whoops!',
errorId
};
}
```
This function is not called for _expected_ errors (those thrown with the [`error`]
(@sveltejs-kit#error) function imported from `@sveltejs/kit`).
### init
This function runs once, when the server is created or the app starts in the
browser, and is a useful place to do asynchronous work such as initializing a
database connection.
```js
/// file: src/hooks.server.js
import * as db from '$lib/server/database';
> In the browser, asynchronous work in `init` will delay hydration, so be mindful
of what you put in there.
## Universal hooks
The following can be added to `src/hooks.js`. Universal hooks run on both server
and client (not to be confused with shared hooks, which are environment-specific).
### reroute
This function runs before `handle` and allows you to change how URLs are translated
into routes. The returned pathname (which defaults to `url.pathname`) is used to
select the route and its parameters.
```js
/// file: src/hooks.js
// @errors: 2345
// @errors: 2304
The `lang` parameter will be correctly derived from the returned pathname.
Using `reroute` will _not_ change the contents of the browser's address bar, or the
value of `event.url`.
Since version 2.18, the `reroute` hook can be asynchronous, allowing it to (for
example) fetch data from your backend to decide where to reroute to. Use this
carefully and make sure it's fast, as it will delay navigation otherwise. If you
need to fetch data, use the `fetch` provided as an argument. It has the [same
benefits](load#Making-fetch-requests) as the `fetch` provided to `load` functions,
with the caveat that `params` and `id` are unavailable to [`handleFetch`](#Server-
hooks-handleFetch) because the route is not yet known.
```js
/// file: src/hooks.js
// @errors: 2345`
// @errors: 2304
### transport
```js
/// file: src/hooks.js
import { Vector } from '$lib/math';
## Further reading
- [Tutorial: Hooks](/tutorial/kit/handle)
## docs/kit/30-advanced/25-errors.md
---
title: Errors
---
## Error objects
SvelteKit distinguishes between expected and unexpected errors, both of which are
represented as simple `{ message: string }` objects by default.
You can add additional properties, like a `code` or a tracking `id`, as shown in
the examples below. (When using TypeScript this requires you to redefine the
`Error` type as described in [type safety](errors#Type-safety)).
## Expected errors
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content:
string } | undefined>
}
// @filename: index.js
//cut
import { error } from '@sveltejs/kit';
import * as db from '$lib/server/database';
if (!post) {
error(404, {
message: 'Not found'
});
}
return { post };
}
```
This throws an exception that SvelteKit catches, causing it to set the response
status code to 404 and render an [`+error.svelte`](routing#error) component, where
`page.error` is the object provided as the second argument to `error(...)`.
```svelte
<!file: src/routes/+error.svelte>
<script>
import { page } from '$app/state';
</script>
<h1>{page.error.message}</h1>
```
> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or
are using Svelte 4, use `$app/stores` instead.
```js
// @filename: ambient.d.ts
declare global {
namespace App {
interface Error {
message: string;
code: string;
}
}
}
export {}
// @filename: index.js
import { error } from '@sveltejs/kit';
//cut
error(404, {
message: 'Not found',
code: 'NOT_FOUND'
});
```
...otherwise, for convenience, you can pass a string as the second argument:
```js
import { error } from '@sveltejs/kit';
//cut
error(404, { message: 'Not found' });
error(404, 'Not found');
```
## Unexpected errors
An _unexpected_ error is any other exception that occurs while handling a request.
Since these can contain sensitive information, unexpected error messages and stack
traces are not exposed to users.
By default, unexpected errors are printed to the console (or, in production, your
server logs), while the error that is exposed to the user has a generic shape:
```json
{ "message": "Internal Error" }
```
## Responses
You can customise the fallback error page by adding a `src/error.html` file:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>%sveltekit.error.message%</title>
</head>
<body>
<h1>My custom error page</h1>
<p>Status: %sveltekit.status%</p>
<p>Message: %sveltekit.error.message%</p>
</body>
</html>
```
If the error instead occurs inside a `load` function while rendering a page,
SvelteKit will render the [`+error.svelte`](routing#error) component nearest to
where the error occurred. If the error occurs inside a `load` function in
`+layout(.server).js`, the closest error boundary in the tree is an `+error.svelte`
file _above_ that layout (not next to it).
The exception is when the error occurs inside the root `+layout.js` or
`+layout.server.js`, since the root layout would ordinarily _contain_ the
`+error.svelte` component. In this case, SvelteKit uses the fallback error page.
## Type safety
If you're using TypeScript and need to customize the shape of errors, you can do so
by declaring an `App.Error` interface in your app (by convention, in
`src/app.d.ts`, though it can live anywhere that TypeScript can 'see'):
```ts
/// file: src/app.d.ts
declare global {
namespace App {
interface Error {
code: string;
id: string;
}
}
}
export {};
```
## Further reading
## docs/kit/30-advanced/30-link-options.md
---
You can customise the behaviour of links with `data-sveltekit-*` attributes. These
can be applied to the `<a>` itself, or to a parent element.
## data-sveltekit-preload-data
Before the browser registers that the user has clicked on a link, we can detect
that they've hovered the mouse over it (on desktop) or that a `touchstart` or
`mousedown` event was triggered. In both cases, we can make an educated guess that
a `click` event is coming.
SvelteKit can use this information to get a head start on importing the code and
fetching the page's data, which can give us an extra couple of hundred milliseconds
— the difference between a user interface that feels laggy and one that feels
snappy.
- `"hover"` means that preloading will start if the mouse comes to a rest over a
link. On mobile, preloading begins on `touchstart`
- `"tap"` means that preloading will start as soon as a `touchstart` or `mousedown`
event is registered
```html
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
```
Sometimes, calling `load` when the user hovers over a link might be undesirable,
either because it's likely to result in false positives (a click needn't follow a
hover) or because data is updating very quickly and a delay could mean staleness.
In these cases, you can specify the `"tap"` value, which causes SvelteKit to call
`load` only when the user taps or clicks on a link:
```html
<a data-sveltekit-preload-data="tap" href="/stonks">
Get current stonk values
</a>
```
Data will never be preloaded if the user has chosen reduced data usage, meaning
[`navigator.connection.saveData`](https://developer.mozilla.org/en-US/docs/Web/
API/NetworkInformation/saveData) is `true`.
## data-sveltekit-preload-code
Even in cases where you don't want to preload _data_ for a link, it can be
beneficial to preload the _code_. The `data-sveltekit-preload-code` attribute works
similarly to `data-sveltekit-preload-data`, except that it can take one of four
values, in decreasing 'eagerness':
Note that `viewport` and `eager` only apply to links that are present in the DOM
immediately following navigation — if a link is added later (in an `{#if ...}`
block, for example) it will not be preloaded until triggered by `hover` or `tap`.
This is to avoid performance pitfalls resulting from aggressively observing the DOM
for changes.
## data-sveltekit-reload
Occasionally, we need to tell SvelteKit not to handle a link, but allow the browser
to handle it. Adding a `data-sveltekit-reload` attribute to a link...
```html
<a data-sveltekit-reload href="/path">Path</a>
```
## data-sveltekit-replacestate
Sometimes you don't want navigation to create a new entry in the browser's session
history. Adding a `data-sveltekit-replacestate` attribute to a link...
```html
<a data-sveltekit-replacestate href="/path">Path</a>
```
...will replace the current `history` entry rather than creating a new one with
`pushState` when the link is clicked.
## data-sveltekit-keepfocus
```html
<form data-sveltekit-keepfocus>
<input type="text" name="query">
</form>
```
...will cause the currently focused element to retain focus after navigation. In
general, avoid using this attribute on links, since the focused element would be
the `<a>` tag (and not a previously focused element) and screen reader and other
assistive technology users often expect focus to be moved after a navigation. You
should also only use this attribute on elements that still exist after navigation.
If the element no longer exists, the user's focus will be lost, making for a
confusing experience for assistive technology users.
## data-sveltekit-noscroll
In certain cases, you may wish to disable this behaviour. Adding a `data-sveltekit-
noscroll` attribute to a link...
```html
<a href="path" data-sveltekit-noscroll>Path</a>
```
## Disabling options
To disable any of these options inside an element where they have been enabled, use
the `"false"` value:
```html
<div data-sveltekit-preload-data>
<!-- these links will be preloaded -->
<a href="/a">a</a>
<a href="/b">b</a>
<a href="/c">c</a>
<div data-sveltekit-preload-data="false">
<!-- these links will NOT be preloaded -->
<a href="/d">d</a>
<a href="/e">e</a>
<a href="/f">f</a>
</div>
</div>
```
```svelte
<div data-sveltekit-preload-data={condition ? 'hover' : false}>
```
## docs/kit/30-advanced/40-service-workers.md
---
Service workers act as proxy servers that handle network requests inside your app.
This makes it possible to make your app work offline, but even if you don't need
offline support (or can't realistically implement it because of the type of app
you're building), it's often worth using service workers to speed up navigation by
precaching your built JS and CSS.
```js
if ('serviceWorker' in navigator) {
addEventListener('load', function () {
navigator.serviceWorker.register('./path/to/service-worker.js');
});
}
```
Inside the service worker you have access to the [`$service-worker` module]
($service-worker), which provides you with the paths to all static assets, build
files and prerendered pages. You're also provided with an app version string, which
you can use for creating a unique cache name, and the deployment's `base` path. If
your Vite config specifies `define` (used for global variable replacements), this
will be applied to service workers as well as your server/client builds.
The following example caches the built app and any files in `static` eagerly, and
caches all other requests as they happen. This would make each page work offline
once visited.
```js
// @errors: 2339
/// <reference types="@sveltejs/kit" />
import { build, files, version } from '$service-worker';
const ASSETS = [
...build, // the app itself
...files // everything in `static`
];
event.waitUntil(addFilesToCache());
});
event.waitUntil(deleteOldCaches());
});
if (response) {
return response;
}
}
return response;
} catch (err) {
const response = await cache.match(event.request);
if (response) {
return response;
}
event.respondWith(respond());
});
```
## During development
The service worker is bundled for production, but not during development. For that
reason, only browsers that support [modules in service workers](https://web.dev/es-
modules-in-sw) will be able to use them at dev time. If you are manually
registering your service worker, you will need to pass the `{ type: 'module' }`
option in development:
```js
import { dev } from '$app/environment';
navigator.serviceWorker.register('/service-worker.js', {
type: dev ? 'module' : 'classic'
});
```
## Type safety
Setting up proper types for service workers requires some manual setup. Inside your
`service-worker.js`, add the following to the top of your file:
```original-js
/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />
This disables access to DOM typings like `HTMLElement` which are not available
inside a service worker and instantiates the correct globals. The reassignment of
`self` to `sw` allows you to type cast it in the process (there are a couple of
ways to do this, but this is the easiest that requires no additional files). Use
`sw` instead of `self` in the rest of the file. The reference to the SvelteKit
types ensures that the `$service-worker` import has proper type definitions. If you
import `$env/static/public` you either have to `// @ts-ignore` the import or add
`/// <reference types="../.svelte-kit/ambient.d.ts" />` to the reference types.
## Other solutions
For more general information on service workers, we recommend [the MDN web docs]
(https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/
Using_Service_Workers).
## docs/kit/30-advanced/50-server-only-modules.md
---
Like a good friend, SvelteKit keeps your secrets. When writing your backend and
frontend in the same repository, it can be easy to accidentally import sensitive
data into your front-end code (environment variables containing API keys, for
example). SvelteKit provides a way to prevent this entirely: server-only modules.
## Server-only utilities
## Your modules
## How it works
Any time you have public-facing code that imports server-only code (whether
directly or indirectly)...
```js
// @errors: 7005
/// file: $lib/server/secrets.js
export const atlantisCoordinates = [/* redacted */];
```
```js
// @errors: 2307 7006 7005
/// file: src/routes/utils.js
export { atlantisCoordinates } from '$lib/server/secrets.js';
```html
/// file: src/routes/+page.svelte
<script>
import { add } from './utils.js';
</script>
```
```
Cannot import $lib/server/secrets.js into public-facing code:
src/routes/+page.svelte
src/routes/utils.js
$lib/server/secrets.js
```
This feature also works with dynamic imports, even interpolated ones like ``await
import(`./${foo}.js`)``, with one small caveat: during development, if there are
two or more dynamic imports between the public-facing code and the server-only
module, the illegal import will not be detected the first time the code is loaded.
## Further reading
## docs/kit/30-advanced/65-snapshots.md
---
title: Snapshots
---
Ephemeral DOM state — like scroll positions on sidebars, the content of `<input>`
elements and so on — is discarded when you navigate from one page to another.
For example, if the user fills out a form but navigates away and then back before
submitting, or if the user refreshes the page, the values they filled in will be
lost. In cases where it's valuable to preserve that input, you can take a
_snapshot_ of DOM state, which can then be restored if the user navigates back.
To do this, export a `snapshot` object with `capture` and `restore` methods from a
`+page.svelte` or `+layout.svelte`:
```svelte
<!file: +page.svelte>
<script>
let comment = $state('');
When you navigate away from this page, the `capture` function is called immediately
before the page updates, and the returned value is associated with the current
entry in the browser's history stack. If you navigate back, the `restore` function
is called with the stored value as soon as the page is updated.
## docs/kit/30-advanced/67-shallow-routing.md
---
As you navigate around a SvelteKit app, you create _history entries_. Clicking the
back and forward buttons traverses through this list of entries, re-running any
`load` functions and replacing page components as necessary.
Sometimes, it's useful to create history entries _without_ navigating. For example,
you might want to show a modal dialog that the user can dismiss by navigating back.
This is particularly valuable on mobile devices, where swipe gestures are often
more natural than interacting directly with the UI. In these cases, a modal that is
_not_ associated with a history entry can be a source of frustration, as a user may
swipe backwards in an attempt to dismiss it and find themselves on the wrong page.
```svelte
<!file: +page.svelte>
<script>
import { pushState } from '$app/navigation';
import { page } from '$app/state';
import Modal from './Modal.svelte';
function showModal() {
pushState('', {
showModal: true
});
}
</script>
{#if page.state.showModal}
<Modal close={() => history.back()} />
{/if}
```
The modal can be dismissed by navigating back (unsetting `page.state.showModal`) or
by interacting with it in a way that causes the `close` callback to run, which will
navigate back programmatically.
## API
The first argument to `pushState` is the URL, relative to the current URL. To stay
on the current URL, use `''`.
The second argument is the new page state, which can be accessed via the [page
object]($app-state#page) as `page.state`. You can make page state type-safe by
declaring an [`App.PageState`](types#PageState) interface (usually in
`src/app.d.ts`).
To set page state without creating a new history entry, use `replaceState` instead
of `pushState`.
> [!LEGACY]
> `page.state` from `$app/state` was added in SvelteKit 2.12. If you're using an
earlier version or are using Svelte 4, use `$page.state` from `$app/stores`
instead.
When shallow routing, you may want to render another `+page.svelte` inside the
current page. For example, clicking on a photo thumbnail could pop up the detail
view without navigating to the photo page.
For this to work, you need to load the data that the `+page.svelte` expects. A
convenient way to do this is to use [`preloadData`]($app-navigation#preloadData)
inside the `click` handler of an `<a>` element. If the element (or a parent) uses
[`data-sveltekit-preload-data`](link-options#data-sveltekit-preload-data), the data
will have already been requested, and `preloadData` will reuse that request.
```svelte
<!file: src/routes/photos/+page.svelte>
<script>
import { preloadData, pushState, goto } from '$app/navigation';
import { page } from '$app/state';
import Modal from './Modal.svelte';
import PhotoPage from './[id]/+page.svelte';
// prevent navigation
e.preventDefault();
const { href } = e.currentTarget;
// run `load` functions (or rather, get the result of the `load`
functions
// that are already running because of `data-sveltekit-preload-
data`)
const result = await preloadData(href);
{#if page.state.selected}
<Modal onclose={() => history.back()}>
<!-- pass page data to the +page.svelte component,
just like SvelteKit would on navigation -->
<PhotoPage data={page.state.selected} />
</Modal>
{/if}
```
## Caveats
## docs/kit/30-advanced/70-packaging.md
---
title: Packaging
---
You can use SvelteKit to build apps as well as component libraries, using the
`@sveltejs/package` package (`npx sv create` has an option to set this up for you).
A component library has the exact same structure as a SvelteKit app, except that
`src/lib` is the public-facing bit, and your root `package.json` is used to publish
the package. `src/routes` might be a documentation or demo site that accompanies
the library, or it might just be a sandbox you use during development.
## Anatomy of a package.json
Since you're now building a library for public use, the contents of your
`package.json` will become more important. Through it, you configure the entry
points of your package, which files are published to npm, and which dependencies
your library has. Let's go through the most important fields one by one.
### name
This is the name of your package. It will be available for others to install using
that name, and visible on `https://npmjs.com/package/<name>`.
```json
{
"name": "your-library"
}
```
### license
Every package should have a license field so people know how they are allowed to
use it. A very popular license which is also very permissive in terms of
distribution and reuse without warranty is `MIT`.
```json
{
"license": "MIT"
}
```
### files
This tells npm which files it will pack up and upload to npm. It should contain
your output folder (`dist` by default). Your `package.json` and `README` and
`LICENSE` will always be included, so you don't need to specify them.
```json
{
"files": ["dist"]
}
```
To exclude unnecessary files (such as unit tests, or modules that are only imported
from `src/routes` etc) you can add them to an `.npmignore` file. This will result
in smaller packages that are faster to install.
### exports
The `"exports"` field contains the package's entry points. If you set up a new
library project through `npx sv create`, it's set to a single export, the package
root:
```json
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"svelte": "./dist/index.js"
}
}
}
```
This tells bundlers and tooling that your package only has one entry point, the
root, and everything should be imported through that, like this:
```js
// @errors: 2307
import { Something } from 'your-library';
```
- TypeScript sees the `types` condition and looks up the type definition file. If
you don't publish type definitions, omit this condition.
- Svelte-aware tooling sees the `svelte` condition and knows this is a Svelte
component library. If you publish a library that does not export any Svelte
components and that could also work in non-Svelte projects (for example a Svelte
store library), you can replace this condition with `default`.
You can adjust `exports` to your liking and provide more entry points. For example,
if instead of a `src/lib/index.js` file that re-exported components you wanted to
expose a `src/lib/Foo.svelte` component directly, you could create the following
export map...
```json
{
"exports": {
"./Foo.svelte": {
"types": "./dist/Foo.svelte.d.ts",
"svelte": "./dist/Foo.svelte"
}
}
}
```
...and a consumer of your library could import the component like so:
```js
// @filename: ambient.d.ts
declare module 'your-library/Foo.svelte';
// @filename: index.js
//cut
import Foo from 'your-library/Foo.svelte';
```
In general, each key of the exports map is the path the user will have to use to
import something from your package, and the value is the path to the file that will
be imported or a map of export conditions which in turn contains these file paths.
### svelte
```json
{
"svelte": "./dist/index.js"
}
```
### sideEffects
Setting the `sideEffects` field in `package.json` can help the bundler to be more
aggressive in eliminating unused exports from the final bundle, a process known as
tree-shaking. This results in smaller and more efficient bundles. Different
bundlers handle `sideEffects` in various manners. While not necessary for Vite, we
recommend that libraries state that all CSS files have side effects so that your
library will be [compatible with webpack](https://webpack.js.org/guides/tree-
shaking/#mark-the-file-as-side-effect-free). This is the configuration that comes
with newly created projects:
```json
/// file: package.json
{
"sideEffects": ["**/*.css"]
}
```
> If the scripts in your library have side effects, ensure that you update the
`sideEffects` field. All scripts are marked as side effect free by default in newly
created projects. If a file with side effects is incorrectly marked as having no
side effects, it can result in broken functionality.
If your package has files with side effects, you can specify them in an array:
```json
/// file: package.json
{
"sideEffects": [
"**/*.css",
"./dist/sideEffectfulFile.js"
]
}
```
This will treat only the specified files as having side effects.
## TypeScript
You should ship type definitions for your library even if you don't use TypeScript
yourself so that people who do get proper intellisense when using your library.
`@sveltejs/package` makes the process of generating types mostly opaque to you. By
default, when packaging your library, type definitions are auto-generated for
JavaScript, TypeScript and Svelte files. All you need to ensure is that the `types`
condition in the [exports](#Anatomy-of-a-package.json-exports) map points to the
correct files. When initialising a library project through `npx sv create`, this is
automatically setup for the root export.
If you have something else than a root export however — for example providing a
`your-library/foo` import — you need to take additional care for providing type
definitions. Unfortunately, TypeScript by default will _not_ resolve the `types`
condition for an export like `{ "./foo": { "types": "./dist/foo.d.ts", ... }}`.
Instead, it will search for a `foo.d.ts` relative to the root of your library (i.e.
`your-library/foo.d.ts` instead of `your-library/dist/foo.d.ts`). To fix this, you
have two options:
The first option is to require people using your library to set the
`moduleResolution` option in their `tsconfig.json` (or `jsconfig.json`) to
`bundler` (available since TypeScript 5, the best and recommended option in the
future), `node16` or `nodenext`. This opts TypeScript into actually looking at the
exports map and resolving the types correctly.
The second option is to (ab)use the `typesVersions` feature from TypeScript to wire
up the types. This is a field inside `package.json` TypeScript uses to check for
different type definitions depending on the TypeScript version, and also contains a
path mapping feature for that. We leverage that path mapping feature to get what we
want. For the mentioned `foo` export above, the corresponding `typesVersions` looks
like this:
```json
{
"exports": {
"./foo": {
"types": "./dist/foo.d.ts",
"svelte": "./dist/foo.js"
}
},
"typesVersions": {
">4.0": {
"foo": ["./dist/foo.d.ts"]
}
}
}
```
`>4.0` tells TypeScript to check the inner map if the used TypeScript version is
greater than 4 (which should in practice always be true). The inner map tells
TypeScript that the typings for `your-library/foo` are found within
`./dist/foo.d.ts`, which essentially replicates the `exports` condition. You also
have `*` as a wildcard at your disposal to make many type definitions at once
available without repeating yourself. Note that if you opt into `typesVersions` you
have to declare all type imports through it, including the root import (which is
defined as `"index.d.ts": [..]`).
## Best practices
You should think carefully about whether or not the changes you make to your
package are a bug fix, a new feature, or a breaking change, and update the package
version accordingly. Note that if you remove any paths from `exports` or any
`export` conditions inside them from your existing library, that should be regarded
as a breaking change.
```json
{
"exports": {
".": {
"types": "./dist/index.d.ts",
// changing `svelte` to `default` is a breaking change:
"svelte": "./dist/index.js"
"default": "./dist/index.js"
},
// removing this is a breaking change:
"./foo": {
"types": "./dist/foo.d.ts",
"svelte": "./dist/foo.js",
"default": "./dist/foo.js"
},
// adding this is ok:
"./bar": {
"types": "./dist/bar.d.ts",
"svelte": "./dist/bar.js",
"default": "./dist/bar.js"
}
}
}
```
## Source maps
```json
{
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*",
"src/lib",
"!src/lib/**/*.test.*",
"!src/lib/**/*.spec.*"
]
}
```
## Options
- `-w`/`--watch` — watch files in `src/lib` for changes and rebuild the package
- `-i`/`--input` — the input directory which contains all the files of the package.
Defaults to `src/lib`
- `-o`/`--output` — the output directory where the processed files are written to.
Your `package.json`'s `exports` should point to files inside there, and the `files`
array should include that folder. Defaults to `dist`
- `-t`/`--types` — whether or not to create type definitions (`d.ts` files). We
strongly recommend doing this as it fosters ecosystem library quality. Defaults to
`true`
- `--tsconfig` - the path to a tsconfig or jsconfig. When not provided, searches
for the next upper tsconfig/jsconfig in the workspace path.
## Publishing
```sh
npm publish
```
## Caveats
All relative file imports need to be fully specified, adhering to Node's ESM
algorithm. This means that for a file like `src/lib/something/index.js`, you must
include the filename with the extension:
```js
// @errors: 2307
import { something } from './something/index.js';
```
If you are using TypeScript, you need to import `.ts` files the same way, but using
a `.js` file ending, _not_ a `.ts` file ending. (This is a TypeScript design
decision outside our control.) Setting `"moduleResolution": "NodeNext"` in your
`tsconfig.json` or `jsconfig.json` will help you with this.
All files except Svelte files (preprocessed) and TypeScript files (transpiled to
JavaScript) are copied across as-is.
## docs/kit/40-best-practices/index.md
---
## docs/kit/40-best-practices/03-auth.md
---
title: Auth
---
Auth refers to authentication and authorization, which are common needs when
building a web application. Authentication means verifying that the user is who
they say they are based on their provided credentials. Authorization means
determining which actions they are allowed to take.
## Sessions vs tokens
After the user has provided their credentials such as a username and password, we
want to allow them to use the application without needing to provide their
credentials again for future requests. Users are commonly authenticated on
subsequent requests with either a session identifier or signed token such as a JSON
Web Token (JWT).
Session IDs are most commonly stored in a database. They can be immediately
revoked, but require a database query to be made on each request.
In contrast, JWT generally are not checked against a datastore, which means they
cannot be immediately revoked. The advantage of this method is improved latency and
reduced load on your datastore.
## Integration points
## Guides
An auth system is tightly coupled to a web framework because most of the code lies
in validating user input, handling errors, and directing users to the appropriate
next page. As a result, many of the generic JS auth libraries include one or more
web frameworks within them. For this reason, many users will find it preferrable to
follow a SvelteKit-specific guide such as the examples found in
[Lucia](https://lucia-auth.com/) rather than having multiple web frameworks inside
their project.
## docs/kit/40-best-practices/05-performance.md
---
title: Performance
---
Out of the box, SvelteKit does a lot of work to make your applications as
performant as possible:
- Code-splitting, so that only the code you need for the current page is loaded
- Asset preloading, so that 'waterfalls' (of files requesting other files) are
prevented
- File hashing, so that your assets can be cached forever
- Request coalescing, so that data fetched from separate server `load` functions is
grouped into a single HTTP request
- Parallel loading, so that separate universal `load` functions fetch data
simultaneously
- Data inlining, so that requests made with `fetch` during server rendering can be
replayed in the browser without issuing a new request
- Conservative invalidation, so that `load` functions are only re-run when
necessary
- Prerendering (configurable on a per-route basis, if necessary) so that pages
without dynamic data can be served instantaneously
- Link preloading, so that data and code requirements for a client-side navigation
are eagerly anticipated
Nevertheless, we can't (yet) eliminate all sources of slowness. To eke out maximum
performance, you should be mindful of the following tips.
## Diagnosing issues
Your browser also includes useful developer tools for analysing your site, whether
deployed or running locally:
* Chrome -
[Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools),
[Network](https://developer.chrome.com/docs/devtools/network), and [Performance]
(https://developer.chrome.com/docs/devtools/performance) devtools
* Edge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-
guide-chromium/lighthouse/lighthouse-tool),
[Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-
chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-
edge/devtools-guide-chromium/evaluate-performance/) devtools
* Firefox -
[Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/)
and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-
devtools-reloaded/) devtools
* Safari - [enhancing the performance of your
webpage](https://developer.apple.com/library/archive/documentation/
NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/
EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html)
Note that your site running locally in `dev` mode will exhibit different behaviour
than your production app, so you should do performance testing in [preview]
(building-your-app#Preview-your-app) mode after building.
### Instrumenting
If you see in the network tab of your browser that an API call is taking a long
time and you'd like to understand why, you may consider instrumenting your backend
with a tool like [OpenTelemetry](https://opentelemetry.io/) or [Server-Timing
headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing).
## Optimizing assets
### Images
Reducing the size of image files is often one of the most impactful changes you can
make to a site's performance. Svelte provides the `@sveltejs/enhanced-img` package,
detailed on the [images](images) page, for making this easier. Additionally,
Lighthouse is useful for identifying the worst offenders.
### Videos
Video files can be very large, so extra care should be taken to ensure that they're
optimized:
### Fonts
SvelteKit automatically preloads critical `.js` and `.css` files when the user
visits a page, but it does _not_ preload fonts by default, since this may cause
unnecessary files (such as font weights that are referenced by your CSS but not
actually used on the current page) to be downloaded. Having said that, preloading
fonts correctly can make a big difference to how fast your site feels. In your
[`handle`](hooks#Server-hooks-handle) hook, you can call `resolve` with a `preload`
filter that includes your fonts.
We recommend running the latest version of Svelte. Svelte 5 is smaller and faster
than Svelte 4, which is smaller and faster than Svelte 3.
### Packages
[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-
visualizer) can be helpful for identifying which packages are contributing the most
to the size of your site. You may also find opportunities to remove code by
manually inspecting the build output (use `build: { minify: false }` in your [Vite
config](https://vitejs.dev/config/build-options.html#build-minify) to make the
output readable, but remember to undo that before deploying your app), or via the
network tab of your browser's devtools.
Try to minimize the number of third-party scripts running in the browser. For
example, instead of using JavaScript-based analytics consider using server-side
implementations, such as those offered by many platforms with SvelteKit adapters
including [Cloudflare](https://www.cloudflare.com/web-analytics/), [Netlify]
(https://docs.netlify.com/monitor-sites/site-analytics/), and
[Vercel](https://vercel.com/docs/analytics).
To run third party scripts in a web worker (which avoids blocking the main thread),
use [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit).
Code imported with static `import` declarations will be automatically bundled with
the rest of your page. If there is a piece of code you need only when some
condition is met, use the dynamic `import(...)` form to selectively lazy-load the
component.
## Navigation
### Preloading
You can speed up client-side navigations by eagerly preloading the necessary code
and data, using [link options](link-options). This is configured by default on the
`<body>` element when you create a new SvelteKit app.
For slow-loading data that isn't needed immediately, the object returned from your
`load` function can contain promises rather than the data itself. For server `load`
functions, this will cause the data to [stream](load#Streaming-with-promises) in
after the navigation (or initial page load).
- Asset waterfalls can occur in the browser when your HTML requests JS which
requests CSS which requests a background image and web font. SvelteKit will largely
solve this class of problems for you by adding
[`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/
rel/modulepreload) tags or headers, but you should view [the network tab in your
devtools](#Diagnosing-issues) to check whether additional resources need to be
preloaded. Pay special attention to this if you use web [fonts](#Optimizing-assets-
Fonts) since they need to be handled manually.
- If a universal `load` function makes an API call to fetch the current user, then
uses the details from that response to fetch a list of saved items, and then uses
_that_ response to fetch the details for each item, the browser will end up making
multiple sequential requests. This is deadly for performance, especially for users
that are physically located far from your backend. Avoid this issue by using
[server `load` functions](load#Universal-vs-server) where possible.
- Server `load` functions are also not immune to waterfalls (though they are much
less costly since they rarely involve roundtrips with high latency). For example if
you query a database to get the current user and then use that data to make a
second query for a list of saved items, it will typically be more performant to
issue a single query with a database join.
## Hosting
Your frontend should be located in the same data center as your backend to minimize
latency. For sites with no central backend, many SvelteKit adapters support
deploying to the _edge_, which means handling each user's requests from a nearby
server. This can reduce load times significantly. Some adapters even support
[configuring deployment on a per-route basis](page-options#config). You should also
consider serving images from a CDN (which are typically edge networks) — the hosts
for many SvelteKit adapters will do this automatically.
Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small
files for improved cacheability, which results in excellent performance, but this
does assume that your files can be loaded in parallel with HTTP/2.
## Further reading
For the most part, building a performant SvelteKit app is the same as building any
performant web app. You should be able to apply information from general
performance resources such as [Core Web Vitals](https://web.dev/explore/learn-core-
web-vitals) to any web experience you build.
## docs/kit/40-best-practices/06-icons.md
---
title: Icons
---
## CSS
A great way to use icons is to define them purely via CSS. Iconify offers support
for [many popular icon sets](https://icon-sets.iconify.design/) that [can be
included via CSS](https://iconify.design/docs/usage/css/). This method can also be
used with popular CSS frameworks by leveraging the Iconify [Tailwind CSS plugin]
(https://iconify.design/docs/usage/css/tailwind/) or [UnoCSS
plugin](https://iconify.design/docs/usage/css/unocss/). As opposed to libraries
based on Svelte components, it doesn't require each icon to be imported into your
`.svelte` file.
## Svelte
## docs/kit/40-best-practices/07-images.md
---
title: Images
---
Images can have a big impact on your app's performance. For best results, you
should optimize them by doing the following:
Doing this manually is tedious. There are a variety of techniques you can use,
depending on your needs and preferences.
```svelte
<script>
import logo from '$lib/assets/logo.png';
</script>
## @sveltejs/enhanced-img
### Setup
Install:
```bash
npm install --save-dev @sveltejs/enhanced-img
```
Adjust `vite.config.js`:
```js
import { sveltekit } from '@sveltejs/kit/vite';
import { enhancedImages } from '@sveltejs/enhanced-img';
import { defineConfig } from 'vite';
Building will take longer on the first build due to the computational expense of
transforming images. However, the build output will be cached in
`./node_modules/.cache/imagetools` so that subsequent builds will be fast.
Use in your `.svelte` components by using `<enhanced:img>` rather than `<img>` and
referencing the image file with a [Vite asset
import](https://vitejs.dev/guide/assets.html#static-asset-handling) path:
```svelte
<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />
```
At build time, your `<enhanced:img>` tag will be replaced with an `<img>` wrapped
by a `<picture>` providing multiple image types and sizes. It's only possible to
downscale images without losing quality, which means that you should provide the
highest resolution image that you need — smaller versions will be generated for the
various device types that may request an image.
You should provide your image at 2x resolution for HiDPI displays (a.k.a. retina
displays). `<enhanced:img>` will automatically take care of serving smaller
versions to smaller devices.
If you wish to add styles to your `<enhanced:img>`, you should add a `class` and
target that.
You can also manually import an image asset and pass it to an `<enhanced:img>`.
This is useful when you have a collection of static images and would like to
dynamically choose one or [iterate over
them](https://github.com/sveltejs/kit/blob/0ab1733e394b6310895a1d3bf0f126ce34531170
/sites/kit.svelte.dev/src/routes/home/Showcase.svelte). In this case you will need
to update both the `import` statement and `<img>` element as shown below to
indicate you'd like process them.
```svelte
<script>
import MyImage from './path/to/your/image.jpg?enhanced';
</script>
```svelte
<script>
const imageModules = import.meta.glob(
'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',
{
eager: true,
query: {
enhanced: true
}
}
)
</script>
`width` and `height` are optional as they can be inferred from the source image and
will be automatically added when the `<enhanced:img>` tag is preprocessed. With
these attributes, the browser can reserve the correct amount of space, preventing
[layout shift](https://web.dev/articles/cls). If you'd like to use a different
`width` and `height` you can style the image with CSS. Because the preprocessor
adds a `width` and `height` for you, if you'd like one of the dimensions to be
automatically calculated then you will need to specify that:
```svelte
<style>
.hero-image img {
width: var(--size);
height: auto;
}
</style>
```
If you have a large image, such as a hero image taking the width of the design, you
should specify `sizes` so that smaller versions are requested on smaller devices.
E.g. if you have a 1280px image you may want to specify something like:
```svelte
<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>
```
The smallest picture generated automatically will have a width of 540px. If you'd
like smaller images or would otherwise like to specify custom widths, you can do
that with the `w` query parameter:
```svelte
<enhanced:img
src="./image.png?w=1280;640;400"
sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px)
400px"
/>
```
```svelte
<enhanced:img src="./path/to/your/image.jpg?blur=15" alt="An alt text" />
```
In some cases, the images may not be accessible at build time — e.g. they may live
inside a content management system or elsewhere.
Using a content delivery network (CDN) can allow you to optimize these images
dynamically, and provides more flexibility with regards to sizes, but it may
involve some setup overhead and usage costs. Depending on caching strategy, the
browser may not be able to use a cached copy of the asset until a [304 response]
(https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) is received from the
CDN. Building HTML to target CDNs allows using an `<img>` tag since the CDN can
serve the appropriate format based on the `User-Agent` header, whereas build-time
optimizations must produce `<picture>` tags with multiple sources. Finally, some
CDNs may generate images lazily, which could have a negative performance impact for
sites with low traffic and frequently changing images.
CDNs can generally be used without any need for a library. However, there are a
number of libraries with Svelte support that make it easier. [`@unpic/svelte`]
(https://unpic.pics/img/svelte/) is a CDN-agnostic library with support for a large
number of providers. You may also find that specific CDNs like [Cloudinary]
(https://svelte.cloudinary.dev/) have Svelte support. Finally, some content
management systems (CMS) which support Svelte (such as
[Contentful](https://www.contentful.com/sveltekit-starter-guide/), [Storyblok]
(https://github.com/storyblok/storyblok-svelte), and
[Contentstack](https://www.contentstack.com/docs/developers/sample-apps/build-a-
starter-website-with-sveltekit-and-contentstack)) have built-in support for image
handling.
## Best practices
- For each image type, use the appropriate solution from those discussed above. You
can mix and match all three solutions in one project. For example, you may use
Vite's built-in handling to provide images for `<meta>` tags, display images on
your homepage with `@sveltejs/enhanced-img`, and display user-submitted content
with a dynamic approach.
- Consider serving all images via CDN regardless of the image optimization types
you use. CDNs reduce latency by distributing copies of static assets globally.
- Your original images should have a good quality/resolution and should have 2x the
width it will be displayed at to serve HiDPI devices. Image processing can size
images down to save bandwidth when serving smaller screens, but it would be a waste
of bandwidth to invent pixels to size images up.
- For images which are much larger than the width of a mobile device (roughly
400px), such as a hero image taking the width of the page design, specify `sizes`
so that smaller images can be served on smaller devices.
- For important images, such as the [largest contentful paint
(LCP)](https://web.dev/articles/lcp) image, set `fetchpriority="high"` and avoid
`loading="lazy"` to prioritize loading as early as possible.
- Give the image a container or styling so that it is constrained and does not jump
around while the page is loading affecting your [cumulative layout shift (CLS)]
(https://web.dev/articles/cls). `width` and `height` help the browser to reserve
space while the image is still loading, so `@sveltejs/enhanced-img` will add a
`width` and `height` for you.
- Always provide a good `alt` text. The Svelte compiler will warn you if you don't
do this.
- Do not use `em` or `rem` in `sizes` and change the default size of these
measures. When used in `sizes` or `@media` queries, `em` and `rem` are both defined
to mean the user's default `font-size`. For a `sizes` declaration like
`sizes="(min-width: 768px) min(100vw, 108rem), 64rem"`, the actual `em` or `rem`
that controls how the image is laid out on the page can be different if changed by
CSS. For example, do not do something like `html { font-size: 62.5%; }` as the slot
reserved by the browser preloader will now end up being larger than the actual slot
of the CSS object model once it has been created.
## docs/kit/40-best-practices/10-accessibility.md
---
title: Accessibility
---
Here's how SvelteKit's built-in accessibility features work and what you need to do
to help these features to work as well as possible. Keep in mind that while
SvelteKit provides an accessible foundation, you are still responsible for making
sure your application code is accessible. If you're new to accessibility, see the
["further reading"](accessibility#Further-reading) section of this guide for
additional resources.
We recognize that accessibility can be hard to get right. If you want to suggest
improvements to how SvelteKit handles accessibility, please [open a GitHub issue]
(https://github.com/sveltejs/kit/issues).
## Route announcements
Since navigation between pages in SvelteKit happens without reloading the page
(known as [client-side routing](glossary#Routing)), SvelteKit injects a [live
region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/
ARIA_Live_Regions) onto the page that will read out the new page name after each
navigation. This determines the page name to announce by inspecting the `<title>`
element.
Because of this behavior, every page in your app should have a unique, descriptive
title. In SvelteKit, you can do this by placing a `<svelte:head>` element on each
page:
```svelte
<!file: src/routes/+page.svelte>
<svelte:head>
<title>Todo List</title>
</svelte:head>
```
This will allow screen readers and other assistive technology to identify the new
page after a navigation occurs. Providing a descriptive title is also important for
[SEO](seo#Manual-setup-title-and-meta).
## Focus management
If you want to customize SvelteKit's focus management, you can use the
`afterNavigate` hook:
```js
/// <reference types="@sveltejs/kit" />
//cut
import { afterNavigate } from '$app/navigation';
afterNavigate(() => {
/** @type {HTMLElement | null} */
const to_focus = document.querySelector('.focus-me');
to_focus?.focus();
});
```
You can also programmatically navigate to a different page using the [`goto`]($app-
navigation#goto) function. By default, this will have the same client-side routing
behavior as clicking on a link. However, `goto` also accepts a `keepFocus` option
that will preserve the currently-focused element instead of resetting focus. If you
enable this option, make sure the currently-focused element still exists on the
page after navigation. If the element no longer exists, the user's focus will be
lost, making for a confusing experience for assistive technology users.
By default, SvelteKit's page template sets the default language of the document to
English. If your content is not in English, you should update the `<html>` element
in `src/app.html` to have the correct [`lang`](https://developer.mozilla.org/en-
US/docs/Web/HTML/Global_attributes/lang#accessibility) attribute. This will ensure
that any assistive technology reading the document uses the correct pronunciation.
For example, if your content is in German, you should update `app.html` to the
following:
```html
/// file: src/app.html
<html lang="de">
```
If your content is available in multiple languages, you should set the `lang`
attribute based on the language of the current page. You can do this with
SvelteKit's [handle hook](hooks#Server-hooks-handle):
```html
/// file: src/app.html
<html lang="%lang%">
```
```js
/// file: src/hooks.server.js
/**
* @param {import('@sveltejs/kit').RequestEvent} event
*/
function get_lang(event) {
return 'en';
}
//cut
/** @type {import('@sveltejs/kit').Handle} */
export function handle({ event, resolve }) {
return resolve(event, {
transformPageChunk: ({ html }) => html.replace('%lang%',
get_lang(event))
});
}
```
## Further reading
For the most part, building an accessible SvelteKit app is the same as building an
accessible web app. You should be able to apply information from the following
general accessibility resources to any web experience you build:
## docs/kit/40-best-practices/20-seo.md
---
title: SEO
---
The most important aspect of SEO is to create high-quality content that is widely
linked to from around the web. However, there are a few technical considerations
for building sites that rank well.
### SSR
While search engines have got better in recent years at indexing content that was
rendered with client-side JavaScript, server-side rendered content is indexed more
frequently and reliably. SvelteKit employs SSR by default, and while you can
disable it in [`handle`](hooks#Server-hooks-handle), you should leave it on unless
you have a good reason not to.
### Performance
SvelteKit redirects pathnames with trailing slashes to ones without (or vice versa
depending on your [configuration](page-options#trailingSlash)), as duplicate URLs
are bad for SEO.
## Manual setup
Every page should have well-written and unique `<title>` and `<meta
name="description">` elements inside a [`<svelte:head>`](../svelte/svelte-head).
Guidance on how to write descriptive titles and descriptions, along with other
suggestions on making content understandable by search engines, can be found on
Google's [Lighthouse SEO audits](https://web.dev/lighthouse-seo/) documentation.
### Sitemaps
[Sitemaps](https://developers.google.com/search/docs/advanced/sitemaps/build-
sitemap) help search engines prioritize pages within your site, particularly when
you have a large amount of content. You can create a sitemap dynamically using an
endpoint:
```js
/// file: src/routes/sitemap.xml/+server.js
export async function GET() {
return new Response(
`
<?xml version="1.0" encoding="UTF-8" ?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="https://www.w3.org/1999/xhtml"
xmlns:mobile="https://www.google.com/schemas/sitemap-mobile/1.0"
xmlns:news="https://www.google.com/schemas/sitemap-news/0.9"
xmlns:image="https://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="https://www.google.com/schemas/sitemap-video/1.1"
>
<!-- <url> elements go here -->
</urlset>`.trim(),
{
headers: {
'Content-Type': 'application/xml'
}
}
);
}
```
### AMP
```js
/// file: svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// since <link rel="stylesheet"> isn't
// allowed, inline all styles
inlineStyleThreshold: Infinity
}
};
```js
/// file: src/routes/+layout.server.js
export const csr = false;
```
```js
/// file: src/hooks.server.js
import * as amp from '@sveltejs/amp';
To prevent shipping any unused CSS as a result of transforming the page to amp, we
can use [`dropcss`](https://www.npmjs.com/package/dropcss):
```js
// @filename: ambient.d.ts
declare module 'dropcss';
// @filename: index.js
//cut
/// file: src/hooks.server.js
// @errors: 2307
import * as amp from '@sveltejs/amp';
import dropcss from 'dropcss';
if (done) {
let css = '';
const markup = amp
.transform(buffer)
.replace('⚡', 'amp') // dropcss can't handle this
character
.replace(/<style
amp-custom([^>]*?)>([^]+?)<\/style>/, (match, attributes, contents) => {
css = contents;
return `<style
amp-custom${attributes}></style>`;
});
css = dropcss({ css, html: markup }).css;
return markup.replace('</style>', `${css}</style>`);
}
}
});
}
```
## docs/kit/60-appendix/index.md
---
title: Appendix
---
## docs/kit/60-appendix/10-faq.md
---
## Other resources
```ts
// @errors: 2732
/// file: svelte.config.js
import pkg from './package.json' with { type: 'json' };
```
Most issues related to including a library are due to incorrect packaging. You can
check if a library's packaging is compatible with Node.js by entering it into [the
publint website](https://publint.dev/).
Here are a few things to keep in mind when checking if a library is packaged
correctly:
- `exports` takes precedence over the other entry point fields such as `main` and
`module`. Adding an `exports` field may not be backwards-compatible as it prevents
deep imports.
- ESM files should end with `.mjs` unless `"type": "module"` is set in which any
case CommonJS files should end with `.cjs`.
- `main` should be defined if `exports` is not. It should be either a CommonJS or
ESM file and adhere to the previous bullet. If a `module` field is defined, it
should refer to an ESM file.
- Svelte components should be distributed as uncompiled `.svelte` files with any JS
in the package written as ESM only. Custom script and style languages, like
TypeScript and SCSS, should be preprocessed as vanilla JS and CSS respectively. We
recommend using [`svelte-package`](./packaging) for packaging Svelte libraries,
which will do this for you.
Libraries work best in the browser with Vite when they distribute an ESM version,
especially if they are dependencies of a Svelte component library. You may wish to
suggest to library authors that they provide an ESM version. However, CommonJS
(CJS) dependencies should work as well since, by default, [`vite-plugin-svelte`
will ask Vite to pre-bundle
them](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#what-is-
going-on-with-vite-and-pre-bundling-dependencies) using `esbuild` to convert them
to ESM.
If you are still encountering issues we recommend searching both [the Vite issue
tracker](https://github.com/vitejs/vite/issues) and the issue tracker of the
library in question. Sometimes issues can be worked around by fiddling with the
[`optimizeDeps`](https://vitejs.dev/config/#dep-optimization-options) or [`ssr`]
(https://vitejs.dev/config/#ssr-options) config values though we recommend this as
only a short-term workaround in favor of fixing the library in question.
While SvelteKit does not have any specific integration with [view transitions]
(https://developer.chrome.com/docs/web-platform/view-transitions/), you can call
`document.startViewTransition` in [`onNavigate`]($app-navigation#onNavigate) to
trigger a view transition on every client-side navigation.
```js
// @errors: 2339 2810
import { onNavigate } from '$app/navigation';
onNavigate((navigation) => {
if (!document.startViewTransition) return;
If you need access to the `document` or `window` variables or otherwise need code
to run only on the client-side you can wrap it in a `browser` check:
```js
/// <reference types="@sveltejs/kit" />
//cut
import { browser } from '$app/environment';
if (browser) {
// client-only code here
}
```
You can also run code in `onMount` if you'd like to run it after the component has
been first rendered to the DOM:
```js
// @filename: ambient.d.ts
// @lib: ES2015
declare module 'some-browser-only-library';
// @filename: index.js
//cut
import { onMount } from 'svelte';
onMount(async () => {
const { method } = await import('some-browser-only-library');
method('hello world');
});
```
If the library you'd like to use is side-effect free you can also statically import
it and it will be tree-shaken out in the server-side build where `onMount` will be
automatically replaced with a no-op:
```js
// @filename: ambient.d.ts
// @lib: ES2015
declare module 'some-browser-only-library';
// @filename: index.js
//cut
import { onMount } from 'svelte';
import { method } from 'some-browser-only-library';
onMount(() => {
method('hello world');
});
```
{#await ComponentConstructor}
<p>Loading...</p>
{:then component}
<svelte:component this={component} />
{:catch error}
<p>Something went wrong: {error.message}</p>
{/await}
```
```js
/// file: src/routes/api/[...path]/+server.js
/** @type {import('./$types').RequestHandler} */
export function GET({ params, url }) {
return fetch(`https://my-api-server.com/${params.path + url.search}`);
}
```
(Note that you may also need to proxy `POST`/`PATCH` etc requests, and forward
`request.headers`, depending on your needs.)
`adapter-node` builds a middleware that you can use with your own server for
production mode. In dev, you can add middleware to Vite by using a Vite plugin. For
example:
```js
// @errors: 2322
// @filename: ambient.d.ts
declare module '@sveltejs/kit/vite'; // TODO this feels unnecessary, why can't it
'see' the declarations?
// @filename: index.js
//cut
import { sveltekit } from '@sveltejs/kit/vite';
Sort of. The Plug'n'Play feature, aka 'pnp', is broken (it deviates from the Node
module resolution algorithm, and [doesn't yet work with native JavaScript modules]
(https://github.com/yarnpkg/berry/issues/638) which SvelteKit — along with an
[increasing number of packages](https://blog.sindresorhus.com/get-ready-for-esm-
aa53530b3f77) — uses). You can use `nodeLinker: 'node-modules'` in your
[`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc#nodeLinker) file to
disable pnp, but it's probably easier to just use npm or [pnpm](https://pnpm.io/),
which is similarly fast and efficient but without the compatibility headaches.
```sh
yarn create svelte myapp
cd myapp
```
```sh
yarn set version berry
yarn install
```
#### Yarn 3 global cache
One of the more interesting features of Yarn Berry is the ability to have a single
global cache for packages, instead of having multiple copies for each project on
the disk. However, setting `enableGlobalCache` to true causes building to fail, so
it is recommended to add the following to the `.yarnrc.yml` file:
```yaml
nodeLinker: node-modules
```
This will cause packages to be downloaded into a local node_modules directory but
avoids the above problem and is your best bet for using version 3 of Yarn at this
point in time.
## docs/kit/60-appendix/20-integrations.md
---
title: Integrations
---
## `vitePreprocess`
Including [`vitePreprocess`](https://github.com/sveltejs/vite-plugin-svelte/blob/
main/docs/preprocess.md) in your project will allow you to use the various flavors
of CSS that Vite supports: PostCSS, SCSS, Less, Stylus, and SugarSS. If you set
your project up with TypeScript it will be included by default:
```js
// svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default {
preprocess: [vitePreprocess()]
};
```
You will also need to use a preprocessor if you're using TypeScript with Svelte 4.
TypeScript is supported natively in Svelte 5 if you're using only the type syntax.
To use more complex TypeScript syntax in Svelte 5, you will need still need a
preprocessor and can use `vitePreprocess({ script: true })`.
## Adders
Run `npx sv add` to setup many different complex integrations with a single command
including:
- prettier (formatting)
- eslint (linting)
- vitest (unit testing)
- playwright (e2e testing)
- lucia (auth)
- tailwind (CSS)
- drizzle (DB)
- paraglide (i18n)
- mdsvex (markdown)
- storybook (frontend workshop)
## Directory
## Additional integrations
### `svelte-preprocess`
You will need to install `svelte-preprocess` with `npm install --save-dev svelte-
preprocess` and [add it to your
`svelte.config.js`](https://github.com/sveltejs/svelte-preprocess/blob/main/docs/
usage.md#with-svelte-config). After that, you will often need to [install the
corresponding
library](https://github.com/sveltejs/svelte-preprocess/blob/main/docs/getting-
started.md) such as `npm install -D sass` or `npm install -D less`.
## Vite plugins
Since SvelteKit projects are built with Vite, you can use Vite plugins to enhance
your project. See a list of available plugins at
[`vitejs/awesome-vite`](https://github.com/vitejs/awesome-vite?tab=readme-ov-
file#plugins).
## Integration FAQs
[The SvelteKit FAQ](./faq) answers many questions about how to do X with SvelteKit,
which may be helpful if you still have questions.
## docs/kit/60-appendix/25-debugging.md
---
In addition to the [`@debug`](../svelte/@debug) tag, you can also debug Svelte and
SvelteKit projects using breakpoints within various tools and development
environments. This includes both frontend and backend code.
With the built-in debug terminal, you can set up breakpoints in source files within
VSCode.
```json
{
"version": "0.2.0",
"configurations": [
{
"command": "npm run dev",
"name": "Run development server",
"request": "launch",
"type": "node-terminal"
}
]
}
```
## Other Editors
If you use a different editor, these community guides might be useful for you:
1. Run the `--inspect` flag when starting the Vite server with Node.js. For
instance: `NODE_OPTIONS="--inspect" npm run dev`
2. Open your site in a new tab. Typically at `localhost:5173`.
3. Open your browser's dev tools, and click on the "Open dedicated DevTools for
Node.js" icon near the top-left. It should display the Node.js logo.
4. Set up breakpoints and debug your application.
## References
- [Debugging Node.js](https://nodejs.org/en/learn/getting-started/debugging)
## docs/kit/60-appendix/30-migrating-to-sveltekit-2.md
---
We highly recommend upgrading to the most recent 1.x version before upgrading to
2.0, so that you can take advantage of targeted deprecation warnings. We also
recommend [updating to Svelte 4](../svelte/v4-migration-guide) first: Later
versions of SvelteKit 1.x support it, and SvelteKit 2.0 requires it.
Previously, you had to `throw` the values returned from `error(...)` and
`redirect(...)` yourself. In SvelteKit 2 this is no longer the case — calling the
functions is sufficient.
```js
import { error } from '@sveltejs/kit'
// ...
throw error(500, 'something went wrong');
error(500, 'something went wrong');
```
If the error or redirect is thrown inside a `try {...}` block (hint: don't do
this!), you can distinguish them from unexpected errors using [`isHttpError`]
(@sveltejs-kit#isHttpError) and [`isRedirect`](@sveltejs-kit#isRedirect) imported
from `@sveltejs/kit`.
When receiving a `Set-Cookie` header that doesn't specify a `path`, browsers will
[set the cookie path](https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4) to the
parent of the resource in question. This behaviour isn't particularly helpful or
intuitive, and frequently results in bugs because the developer expected the cookie
to apply to the domain as a whole.
```js
/** @type {import('./$types').PageServerLoad} */
export function load({ cookies }) {
cookies.set(name, value,{ path: '/' });
return { response }
}
```
```js
// @filename: ambient.d.ts
declare const url: string;
// @filename: index.js
//cut
// If you have a single promise
/** @type {import('./$types').PageServerLoad} */
exportasyncfunction load({ fetch }) {
const response =awaitfetch(url).then(r => r.json());
return { response }
}
```
```js
// @filename: ambient.d.ts
declare const url1: string;
declare const url2: string;
// @filename: index.js
//cut
// If you have multiple promises
/** @type {import('./$types').PageServerLoad} */
exportasyncfunction load({ fetch }) {
const a = fetch(url1).then(r => r.json());
const b = fetch(url2).then(r => r.json());
const [a, b] = await Promise.all([
fetch(url1).then(r => r.json()),
fetch(url2).then(r => r.json()),
]);
return { a, b };
}
```
## goto(...) changes
Previously it was possible to track URLs from `fetch`es on the server in order to
rerun load functions. This poses a possible security risk (private URLs leaking),
and as such it was behind the `dangerZone.trackServerFetches` setting, which is now
removed.
This is fixed in SvelteKit 2 — in both cases, the path should be prefixed with
`base` if it is set.
Additionally, `preloadCode` now takes a single argument rather than _n_ arguments.
```js
import { resolvePath } from '@sveltejs/kit';
import { base } from '$app/paths';
import { resolveRoute } from '$app/paths';
`svelte-migrate` will do the method replacement for you, though if you later
prepend the result with `base`, you need to remove that yourself.
SvelteKit 2 cleans this up by calling `handleError` hooks with two new properties:
`status` and `message`. For errors thrown from your code (or library code called by
your code) the status will be `500` and the message will be `Internal Error`. While
`error.message` may contain sensitive information that should not be exposed to
users, `message` is safe.
During prerendering in SvelteKit 1, they are one and the same. As such, prerendered
pages that make use of 'dynamic' environment variables are really 'baking in' build
time values, which is incorrect. Worse, `$env/dynamic/public` is populated in the
browser with these stale values if the user happens to land on a prerendered page
before navigating to dynamically-rendered pages.
In SvelteKit 1, those properties included `form` and `data`. These were deprecated
some time ago in favour of `formElement` and `formData`, and have been removed
altogether in SvelteKit 2.
Previously, the generated `tsconfig.json` was trying its best to still produce a
somewhat valid config when your `tsconfig.json` included `paths` or `baseUrl`. In
SvelteKit 2, the validation is more strict and will warn when you use either
`paths` or `baseUrl` in your `tsconfig.json`. These settings are used to generate
path aliases and you should use [the `alias` config](configuration#alias) option in
your `svelte.config.js` instead, to also create a corresponding alias for the
bundler.
SvelteKit 2 requires Node `18.13` or higher, and the following minimum dependency
versions:
- `svelte@4`
- `vite@5`
- `typescript@5`
- `@sveltejs/vite-plugin-svelte@3` (this is now required as a `peerDependency` of
SvelteKit — previously it was directly depended upon)
- `@sveltejs/adapter-cloudflare@3` (if you're using these adapters)
- `@sveltejs/adapter-cloudflare-workers@2`
- `@sveltejs/adapter-netlify@3`
- `@sveltejs/adapter-node@2`
- `@sveltejs/adapter-static@3`
- `@sveltejs/adapter-vercel@4`
As part of the TypeScript upgrade, the generated `tsconfig.json` (the one your
`tsconfig.json` extends from) now uses `"moduleResolution": "bundler"` (which is
recommended by the TypeScript team, as it properly resolves types from packages
with an `exports` map in package.json) and `verbatimModuleSyntax` (which replaces
the existing `importsNotUsedAsValues ` and `preserveValueImports` flags — if you
have those in your `tsconfig.json`, remove them. `svelte-migrate` will do this for
you).
```svelte
<script>
import { page } from '$app/stores';
import { page } from '$app/state';
</script>
{$page.data}
{page.data}
```
## docs/kit/60-appendix/40-migrating.md
---
SvelteKit is the successor to Sapper and shares many elements of its design.
If you have an existing Sapper app that you plan to migrate to SvelteKit, there are
a number of changes you will need to make. You may find it helpful to view [some
examples](additional-resources#Examples) while migrating.
## package.json
Add `"type": "module"` to your `package.json`. You can do this step separately from
the rest as part of an incremental migration if you are using Sapper 0.29.3
or newer.
### dependencies
Remove `polka` or `express`, if you're using one of those, and any middleware such
as `sirv` or `compression`.
### devDependencies
Remove `sapper` from your `devDependencies` and replace it with `@sveltejs/kit` and
whichever [adapter](adapters) you plan to use (see [next section]
(migrating#Project-files-Configuration)).
### scripts
- `sapper build` should become `vite build` using the Node [adapter](adapters)
- `sapper export` should become `vite build` using the static [adapter](adapters)
- `sapper dev` should become `vite dev`
- `node __sapper__/build` should become `node build`
## Project files
The bulk of your app, in `src/routes`, can be left where it is, but several project
files will need to be moved or updated.
### Configuration
If you were using plugins for filetypes that are not automatically handled by
[Vite](https://vitejs.dev), you will need to find Vite equivalents and add them to
the [Vite config](project-structure#Project-files-vite.config.js).
### src/client.js
### src/server.js
### src/service-worker.js
- `files` is unchanged
- `routes` has been removed
- `shell` is now `build`
- `timestamp` is now `version`
### src/template.html
### src/node_modules
| Old | New |
| ------------------------- | ------------------------- |
| routes/about/index.svelte | routes/about/+page.svelte |
| routes/about.svelte | routes/about/+page.svelte |
### Imports
The `stores` import from `@sapper/app` should be replaced — see the [Stores]
(migrating#Pages-and-layouts-Stores) section below.
Any files you previously imported from directories in `src/node_modules` will need
to be replaced with [`$lib`]($lib) imports.
### Preload
As before, pages and layouts can export a function that allows data to be loaded
before rendering takes place.
This function has been renamed from `preload` to [`load`](load), it now lives in a
`+page.js` (or `+layout.js`) next to its `+page.svelte` (or `+layout.svelte`), and
its API has changed. Instead of two arguments — `page` and `session` — there is a
single `event` argument.
### Stores
```js
// @filename: ambient.d.ts
declare module '@sapper/app';
// @filename: index.js
//cut
import { stores } from '@sapper/app';
const { preloading, page, session } = stores();
```
The `page` store still exists; `preloading` has been replaced with a `navigating`
store that contains `from` and `to` properties. `page` now has `url` and `params`
properties, but no `path` or `query`.
You access them differently in SvelteKit. `stores` is now `getStores`, but in most
cases it is unnecessary since you can import `navigating`, and `page` directly from
[`$app/stores`]($app-stores). If you're on Svelte 5 and SvelteKit 2.12 or higher,
consider using [`$app/state`]($app-state) instead.
### Routing
Regex routes are no longer supported. Instead, use [advanced route matching]
(advanced-routing#Matching).
### Segments
### URLs
In Sapper, all relative URLs were resolved against the base URL — usually `/`,
unless the `basepath` option was used — rather than against the current page.
This caused problems and is no longer the case in SvelteKit. Instead, relative URLs
are resolved against the current page (or the destination page, for `fetch` URLs in
`load` functions) instead. In most cases, it's easier to use root-relative (i.e.
starts with `/`) URLs, since their meaning is not context-dependent.
## Endpoints
## Integrations
Sapper includes `html-minifier` by default. SvelteKit does not include this, but
you can add it as a prod dependency and then use it through a [hook](hooks#Server-
hooks-handle):
```js
// @filename: ambient.d.ts
/// <reference types="@sveltejs/kit" />
declare module 'html-minifier';
// @filename: index.js
//cut
import { minify } from 'html-minifier';
import { building } from '$app/environment';
const minification_options = {
collapseBooleanAttributes: true,
collapseWhitespace: true,
conservativeCollapse: true,
decodeEntities: true,
html5: true,
ignoreCustomComments: [/^#/],
minifyCSS: true,
minifyJS: false,
removeAttributeQuotes: true,
removeComments: false, // some hydration code needs comments, so leave them
in
removeOptionalTags: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortAttributes: true,
sortClassName: true
};
return resolve(event, {
transformPageChunk: ({ html, done }) => {
page += html;
if (done) {
return building ? minify(page, minification_options) :
page;
}
}
});
}
```
Note that `prerendering` is `false` when using `vite preview` to test the
production build of the site, so to verify the results of minifying, you'll need to
inspect the built HTML files directly.
## docs/kit/60-appendix/50-additional-resources.md
---
## FAQs
Please see the [SvelteKit FAQ](faq) for solutions to common issues and helpful tips
and tricks.
The [Svelte FAQ](../svelte/faq) and [`vite-plugin-svelte`
FAQ](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md) may also
be helpful for questions deriving from those libraries.
## Examples
SvelteKit users have also published plenty of examples on GitHub, under the
[#sveltekit](https://github.com/topics/sveltekit) and [#sveltekit-template]
(https://github.com/topics/sveltekit-template) topics, as well as on [the Svelte
Society site](https://sveltesociety.dev/templates?category=sveltekit). Note that
these have not been vetted by the maintainers and may not be up to date.
## Support
## docs/kit/60-appendix/60-glossary.md
---
title: Glossary
---
The core of SvelteKit provides a highly configurable rendering engine. This section
describes some of the terms used when discussing rendering. A reference for setting
these options is provided in the documentation above.
## CSR
Client-side rendering (CSR) is the generation of the page contents in the web
browser using JavaScript.
In SvelteKit, client-side rendering will be used by default, but you can turn off
JavaScript with [the `csr = false` page option](page-options#csr).
## Edge
## Hydration
Svelte components store some state and update the DOM when the state is updated.
When fetching data during SSR, by default SvelteKit will store this data and
transmit it to the client along with the server-rendered HTML. The components can
then be initialized on the client with that data without having to call the same
API endpoints again. Svelte will then check that the DOM is in the expected state
and attach event listeners in a process called hydration. Once the components are
fully hydrated, they can react to changes to their properties just like any newly
created Svelte component.
In SvelteKit, pages will be hydrated by default, but you can turn off JavaScript
with [the `csr = false` page option](page-options#csr).
## ISR
Incremental static regeneration (ISR) allows you to generate static pages on your
site as visitors request those pages without redeploying. This may reduces build
times compared to [SSG](#SSG) sites with a large number of pages. You can do [ISR
with `adapter-vercel`](adapter-vercel#Incremental-Static-Regeneration).
## MPA
Traditional applications that render each page view on the server — such as those
written in languages other than JavaScript — are often referred to as multi-page
apps (MPA).
## Prerendering
Prerendering means computing the contents of a page at build time and saving the
HTML for display. This approach has the same benefits as traditional server-
rendered pages, but avoids recomputing the page for each visitor and so scales
nearly for free as the number of visitors increases. The tradeoff is that the build
process is more expensive and prerendered content can only be updated by building
and deploying a new version of the application.
Not all pages can be prerendered. The basic rule is this: for content to be
prerenderable, any two users hitting it directly must get the same content from the
server, and the page must not contain [actions](form-actions). Note that you can
still prerender content that is loaded based on the page's parameters as long as
all users will be seeing the same prerendered content.
Pre-rendered pages are not limited to static content. You can build personalized
pages if user-specific data is fetched and rendered client-side. This is subject to
the caveat that you will experience the downsides of not doing SSR for that content
as discussed above.
In SvelteKit, you can control prerendering with [the `prerender` page option](page-
options#prerender) and [`prerender` config](configuration#prerender) in
`svelte.config.js`.
## PWA
A progressive web app (PWA) is an app that's built using web APIs and technologies,
but functions like a mobile or desktop app. Sites served as [PWAs can be installed]
(https://web.dev/learn/pwa/installation), allowing you to add a shortcut to the
application on your launcher, home screen, or start menu. Many PWAs will utilize
[service workers](service-workers) to build offline capabilities.
## Routing
By default, when you navigate to a new page (by clicking on a link or using the
browser's forward or back buttons), SvelteKit will intercept the attempted
navigation and handle it instead of allowing the browser to send a request to the
server for the destination page. SvelteKit will then update the displayed contents
on the client by rendering the component for the new page, which in turn can make
calls to the necessary API endpoints. This process of updating the page on the
client in response to attempted navigation is called client-side routing.
In SvelteKit, client-side routing will be used by default, but you can skip it with
[`data-sveltekit-reload`](link-options#data-sveltekit-reload).
## SPA
A single-page app (SPA) is an application in which all requests to the server load
a single HTML file which then does client-side rendering of the requested contents
based on the requested URL. All navigation is handled on the client-side in a
process called client-side routing with per-page contents being updated and common
layout elements remaining largely unchanged. SPAs do not provide SSR and thus have
worse performance and SEO characteristics. However, some applications are not
greatly impacted by these shortcomings such as a complex business application
behind a login where SEO would not be important and it is known that users will be
accessing the application from a consistent computing environment.
## SSG
Static Site Generation (SSG) is a term that refers to a site where every page is
prerendered. One benefit of fully prerendering a site is that you do not need to
maintain or pay for servers to perform SSR. Once generated, the site can be served
from CDNs, leading to great “time to first byte” performance. This delivery model
is often referred to as JAMstack.
## SSR
Server-side rendering (SSR) is the generation of the page contents on the server.
SSR is generally preferred for SEO. While some search engines can index content
that is dynamically generated on the client-side it may take longer even in these
cases. It also tends to improve perceived performance and makes your app accessible
to users if JavaScript fails or is disabled (which happens [more often than you
probably think](https://kryogenix.org/code/browser/everyonehasjs.html)).
In SvelteKit, pages are server-side rendered by default. You can disable SSR with
[the `ssr` page option](page-options#ssr).
## docs/kit/98-reference/index.md
---
title: Reference
---
## docs/kit/98-reference/10-@sveltejs-kit.md
---
title: @sveltejs/kit
---
```js
// @noErrors
import {
Server,
VERSION,
error,
fail,
isActionFailure,
isHttpError,
isRedirect,
json,
normalizeUrl,
redirect,
text
} from '@sveltejs/kit';
```
## Server
<div class="ts-block">
```dts
class Server {/*…*/}
```
<div class="ts-block-property">
```dts
constructor(manifest: SSRManifest);
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
init(options: ServerInitOptions): Promise<void>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
respond(request: Request, options: RequestOptions): Promise<Response>;
```
<div class="ts-block-property-details"></div>
</div></div>
## VERSION
<div class="ts-block">
```dts
const VERSION: string;
```
</div>
## error
<div class="ts-block">
```dts
function error(status: number, body: App.Error): never;
```
</div>
<div class="ts-block">
```dts
function error(
status: number,
body?: {
message: string;
} extends App.Error
? App.Error | string | undefined
: never
): never;
```
</div>
## fail
<div class="ts-block">
```dts
function fail(status: number): ActionFailure<undefined>;
```
</div>
<div class="ts-block">
```dts
function fail<
T extends Record<string, unknown> | undefined = undefined
>(status: number, data: T): ActionFailure<T>;
```
</div>
## isActionFailure
<div class="ts-block">
```dts
function isActionFailure(e: unknown): e is ActionFailure;
```
</div>
## isHttpError
<div class="ts-block">
```dts
function isHttpError<T extends number>(
e: unknown,
status?: T | undefined
): e is HttpError_1 & {
status: T extends undefined ? never : T;
};
```
</div>
## isRedirect
<div class="ts-block">
```dts
function isRedirect(e: unknown): e is Redirect_1;
```
</div>
## json
```dts
function json(
data: any,
init?: ResponseInit | undefined
): Response;
```
</div>
## normalizeUrl
</blockquote>
Strips possible SvelteKit-internal suffixes and trailing slashes from the URL
pathname.
Returns the normalized URL as well as a method for adding the potential suffix back
based on a new pathname (possibly including search) or URL.
```js
// @errors: 7031
import { normalizeUrl } from '@sveltejs/kit';
<div class="ts-block">
```dts
function normalizeUrl(url: URL | string): {
url: URL;
wasNormalized: boolean;
denormalize: (url?: string | URL) => URL;
};
```
</div>
## redirect
Redirect a request. When called during request handling, SvelteKit will return a
redirect response.
Make sure you're not catching the thrown redirect, which would prevent SvelteKit
from handling it.
<div class="ts-block">
```dts
function redirect(
status:
| 300
| 301
| 302
| 303
| 304
| 305
| 306
| 307
| 308
| ({} & number),
location: string | URL
): never;
```
</div>
## text
<div class="ts-block">
```dts
function text(
body: string,
init?: ResponseInit | undefined
): Response;
```
</div>
## Action
Shape of a form action method that is part of `export const actions = {..}` in
`+page.server.js`.
See [form actions](/docs/kit/form-actions) for more information.
<div class="ts-block">
```dts
type Action<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
OutputData extends Record<string, any> | void = Record<
string,
any
> | void,
RouteId extends string | null = string | null
> = (
event: RequestEvent<Params, RouteId>
) => MaybePromise<OutputData>;
```
</div>
## ActionFailure
<div class="ts-block">
```dts
interface ActionFailure<
T extends Record<string, unknown> | undefined = undefined
> {/*…*/}
```
<div class="ts-block-property">
```dts
status: number;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
data: T;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
[uniqueSymbol]: true;
```
<div class="ts-block-property-details"></div>
</div></div>
## ActionResult
When calling a form action via fetch, the response will be one of these shapes.
```svelte
<form method="post" use:enhance={() => {
return ({ result }) => {
// result is of type ActionResult
};
}}
```
<div class="ts-block">
```dts
type ActionResult<
Success extends
| Record<string, unknown>
| undefined = Record<string, any>,
Failure extends
| Record<string, unknown>
| undefined = Record<string, any>
> =
| { type: 'success'; status: number; data?: Success }
| { type: 'failure'; status: number; data?: Failure }
| { type: 'redirect'; status: number; location: string }
| { type: 'error'; status?: number; error: any };
```
</div>
## Actions
<div class="ts-block">
```dts
type Actions<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
OutputData extends Record<string, any> | void = Record<
string,
any
> | void,
RouteId extends string | null = string | null
> = Record<string, Action<Params, OutputData, RouteId>>;
```
</div>
## Adapter
<div class="ts-block">
```dts
interface Adapter {/*…*/}
```
<div class="ts-block-property">
```dts
name: string;
```
<div class="ts-block-property-details">
The name of the adapter, using for logging. Will typically correspond to the
package name.
</div>
</div>
<div class="ts-block-property">
```dts
adapt: (builder: Builder) => MaybePromise<void>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `builder` An object provided by SvelteKit that contains methods for adapting the
app
</div>
</div>
</div>
<div class="ts-block-property">
```dts
supports?: {/*…*/}
```
<div class="ts-block-property-details">
Checks called during dev and build to determine whether specific features will work
in production with this adapter
```dts
read?: (details: { config: any; route: { id: string } }) => boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
emulate?: () => MaybePromise<Emulator>;
```
<div class="ts-block-property-details">
</div>
</div></div>
## AfterNavigate
<div class="ts-block">
```dts
interface AfterNavigate extends Omit<Navigation, 'type'> {/*…*/}
```
<div class="ts-block-property">
```dts
type: Exclude<NavigationType, 'leave'>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
willUnload: false;
```
<div class="ts-block-property-details">
Since `afterNavigate` callbacks are called after a navigation completes, they will
never be called with a navigation that unloads the page.
</div>
</div></div>
## AwaitedActions
<div class="ts-block">
```dts
type AwaitedActions<
T extends Record<string, (...args: any) => any>
> = OptionalUnion<
{
[Key in keyof T]: UnpackValidationError<
Awaited<ReturnType<T[Key]>>
>;
}[keyof T]
>;
```
</div>
## BeforeNavigate
<div class="ts-block">
```dts
interface BeforeNavigate extends Navigation {/*…*/}
```
<div class="ts-block-property">
```dts
cancel: () => void;
```
<div class="ts-block-property-details">
</div>
</div></div>
## Builder
<div class="ts-block">
```dts
interface Builder {/*…*/}
```
<div class="ts-block-property">
```dts
log: Logger;
```
<div class="ts-block-property-details">
Print messages to the console. `log.info` and `log.minor` are silent unless Vite's
`logLevel` is `info`.
</div>
</div>
<div class="ts-block-property">
```dts
rimraf: (dir: string) => void;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
mkdirp: (dir: string) => void;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
config: ValidatedConfig;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
prerendered: Prerendered;
```
<div class="ts-block-property-details">
<div class="ts-block-property">
```dts
routes: RouteDefinition[];
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
createEntries: (fn: (route: RouteDefinition) => AdapterEntry) => Promise<void>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Create separate functions that map to one or more routes of your app.
</div>
</div>
<div class="ts-block-property">
```dts
findServerAssets: (routes: RouteDefinition[]) => string[];
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
generateFallback: (dest: string) => Promise<void>;
```
<div class="ts-block-property-details">
Generate a fallback page for a static webserver to use when no route is matched.
Useful for single-page apps.
</div>
</div>
<div class="ts-block-property">
```dts
generateEnvModule: () => void;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
generateManifest: (opts: { relativePath: string; routes?: RouteDefinition[] }) =>
string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `opts` a relative path to the base directory of the app and optionally in which
format (esm or cjs) the manifest should be generated
</div>
</div>
</div>
<div class="ts-block-property">
```dts
getBuildDirectory: (name: string) => string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
getClientDirectory: () => string;
```
<div class="ts-block-property-details">
Get the fully resolved path to the directory containing client-side assets,
including the contents of your `static` directory.
</div>
</div>
<div class="ts-block-property">
```dts
getServerDirectory: () => string;
```
<div class="ts-block-property-details">
Get the fully resolved path to the directory containing server-side code.
</div>
</div>
<div class="ts-block-property">
```dts
getAppPath: () => string;
```
<div class="ts-block-property-details">
Get the application path including any configured `base` path, e.g.
`my-base-path/_app`.
</div>
</div>
<div class="ts-block-property">
```dts
writeClient: (dest: string) => string[];
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property">
```dts
writePrerendered: (dest: string) => string[];
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
writeServer: (dest: string) => string[];
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
copy: (
from: string,
to: string,
opts?: {
filter?(basename: string): boolean;
replace?: Record<string, string>;
}
) => string[];
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `from` the source file or directory
- `to` the destination file or directory
- `opts.filter` a function to determine whether a file or directory should be
copied
- `opts.replace` a map of strings to replace
- <span class="tag">returns</span> an array of files that were copied
</div>
</div>
</div>
<div class="ts-block-property">
```dts
compress: (directory: string) => Promise<void>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Compress files in `directory` with gzip and brotli, where appropriate. Generates
`.gz` and `.br` files alongside the originals.
</div>
</div></div>
## ClientInit
</blockquote>
<div class="ts-block">
```dts
type ClientInit = () => MaybePromise<void>;
```
</div>
## Config
## Cookies
<div class="ts-block">
```dts
interface Cookies {/*…*/}
```
<div class="ts-block-property">
```dts
get: (name: string, opts?: import('cookie').CookieParseOptions) => string |
undefined;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Gets a cookie that was previously set with `cookies.set`, or from the request
headers.
</div>
</div>
<div class="ts-block-property">
```dts
getAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string;
value: string }>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Gets all cookies that were previously set with `cookies.set`, or from the request
headers.
</div>
</div>
<div class="ts-block-property">
```dts
set: (
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
) => void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Sets a cookie. This will add a `set-cookie` header to the response, but also make
the cookie available via `cookies.get` or `cookies.getAll` during the current
request.
You must specify a `path` for the cookie. In most cases you should explicitly set
`path: '/'` to make the cookie available throughout your app. You can use relative
paths, or set `path: ''` to make the cookie only available on the current path and
its children
</div>
</div>
<div class="ts-block-property">
```dts
delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path:
string }) => void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Deletes a cookie by setting its value to an empty string and setting the expiry
date in the past.
You must specify a `path` for the cookie. In most cases you should explicitly set
`path: '/'` to make the cookie available throughout your app. You can use relative
paths, or set `path: ''` to make the cookie only available on the current path and
its children
</div>
</div>
<div class="ts-block-property">
```dts
serialize: (
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
) => string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't
apply it to the response.
You must specify a `path` for the cookie. In most cases you should explicitly set
`path: '/'` to make the cookie available throughout your app. You can use relative
paths, or set `path: ''` to make the cookie only available on the current path and
its children
</div>
</div></div>
## Emulator
A collection of functions that influence the environment during dev, build and
prerendering
<div class="ts-block">
```dts
interface Emulator {/*…*/}
```
<div class="ts-block-property">
```dts
platform?(details: { config: any; prerender: PrerenderOption }):
MaybePromise<App.Platform>;
```
<div class="ts-block-property-details">
A function that is called with the current route `config` and `prerender` option
and returns an `App.Platform` object
</div>
</div></div>
## Handle
<div class="ts-block">
```dts
type Handle = (input: {
event: RequestEvent;
resolve: (
event: RequestEvent,
opts?: ResolveOptions
) => MaybePromise<Response>;
}) => MaybePromise<Response>;
```
</div>
## HandleClientError
<div class="ts-block">
```dts
type HandleClientError = (input: {
error: unknown;
event: NavigationEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;
```
</div>
## HandleFetch
<div class="ts-block">
```dts
type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>;
```
</div>
## HandleServerError
<div class="ts-block">
```dts
type HandleServerError = (input: {
error: unknown;
event: RequestEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;
```
</div>
## HttpError
<div class="ts-block">
```dts
interface HttpError {/*…*/}
```
<div class="ts-block-property">
```dts
status: number;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
body: App.Error;
```
<div class="ts-block-property-details">
</div>
</div></div>
## KitConfig
## LessThan
<div class="ts-block">
```dts
type LessThan<
TNumber extends number,
TArray extends any[] = []
> = TNumber extends TArray['length']
? TArray[number]
: LessThan<TNumber, [...TArray, TArray['length']]>;
```
</div>
## Load
The generic form of `PageLoad` and `LayoutLoad`. You should import those from
`./$types` (see [generated types](/docs/kit/types#Generated-types))
rather than using `Load` directly.
<div class="ts-block">
```dts
type Load<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
InputData extends Record<string, unknown> | null = Record<
string,
any
> | null,
ParentData extends Record<string, unknown> = Record<
string,
any
>,
OutputData extends Record<
string,
unknown
> | void = Record<string, any> | void,
RouteId extends string | null = string | null
> = (
event: LoadEvent<Params, InputData, ParentData, RouteId>
) => MaybePromise<OutputData>;
```
</div>
## LoadEvent
The generic form of `PageLoadEvent` and `LayoutLoadEvent`. You should import those
from `./$types` (see [generated types](/docs/kit/types#Generated-types))
rather than using `LoadEvent` directly.
<div class="ts-block">
```dts
interface LoadEvent<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
Data extends Record<string, unknown> | null = Record<
string,
any
> | null,
ParentData extends Record<string, unknown> = Record<
string,
any
>,
RouteId extends string | null = string | null
> extends NavigationEvent<Params, RouteId> {/*…*/}
```
<div class="ts-block-property">
```dts
fetch: typeof fetch;
```
<div class="ts-block-property-details">
You can learn more about making credentialed requests with cookies
[here](/docs/kit/load#Cookies)
</div>
</div>
<div class="ts-block-property">
```dts
data: Data;
```
<div class="ts-block-property-details">
Contains the data returned by the route's server `load` function (in
`+layout.server.js` or `+page.server.js`), if any.
</div>
</div>
<div class="ts-block-property">
```dts
setHeaders: (headers: Record<string, string>) => void;
```
<div class="ts-block-property-details">
If you need to set headers for the response, you can do so using the this method.
This is useful if you want the page to be cached, for example:
```js
// @errors: 7031
/// file: src/routes/blog/+page.js
export async function load({ fetch, setHeaders }) {
const url = `https://cms.example.com/articles.json`;
const response = await fetch(url);
setHeaders({
age: response.headers.get('age'),
'cache-control': response.headers.get('cache-control')
});
return response.json();
}
```
Setting the same header multiple times (even in separate `load` functions) is an
error — you can only set a given header once.
</div>
</div>
<div class="ts-block-property">
```dts
parent: () => Promise<ParentData>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
depends: (...deps: Array<`${string}:${string}`>) => void;
```
<div class="ts-block-property-details">
This function declares that the `load` function has a _dependency_ on one or more
URLs or custom identifiers, which can subsequently be used with
[`invalidate()`](/docs/kit/$app-navigation#invalidate) to cause `load` to rerun.
Most of the time you won't need this, as `fetch` calls `depends` on your behalf —
it's only necessary if you're using a custom API client that bypasses `fetch`.
URLs can be absolute or relative to the page being loaded, and must be [encoded]
(https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).
Custom identifiers have to be prefixed with one or more lowercase letters followed
by a colon to conform to the [URI
specification](https://www.rfc-editor.org/rfc/rfc3986.html).
```js
// @errors: 7031
/// file: src/routes/+page.js
let count = 0;
export async function load({ depends }) {
depends('increase:count');
```html
/// file: src/routes/+page.svelte
<script>
import { invalidate } from '$app/navigation';
<p>{data.count}<p>
<button on:click={increase}>Increase Count</button>
```
</div>
</div>
<div class="ts-block-property">
```dts
untrack: <T>(fn: () => T) => T;
```
<div class="ts-block-property-details">
Use this function to opt out of dependency tracking for everything that is
synchronously called within the callback. Example:
```js
// @errors: 7031
/// file: src/routes/+page.server.js
export async function load({ untrack, url }) {
// Untrack url.pathname so that path changes don't trigger a rerun
if (untrack(() => url.pathname === '/')) {
return { message: 'Welcome!' };
}
}
```
</div>
</div></div>
## LoadProperties
<div class="ts-block">
```dts
type LoadProperties<
input extends Record<string, any> | void
> = input extends void
? undefined // needs to be undefined, because void will break intellisense
: input extends Record<string, any>
? input
: unknown;
```
</div>
## Navigation
<div class="ts-block">
```dts
interface Navigation {/*…*/}
```
<div class="ts-block-property">
```dts
from: NavigationTarget | null;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
to: NavigationTarget | null;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
type: Exclude<NavigationType, 'enter'>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
willUnload: boolean;
```
<div class="ts-block-property-details">
Whether or not the navigation will result in the page being unloaded (i.e. not a
client-side navigation)
</div>
</div>
<div class="ts-block-property">
```dts
delta?: number;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
complete: Promise<void>;
```
<div class="ts-block-property-details">
A promise that resolves once the navigation is complete, and rejects if the
navigation
fails or is aborted. In the case of a `willUnload` navigation, the promise will
never resolve
</div>
</div></div>
## NavigationEvent
<div class="ts-block">
```dts
interface NavigationEvent<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
RouteId extends string | null = string | null
> {/*…*/}
```
<div class="ts-block-property">
```dts
params: Params;
```
<div class="ts-block-property-details">
The parameters of the current page - e.g. for a route like `/blog/[slug]`, a
`{ slug: string }` object
</div>
</div>
<div class="ts-block-property">
```dts
route: {/*…*/}
```
<div class="ts-block-property-details">
```dts
id: RouteId;
```
<div class="ts-block-property-details">
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
url: URL;
```
<div class="ts-block-property-details">
</div>
</div></div>
## NavigationTarget
<div class="ts-block">
```dts
interface NavigationTarget {/*…*/}
```
<div class="ts-block-property">
```dts
params: Record<string, string> | null;
```
<div class="ts-block-property-details">
Parameters of the target page - e.g. for a route like `/blog/[slug]`, a `{ slug:
string }` object.
Is `null` if the target is not part of the SvelteKit app (could not be resolved to
a route).
</div>
</div>
<div class="ts-block-property">
```dts
route: {/*…*/}
```
<div class="ts-block-property-details">
```dts
id: string | null;
```
<div class="ts-block-property-details">
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
url: URL;
```
<div class="ts-block-property-details">
</div>
</div></div>
## NavigationType
<div class="ts-block">
```dts
type NavigationType =
| 'enter'
| 'form'
| 'leave'
| 'link'
| 'goto'
| 'popstate';
```
</div>
## NumericRange
<div class="ts-block">
```dts
type NumericRange<
TStart extends number,
TEnd extends number
> = Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>;
```
</div>
## OnNavigate
<div class="ts-block">
```dts
interface OnNavigate extends Navigation {/*…*/}
```
<div class="ts-block-property">
```dts
type: Exclude<NavigationType, 'enter' | 'leave'>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
willUnload: false;
```
<div class="ts-block-property-details">
</div>
</div></div>
## Page
<div class="ts-block">
```dts
interface Page<
Params extends Record<string, string> = Record<
string,
string
>,
RouteId extends string | null = string | null
> {/*…*/}
```
<div class="ts-block-property">
```dts
url: URL;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
params: Params;
```
<div class="ts-block-property-details">
The parameters of the current page - e.g. for a route like `/blog/[slug]`, a
`{ slug: string }` object.
</div>
</div>
<div class="ts-block-property">
```dts
route: {/*…*/}
```
<div class="ts-block-property-details">
Info about the current route.
```dts
id: RouteId;
```
<div class="ts-block-property-details">
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```dts
status: number;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
error: App.Error | null;
```
<div class="ts-block-property-details">
The error object of the current page, if any. Filled from the `handleError` hooks.
</div>
</div>
<div class="ts-block-property">
```dts
data: App.PageData & Record<string, any>;
```
<div class="ts-block-property-details">
The merged result of all data from all `load` functions on the current page. You
can type a common denominator through `App.PageData`.
</div>
</div>
<div class="ts-block-property">
```dts
state: App.PageState;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
form: any;
```
<div class="ts-block-property-details">
</div>
</div></div>
## ParamMatcher
<div class="ts-block">
```dts
type ParamMatcher = (param: string) => boolean;
```
</div>
## PrerenderOption
<div class="ts-block">
```dts
type PrerenderOption = boolean | 'auto';
```
</div>
## Redirect
<div class="ts-block">
```dts
interface Redirect {/*…*/}
```
<div class="ts-block-property">
```dts
status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
location: string;
```
<div class="ts-block-property-details">
</div>
</div></div>
## RequestEvent
<div class="ts-block">
```dts
interface RequestEvent<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
RouteId extends string | null = string | null
> {/*…*/}
```
<div class="ts-block-property">
```dts
cookies: Cookies;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
fetch: typeof fetch;
```
<div class="ts-block-property-details">
You can learn more about making credentialed requests with cookies
[here](/docs/kit/load#Cookies).
</div>
</div>
<div class="ts-block-property">
```dts
getClientAddress: () => string;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
locals: App.Locals;
```
<div class="ts-block-property-details">
Contains custom data that was added to the request within the [`server handle
hook`](/docs/kit/hooks#Server-hooks-handle).
</div>
</div>
<div class="ts-block-property">
```dts
params: Params;
```
<div class="ts-block-property-details">
The parameters of the current route - e.g. for a route like `/blog/[slug]`, a
`{ slug: string }` object.
</div>
</div>
<div class="ts-block-property">
```dts
platform: Readonly<App.Platform> | undefined;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
request: Request;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
route: {/*…*/}
```
<div class="ts-block-property-details">
```dts
id: RouteId;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
setHeaders: (headers: Record<string, string>) => void;
```
<div class="ts-block-property-details">
If you need to set headers for the response, you can do so using the this method.
This is useful if you want the page to be cached, for example:
```js
// @errors: 7031
/// file: src/routes/blog/+page.js
export async function load({ fetch, setHeaders }) {
const url = `https://cms.example.com/articles.json`;
const response = await fetch(url);
setHeaders({
age: response.headers.get('age'),
'cache-control': response.headers.get('cache-control')
});
return response.json();
}
```
Setting the same header multiple times (even in separate `load` functions) is an
error — you can only set a given header once.
</div>
</div>
<div class="ts-block-property">
```dts
url: URL;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
isDataRequest: boolean;
```
<div class="ts-block-property-details">
`true` if the request comes from the client asking for `+page/layout.server.js`
data. The `url` property will be stripped of the internal information
related to the data request in this case. Use this property instead if the
distinction is important to you.
</div>
</div>
<div class="ts-block-property">
```dts
isSubRequest: boolean;
```
<div class="ts-block-property-details">
`true` for `+server.js` calls coming from SvelteKit without the overhead of
actually making an HTTP request. This happens when you make same-origin `fetch`
requests on the server.
</div>
</div></div>
## RequestHandler
It receives `Params` as the first generic argument, which you can skip by using
[generated types](/docs/kit/types#Generated-types) instead.
<div class="ts-block">
```dts
type RequestHandler<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
RouteId extends string | null = string | null
> = (
event: RequestEvent<Params, RouteId>
) => MaybePromise<Response>;
```
</div>
## Reroute
</blockquote>
The [`reroute`](/docs/kit/hooks#Universal-hooks-reroute) hook allows you to modify
the URL before it is used to determine which route to render.
<div class="ts-block">
```dts
type Reroute = (event: {
url: URL;
fetch: typeof fetch;
}) => MaybePromise<void | string>;
```
</div>
## ResolveOptions
<div class="ts-block">
```dts
interface ResolveOptions {/*…*/}
```
<div class="ts-block-property">
```dts
transformPageChunk?: (input: { html: string; done: boolean }) =>
MaybePromise<string | undefined>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
- `input` the html chunk and the info if this is the last chunk
</div>
Applies custom transforms to HTML. If `done` is true, it's the final chunk. Chunks
are not guaranteed to be well-formed HTML
(they could include an element's opening tag but not its closing tag, for example)
but they will always be split at sensible boundaries such as `%sveltekit.head%` or
layout/page components.
</div>
</div>
<div class="ts-block-property">
```dts
filterSerializedResponseHeaders?: (name: string, value: string) => boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
<div class="ts-block-property">
```dts
preload?: (input: { type: 'font' | 'css' | 'js' | 'asset'; path: string }) =>
boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
## RouteDefinition
<div class="ts-block">
```dts
interface RouteDefinition<Config = any> {/*…*/}
```
<div class="ts-block-property">
```dts
id: string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
api: {
methods: Array<HttpMethod | '*'>;
};
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
page: {
methods: Array<Extract<HttpMethod, 'GET' | 'POST'>>;
};
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
pattern: RegExp;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
prerender: PrerenderOption;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
segments: RouteSegment[];
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
methods: Array<HttpMethod | '*'>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
config: Config;
```
<div class="ts-block-property-details"></div>
</div></div>
## SSRManifest
<div class="ts-block">
```dts
interface SSRManifest {/*…*/}
```
<div class="ts-block-property">
```dts
appDir: string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
appPath: string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
assets: Set<string>;
```
<div class="ts-block-property-details">
Static files from `kit.config.files.assets` and the service worker (if any).
</div>
</div>
<div class="ts-block-property">
```dts
mimeTypes: Record<string, string>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
_: {/*…*/}
```
<div class="ts-block-property-details">
private fields
```dts
client: NonNullable<BuildData['client']>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
nodes: SSRNodeLoader[];
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
routes: SSRRoute[];
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
prerendered_routes: Set<string>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
matchers: () => Promise<Record<string, ParamMatcher>>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
server_assets: Record<string, number>;
```
<div class="ts-block-property-details">
</div>
</div></div>
</div>
</div></div>
## ServerInit
</blockquote>
The [`init`](/docs/kit/hooks#Shared-hooks-init) will be invoked before the server
responds to its first request
<div class="ts-block">
```dts
type ServerInit = () => MaybePromise<void>;
```
</div>
## ServerInitOptions
<div class="ts-block">
```dts
interface ServerInitOptions {/*…*/}
```
<div class="ts-block-property">
```dts
env: Record<string, string>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
read?: (file: string) => ReadableStream;
```
<div class="ts-block-property-details">
A function that turns an asset filename into a `ReadableStream`. Required for the
`read` export from `$app/server` to work.
</div>
</div></div>
## ServerLoad
<div class="ts-block">
```dts
type ServerLoad<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
ParentData extends Record<string, any> = Record<
string,
any
>,
OutputData extends Record<string, any> | void = Record<
string,
any
> | void,
RouteId extends string | null = string | null
> = (
event: ServerLoadEvent<Params, ParentData, RouteId>
) => MaybePromise<OutputData>;
```
</div>
## ServerLoadEvent
<div class="ts-block">
```dts
interface ServerLoadEvent<
Params extends Partial<Record<string, string>> = Partial<
Record<string, string>
>,
ParentData extends Record<string, any> = Record<
string,
any
>,
RouteId extends string | null = string | null
> extends RequestEvent<Params, RouteId> {/*…*/}
```
<div class="ts-block-property">
```dts
parent: () => Promise<ParentData>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
depends: (...deps: string[]) => void;
```
<div class="ts-block-property-details">
This function declares that the `load` function has a _dependency_ on one or more
URLs or custom identifiers, which can subsequently be used with
[`invalidate()`](/docs/kit/$app-navigation#invalidate) to cause `load` to rerun.
Most of the time you won't need this, as `fetch` calls `depends` on your behalf —
it's only necessary if you're using a custom API client that bypasses `fetch`.
URLs can be absolute or relative to the page being loaded, and must be [encoded]
(https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).
Custom identifiers have to be prefixed with one or more lowercase letters followed
by a colon to conform to the [URI
specification](https://www.rfc-editor.org/rfc/rfc3986.html).
```js
// @errors: 7031
/// file: src/routes/+page.js
let count = 0;
export async function load({ depends }) {
depends('increase:count');
```html
/// file: src/routes/+page.svelte
<script>
import { invalidate } from '$app/navigation';
<p>{data.count}<p>
<button on:click={increase}>Increase Count</button>
```
</div>
</div>
<div class="ts-block-property">
```dts
untrack: <T>(fn: () => T) => T;
```
<div class="ts-block-property-details">
Use this function to opt out of dependency tracking for everything that is
synchronously called within the callback. Example:
```js
// @errors: 7031
/// file: src/routes/+page.js
export async function load({ untrack, url }) {
// Untrack url.pathname so that path changes don't trigger a rerun
if (untrack(() => url.pathname === '/')) {
return { message: 'Welcome!' };
}
}
```
</div>
</div></div>
## Snapshot
The type of `export const snapshot` exported from a page or layout component.
<div class="ts-block">
```dts
interface Snapshot<T = any> {/*…*/}
```
<div class="ts-block-property">
```dts
capture: () => T;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
restore: (snapshot: T) => void;
```
<div class="ts-block-property-details"></div>
</div></div>
## SubmitFunction
<div class="ts-block">
```dts
type SubmitFunction<
Success extends
| Record<string, unknown>
| undefined = Record<string, any>,
Failure extends
| Record<string, unknown>
| undefined = Record<string, any>
> = (input: {
action: URL;
formData: FormData;
formElement: HTMLFormElement;
controller: AbortController;
submitter: HTMLElement | null;
cancel: () => void;
}) => MaybePromise<
| void
| ((opts: {
formData: FormData;
formElement: HTMLFormElement;
action: URL;
result: ActionResult<Success, Failure>;
/**
* Call this to get the default behavior of a form submission
response.
* @param options Set `reset: false` if you don't want the
`<form>` values to be reset after a successful submission.
* @param invalidateAll Set `invalidateAll: false` if you don't
want the action to call `invalidateAll` after submission.
*/
update: (options?: {
reset?: boolean;
invalidateAll?: boolean;
}) => Promise<void>;
}) => MaybePromise<void>)
>;
```
</div>
## Transport
</blockquote>
Each transporter has a pair of `encode` and `decode` functions. On the server,
`encode` determines whether a value is an instance of the custom type and, if so,
returns a non-falsy encoding of the value which can be an object or an array (or
`false` otherwise).
In the browser, `decode` turns the encoding back into an instance of the custom
type.
```ts
import type { Transport } from '@sveltejs/kit';
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
```
<div class="ts-block">
```dts
type Transport = Record<string, Transporter>;
```
</div>
## Transporter
<div class="ts-block">
```dts
interface Transporter<
T = any,
U = Exclude<
any,
false | 0 | '' | null | undefined | typeof NaN
>
> {/*…*/}
```
<div class="ts-block-property">
```dts
encode: (value: T) => false | U;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
decode: (data: U) => T;
```
<div class="ts-block-property-details"></div>
</div></div>
## Private types
The following are referenced by the public types documented above, but cannot be
imported directly:
## AdapterEntry
<div class="ts-block">
```dts
interface AdapterEntry {/*…*/}
```
<div class="ts-block-property">
```dts
id: string;
```
<div class="ts-block-property-details">
A string that uniquely identifies an HTTP service (e.g. serverless function) and is
used for deduplication.
For example, `/foo/a-[b]` and `/foo/[c]` are different routes, but would both
be represented in a Netlify _redirects file as `/foo/:param`, so they share an ID
</div>
</div>
<div class="ts-block-property">
```dts
filter(route: RouteDefinition): boolean;
```
<div class="ts-block-property-details">
A function that compares the candidate route with the current route to determine
if it should be grouped with the current route.
Use cases:
- Fallback pages: `/foo/[c]` is a fallback for `/foo/a-[b]`, and `/[...catchall]`
is a fallback for all routes
- Grouping routes that share a common `config`: `/foo` should be deployed to the
edge, `/bar` and `/baz` should be deployed to a serverless function
</div>
</div>
<div class="ts-block-property">
```dts
complete(entry: { generateManifest(opts: { relativePath: string }): string }):
MaybePromise<void>;
```
<div class="ts-block-property-details">
A function that is invoked once the entry has been created. This is where you
should write the function to the filesystem and generate redirect manifests.
</div>
</div></div>
## Csp
<div class="ts-block">
```dts
namespace Csp {
type ActionSource = 'strict-dynamic' | 'report-sample';
type BaseSource =
| 'self'
| 'unsafe-eval'
| 'unsafe-hashes'
| 'unsafe-inline'
| 'wasm-unsafe-eval'
| 'none';
type CryptoSource =
`${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;
type FrameSource =
| HostSource
| SchemeSource
| 'self'
| 'none';
type HostNameScheme = `${string}.${string}` | 'localhost';
type HostSource =
`${HostProtocolSchemes}${HostNameScheme}${PortScheme}`;
type HostProtocolSchemes = `${string}://` | '';
type HttpDelineator = '/' | '?' | '#' | '\\';
type PortScheme = `:${number}` | '' | ':*';
type SchemeSource =
| 'http:'
| 'https:'
| 'data:'
| 'mediastream:'
| 'blob:'
| 'filesystem:';
type Source =
| HostSource
| SchemeSource
| CryptoSource
| BaseSource;
type Sources = Source[];
}
```
</div>
## CspDirectives
<div class="ts-block">
```dts
interface CspDirectives {/*…*/}
```
<div class="ts-block-property">
```dts
'child-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'default-src'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'frame-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'worker-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'connect-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'font-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'img-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'manifest-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'media-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'object-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'prefetch-src'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'script-src'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'script-src-elem'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'script-src-attr'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'style-src'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'style-src-elem'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'style-src-attr'?: Csp.Sources;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'base-uri'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
sandbox?: Array<
| 'allow-downloads-without-user-activation'
| 'allow-forms'
| 'allow-modals'
| 'allow-orientation-lock'
| 'allow-pointer-lock'
| 'allow-popups'
| 'allow-popups-to-escape-sandbox'
| 'allow-presentation'
| 'allow-same-origin'
| 'allow-scripts'
| 'allow-storage-access-by-user-activation'
| 'allow-top-navigation'
| 'allow-top-navigation-by-user-activation'
>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'form-action'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'frame-ancestors'?: Array<Csp.HostSource | Csp.SchemeSource | Csp.FrameSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'navigate-to'?: Array<Csp.Source | Csp.ActionSource>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'report-uri'?: string[];
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'report-to'?: string[];
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'require-trusted-types-for'?: Array<'script'>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'trusted-types'?: Array<'none' | 'allow-duplicates' | '*' | string>;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'upgrade-insecure-requests'?: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
'require-sri-for'?: Array<'script' | 'style' | 'script style'>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
'block-all-mixed-content'?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
'plugin-types'?: Array<`${string}/${string}` | 'none'>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
referrer?: Array<
| 'no-referrer'
| 'no-referrer-when-downgrade'
| 'origin'
| 'origin-when-cross-origin'
| 'same-origin'
| 'strict-origin'
| 'strict-origin-when-cross-origin'
| 'unsafe-url'
| 'none'
>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
## HttpMethod
<div class="ts-block">
```dts
type HttpMethod =
| 'GET'
| 'HEAD'
| 'POST'
| 'PUT'
| 'DELETE'
| 'PATCH'
| 'OPTIONS';
```
</div>
## Logger
<div class="ts-block">
```dts
interface Logger {/*…*/}
```
<div class="ts-block-property">
```dts
(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
success(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
error(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
warn(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
minor(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
info(msg: string): void;
```
<div class="ts-block-property-details"></div>
</div></div>
## MaybePromise
<div class="ts-block">
```dts
type MaybePromise<T> = T | Promise<T>;
```
</div>
## PrerenderEntryGeneratorMismatchHandler
<div class="ts-block">
```dts
interface PrerenderEntryGeneratorMismatchHandler {/*…*/}
```
<div class="ts-block-property">
```dts
(details: { generatedFromId: string; entry: string; matchedId: string; message:
string }): void;
```
<div class="ts-block-property-details"></div>
</div></div>
## PrerenderEntryGeneratorMismatchHandlerValue
<div class="ts-block">
```dts
type PrerenderEntryGeneratorMismatchHandlerValue =
| 'fail'
| 'warn'
| 'ignore'
| PrerenderEntryGeneratorMismatchHandler;
```
</div>
## PrerenderHttpErrorHandler
<div class="ts-block">
```dts
interface PrerenderHttpErrorHandler {/*…*/}
```
<div class="ts-block-property">
```dts
(details: {
status: number;
path: string;
referrer: string | null;
referenceType: 'linked' | 'fetched';
message: string;
}): void;
```
<div class="ts-block-property-details"></div>
</div></div>
## PrerenderHttpErrorHandlerValue
<div class="ts-block">
```dts
type PrerenderHttpErrorHandlerValue =
| 'fail'
| 'warn'
| 'ignore'
| PrerenderHttpErrorHandler;
```
</div>
## PrerenderMap
<div class="ts-block">
```dts
type PrerenderMap = Map<string, PrerenderOption>;
```
</div>
## PrerenderMissingIdHandler
<div class="ts-block">
```dts
interface PrerenderMissingIdHandler {/*…*/}
```
<div class="ts-block-property">
```dts
(details: { path: string; id: string; referrers: string[]; message: string }):
void;
```
<div class="ts-block-property-details"></div>
</div></div>
## PrerenderMissingIdHandlerValue
<div class="ts-block">
```dts
type PrerenderMissingIdHandlerValue =
| 'fail'
| 'warn'
| 'ignore'
| PrerenderMissingIdHandler;
```
</div>
## PrerenderOption
<div class="ts-block">
```dts
type PrerenderOption = boolean | 'auto';
```
</div>
## Prerendered
<div class="ts-block">
```dts
interface Prerendered {/*…*/}
```
<div class="ts-block-property">
```dts
pages: Map<
string,
{
/** The location of the .html file relative to the output directory */
file: string;
}
>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
assets: Map<
string,
{
/** The MIME type of the asset */
type: string;
}
>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
redirects: Map<
string,
{
status: number;
location: string;
}
>;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
paths: string[];
```
<div class="ts-block-property-details">
</div>
</div></div>
## RequestOptions
<div class="ts-block">
```dts
interface RequestOptions {/*…*/}
```
<div class="ts-block-property">
```dts
getClientAddress(): string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
platform?: App.Platform;
```
<div class="ts-block-property-details"></div>
</div></div>
## RouteSegment
<div class="ts-block">
```dts
interface RouteSegment {/*…*/}
```
<div class="ts-block-property">
```dts
content: string;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
dynamic: boolean;
```
<div class="ts-block-property-details"></div>
</div>
<div class="ts-block-property">
```dts
rest: boolean;
```
<div class="ts-block-property-details"></div>
</div></div>
## TrailingSlash
<div class="ts-block">
```dts
type TrailingSlash = 'never' | 'always' | 'ignore';
```
</div>
## docs/kit/98-reference/15-@sveltejs-kit-hooks.md
---
title: @sveltejs/kit/hooks
---
```js
// @noErrors
import { sequence } from '@sveltejs/kit/hooks';
```
## sequence
```js
// @errors: 7031
/// file: src/hooks.server.js
import { sequence } from '@sveltejs/kit/hooks';
```
first pre-processing
first preload
second pre-processing
second filterSerializedResponseHeaders
second transform
first transform
second post-processing
first post-processing
```
<div class="ts-block">
```dts
function sequence(
...handlers: import('@sveltejs/kit').Handle[]
): import('@sveltejs/kit').Handle;
```
</div>
## docs/kit/98-reference/15-@sveltejs-kit-node-polyfills.md
---
title: @sveltejs/kit/node/polyfills
---
```js
// @noErrors
import { installPolyfills } from '@sveltejs/kit/node/polyfills';
```
## installPolyfills
<div class="ts-block">
```dts
function installPolyfills(): void;
```
</div>
## docs/kit/98-reference/15-@sveltejs-kit-node.md
---
title: @sveltejs/kit/node
---
```js
// @noErrors
import {
createReadableStream,
getRequest,
setResponse
} from '@sveltejs/kit/node';
```
## createReadableStream
<blockquote class="since note">
</blockquote>
<div class="ts-block">
```dts
function createReadableStream(file: string): ReadableStream;
```
</div>
## getRequest
<div class="ts-block">
```dts
function getRequest({
request,
base,
bodySizeLimit
}: {
request: import('http').IncomingMessage;
base: string;
bodySizeLimit?: number;
}): Promise<Request>;
```
</div>
## setResponse
<div class="ts-block">
```dts
function setResponse(
res: import('http').ServerResponse,
response: Response
): Promise<void>;
```
</div>
## docs/kit/98-reference/15-@sveltejs-kit-vite.md
---
title: @sveltejs/kit/vite
---
```js
// @noErrors
import { sveltekit } from '@sveltejs/kit/vite';
```
## sveltekit
<div class="ts-block">
```dts
function sveltekit(): Promise<import('vite').Plugin[]>;
```
</div>
## docs/kit/98-reference/20-$app-environment.md
---
title: $app/environment
---
```js
// @noErrors
import { browser, building, dev, version } from '$app/environment';
```
## browser
<div class="ts-block">
```dts
const browser: boolean;
```
</div>
## building
SvelteKit analyses your app during the `build` step by running it. During this
process, `building` is `true`. This also applies during prerendering.
<div class="ts-block">
```dts
const building: boolean;
```
</div>
## dev
<div class="ts-block">
```dts
const dev: boolean;
```
</div>
## version
<div class="ts-block">
```dts
const version: string;
```
</div>
## docs/kit/98-reference/20-$app-forms.md
---
title: $app/forms
---
```js
// @noErrors
import { applyAction, deserialize, enhance } from '$app/forms';
```
## applyAction
This action updates the `form` property of the current page with the given data and
updates `page.status`.
In case of an error, it redirects to the nearest error page.
<div class="ts-block">
```dts
function applyAction<
Success extends Record<string, unknown> | undefined,
Failure extends Record<string, unknown> | undefined
>(
result: import('@sveltejs/kit').ActionResult<
Success,
Failure
>
): Promise<void>;
```
</div>
## deserialize
```js
// @errors: 7031
import { deserialize } from '$app/forms';
<div class="ts-block">
```dts
function deserialize<
Success extends Record<string, unknown> | undefined,
Failure extends Record<string, unknown> | undefined
>(
result: string
): import('@sveltejs/kit').ActionResult<Success, Failure>;
```
</div>
## enhance
This action enhances a `<form>` element that otherwise would work without
JavaScript.
The `submit` function is called upon submission with the given FormData and the
`action` that should be triggered.
If `cancel` is called, the form will not be submitted.
You can use the abort `controller` to cancel the submission in case another one
starts.
If a function is returned, that function is called with the response from the
server.
If nothing is returned, the fallback will be used.
If you provide a custom function with a callback and want to use the default
behavior, invoke `update` in your callback.
It accepts an options object
- `reset: false` if you don't want the `<form>` values to be reset after a
successful submission
- `invalidateAll: false` if you don't want the action to call `invalidateAll` after
submission
<div class="ts-block">
```dts
function enhance<
Success extends Record<string, unknown> | undefined,
Failure extends Record<string, unknown> | undefined
>(
form_element: HTMLFormElement,
submit?: import('@sveltejs/kit').SubmitFunction<
Success,
Failure
>
): {
destroy(): void;
};
```
</div>
## docs/kit/98-reference/20-$app-navigation.md
---
title: $app/navigation
---
```js
// @noErrors
import {
afterNavigate,
beforeNavigate,
disableScrollHandling,
goto,
invalidate,
invalidateAll,
onNavigate,
preloadCode,
preloadData,
pushState,
replaceState
} from '$app/navigation';
```
## afterNavigate
A lifecycle function that runs the supplied `callback` when the current component
mounts, and also whenever we navigate to a URL.
<div class="ts-block">
```dts
function afterNavigate(
callback: (
navigation: import('@sveltejs/kit').AfterNavigate
) => void
): void;
```
</div>
## beforeNavigate
If the navigation will (if not cancelled) cause the document to unload — in other
words `'leave'` navigations and `'link'` navigations where `navigation.to.route ===
null` — `navigation.willUnload` is `true`.
<div class="ts-block">
```dts
function beforeNavigate(
callback: (
navigation: import('@sveltejs/kit').BeforeNavigate
) => void
): void;
```
</div>
## disableScrollHandling
If called when the page is being updated following a navigation (in `onMount` or
`afterNavigate` or an action, for example), this disables SvelteKit's built-in
scroll handling.
This is generally discouraged, since it breaks user expectations.
<div class="ts-block">
```dts
function disableScrollHandling(): void;
```
</div>
## goto
<div class="ts-block">
```dts
function goto(
url: string | URL,
opts?:
| {
replaceState?: boolean | undefined;
noScroll?: boolean | undefined;
keepFocus?: boolean | undefined;
invalidateAll?: boolean | undefined;
invalidate?:
| (string | URL | ((url: URL) => boolean))[]
| undefined;
state?: App.PageState | undefined;
}
| undefined
): Promise<void>;
```
</div>
## invalidate
Causes any `load` functions belonging to the currently active page to re-run if
they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise`
that resolves when the page is subsequently updated.
If the argument is given as a `string` or `URL`, it must resolve to the same URL
that was passed to `fetch` or `depends` (including query parameters).
To create a custom identifier, use a string beginning with `[a-z]+:` (e.g.
`custom:state`) — this is a valid URL.
The `function` argument can be used define a custom predicate. It receives the full
`URL` and causes `load` to rerun if `true` is returned.
This can be useful if you want to invalidate based on a pattern instead of a exact
match.
```ts
// Example: Match '/path' regardless of the query parameters
import { invalidate } from '$app/navigation';
<div class="ts-block">
```dts
function invalidate(
resource: string | URL | ((url: URL) => boolean)
): Promise<void>;
```
</div>
## invalidateAll
Causes all `load` functions belonging to the currently active page to re-run.
Returns a `Promise` that resolves when the page is subsequently updated.
<div class="ts-block">
```dts
function invalidateAll(): Promise<void>;
```
</div>
## onNavigate
If you return a `Promise`, SvelteKit will wait for it to resolve before completing
the navigation. This allows you to — for example — use
`document.startViewTransition`. Avoid promises that are slow to resolve, since
navigation will appear stalled to the user.
<div class="ts-block">
```dts
function onNavigate(
callback: (
navigation: import('@sveltejs/kit').OnNavigate
) => MaybePromise<(() => void) | void>
): void;
```
</div>
## preloadCode
Programmatically imports the code for routes that haven't yet been fetched.
Typically, you might call this to speed up subsequent navigation.
You can specify routes by any matching pathname such as `/about` (to match
`src/routes/about/+page.svelte`) or `/blog/*` (to match
`src/routes/blog/[slug]/+page.svelte`).
<div class="ts-block">
```dts
function preloadCode(pathname: string): Promise<void>;
```
</div>
## preloadData
This is the same behaviour that SvelteKit triggers when the user taps or mouses
over an `<a>` element with `data-sveltekit-preload-data`.
If the next navigation is to `href`, the values returned from load will be used,
making navigation instantaneous.
Returns a Promise that resolves with the result of running the new route's `load`
functions once the preload is complete.
<div class="ts-block">
```dts
function preloadData(href: string): Promise<
| {
type: 'loaded';
status: number;
data: Record<string, any>;
}
| {
type: 'redirect';
location: string;
}
>;
```
</div>
## pushState
Programmatically create a new history entry with the given `page.state`. To use the
current URL, you can pass `''` as the first argument. Used for [shallow
routing](/docs/kit/shallow-routing).
<div class="ts-block">
```dts
function pushState(
url: string | URL,
state: App.PageState
): void;
```
</div>
## replaceState
Programmatically replace the current history entry with the given `page.state`. To
use the current URL, you can pass `''` as the first argument. Used for [shallow
routing](/docs/kit/shallow-routing).
<div class="ts-block">
```dts
function replaceState(
url: string | URL,
state: App.PageState
): void;
```
</div>
## docs/kit/98-reference/20-$app-paths.md
---
title: $app/paths
---
```js
// @noErrors
import { assets, base, resolveRoute } from '$app/paths';
```
## assets
An absolute path that matches
[`config.kit.paths.assets`](/docs/kit/configuration#paths).
<div class="ts-block">
```dts
let assets:
| ''
| `https://${string}`
| `http://${string}`
| '/_svelte_kit_assets';
```
</div>
## base
<div class="ts-block">
```dts
let base: '' | `/${string}`;
```
</div>
## resolveRoute
```js
// @errors: 7031
import { resolveRoute } from '$app/paths';
resolveRoute(
`/blog/[slug]/[...somethingElse]`,
{
slug: 'hello-world',
somethingElse: 'something/else'
}
); // `/blog/hello-world/something/else`
```
<div class="ts-block">
```dts
function resolveRoute(
id: string,
params: Record<string, string | undefined>
): string;
```
</div>
## docs/kit/98-reference/20-$app-server.md
---
title: $app/server
---
```js
// @noErrors
import { getRequestEvent, read } from '$app/server';
```
## getRequestEvent
</blockquote>
Returns the current `RequestEvent`. Can be used inside `handle`, `load` and actions
(and functions called by them).
In environments without
[`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-
asynclocalstorage), this must be called synchronously (i.e. not after an `await`).
<div class="ts-block">
```dts
function getRequestEvent(): RequestEvent<
Partial<Record<string, string>>,
string | null
>;
```
</div>
## read
</blockquote>
```js
// @errors: 7031
import { read } from '$app/server';
import somefile from './somefile.txt';
const asset = read(somefile);
const text = await asset.text();
```
<div class="ts-block">
```dts
function read(asset: string): Response;
```
</div>
## docs/kit/98-reference/20-$app-state.md
---
title: $app/state
---
SvelteKit makes three read-only state objects available via the `$app/state` module
— `page`, `navigating` and `updated`.
> This module was added in 2.12. If you're using an earlier version of SvelteKit,
use [`$app/stores`]($app-stores) instead.
```js
// @noErrors
import { navigating, page, updated } from '$app/state';
```
## navigating
<div class="ts-block">
```dts
const navigating:
| import('@sveltejs/kit').Navigation
| {
from: null;
to: null;
type: null;
willUnload: null;
delta: null;
complete: null;
};
```
</div>
## page
A read-only reactive object with information about the current page, serving
several use cases:
- retrieving the combined `data` of all pages/layouts anywhere in your component
tree (also see [loading data](/docs/kit/load))
- retrieving the current value of the `form` prop anywhere in your component tree
(also see [form actions](/docs/kit/form-actions))
- retrieving the page state that was set through `goto`, `pushState` or
`replaceState` (also see [goto](/docs/kit/$app-navigation#goto) and [shallow
routing](/docs/kit/shallow-routing))
- retrieving metadata such as the URL you're on, the current route and its
parameters, and whether or not there was an error
```svelte
<!file: +layout.svelte>
<script>
import { page } from '$app/state';
</script>
<p>Currently at {page.url.pathname}</p>
{#if page.error}
<span class="red">Problem detected</span>
{:else}
<span class="small">All systems operational</span>
{/if}
```
Changes to `page` are available exclusively with runes. (The legacy reactivity
syntax will not reflect any changes)
```svelte
<!file: +page.svelte>
<script>
import { page } from '$app/state';
const id = $derived(page.params.id); // This will correctly update id for
usage on this page
$: badId = page.params.id; // Do not use; will never update after initial
load
</script>
```
On the server, values can only be read during rendering (in other words _not_ in
e.g. `load` functions). In the browser, the values can be read at any time.
<div class="ts-block">
```dts
const page: import('@sveltejs/kit').Page;
```
</div>
## updated
<div class="ts-block">
```dts
const updated: {
get current(): boolean;
check(): Promise<boolean>;
};
```
</div>
## docs/kit/98-reference/20-$app-stores.md
---
title: $app/stores
---
```js
// @noErrors
import { getStores, navigating, page, updated } from '$app/stores';
```
## getStores
<div class="ts-block">
```dts
function getStores(): {
page: typeof page;
</div>
## navigating
Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more
info](/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
</blockquote>
A readable store.
When navigating starts, its value is a `Navigation` object with `from`, `to`,
`type` and (if `type === 'popstate'`) `delta` properties.
When navigating finishes, its value reverts to `null`.
<div class="ts-block">
```dts
const navigating: import('svelte/store').Readable<
import('@sveltejs/kit').Navigation | null
>;
```
</div>
## page
Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info]
(/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
</blockquote>
<div class="ts-block">
```dts
const page: import('svelte/store').Readable<
import('@sveltejs/kit').Page
>;
```
</div>
## updated
Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more
info](/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
</blockquote>
<div class="ts-block">
```dts
const updated: import('svelte/store').Readable<boolean> & {
check(): Promise<boolean>;
};
```
</div>
## docs/kit/98-reference/25-$env-dynamic-private.md
---
title: $env/dynamic/private
---
```ts
import { env } from '$env/dynamic/private';
console.log(env.DEPLOYMENT_SPECIFIC_VARIABLE);
```
## docs/kit/98-reference/25-$env-dynamic-public.md
---
title: $env/dynamic/public
---
Note that public dynamic environment variables must all be sent from the server to
the client, causing larger network requests — when possible, use
`$env/static/public` instead.
## docs/kit/98-reference/25-$env-static-private.md
---
title: $env/static/private
---
```ts
import { API_KEY } from '$env/static/private';
```
Note that all environment variables referenced in your code should be declared (for
example in an `.env` file), even if they don't have a value until the app is
deployed:
```
MY_FEATURE_FLAG=""
```
You can override `.env` values from the command line like so:
```bash
MY_FEATURE_FLAG="enabled" npm run dev
```
## docs/kit/98-reference/25-$env-static-public.md
---
title: $env/static/public
---
```ts
import { PUBLIC_BASE_URL } from '$env/static/public';
```
## docs/kit/98-reference/26-$lib.md
---
title: $lib
---
SvelteKit automatically makes files under `src/lib` available using the `$lib`
import alias. You can change which directory this alias points to in your [config
file](configuration#files).
```svelte
<!file: src/lib/Component.svelte>
A reusable component
```
```svelte
<!file: src/routes/+page.svelte>
<script>
import Component from '$lib/Component.svelte';
</script>
<Component />
```
## docs/kit/98-reference/27-$service-worker.md
---
title: $service-worker
---
```js
// @noErrors
import { base, build, files, prerendered, version } from '$service-worker';
```
## base
<div class="ts-block">
```dts
const base: string;
```
</div>
## build
An array of URL strings representing the files generated by Vite, suitable for
caching with `cache.addAll(build)`.
During development, this is an empty array.
<div class="ts-block">
```dts
const build: string[];
```
</div>
## files
<div class="ts-block">
```dts
const files: string[];
```
</div>
## prerendered
<div class="ts-block">
```dts
const prerendered: string[];
```
</div>
## version
<div class="ts-block">
```dts
const version: string;
```
</div>
## docs/kit/98-reference/50-configuration.md
---
title: Configuration
---
```js
/// file: svelte.config.js
// @filename: ambient.d.ts
declare module '@sveltejs/adapter-auto' {
const plugin: () => import('@sveltejs/kit').Adapter;
export default plugin;
}
// @filename: index.js
//cut
import adapter from '@sveltejs/adapter-auto';
## Config
<div class="ts-block">
```dts
interface Config {/*…*/}
```
<div class="ts-block-property">
```dts
compilerOptions?: CompileOptions;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Options passed to [`svelte.compile`](/docs/svelte/svelte-compiler#CompileOptions).
</div>
</div>
<div class="ts-block-property">
```dts
extensions?: string[];
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```dts
kit?: KitConfig;
```
<div class="ts-block-property-details">
SvelteKit options
</div>
</div>
<div class="ts-block-property">
```dts
preprocess?: any;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```dts
vitePlugin?: PluginOptions;
```
<div class="ts-block-property-details">
`vite-plugin-svelte` plugin options.
</div>
</div>
<div class="ts-block-property">
```dts
[key: string]: any;
```
<div class="ts-block-property-details">
</div>
</div></div>
## KitConfig
The `kit` property configures SvelteKit, and can have the following properties:
## adapter
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
</div>
## alias
<div class="ts-block-property-bullets">
</div>
```js
// @errors: 7031
/// file: svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
alias: {
// this will match a file
'my-file': 'path/to/my-file.js',
<div class="ts-block-property-children">
</div>
## appDir
<div class="ts-block-property-bullets">
</div>
The directory where SvelteKit keeps its stuff, including static assets (such as JS
and CSS) and internally-used routes.
<div class="ts-block-property-children">
</div>
## csp
<div class="ts-block-property-bullets">
</div>
[Content Security
Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-
Policy) configuration. CSP helps to protect your users against cross-site scripting
(XSS) attacks, by limiting the places resources can be loaded from. For example, a
configuration like this...
```js
// @errors: 7031
/// file: svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
csp: {
directives: {
'script-src': ['self']
},
// must be specified with either the `report-uri` or `report-to`
directives, or both
reportOnly: {
'script-src': ['self'],
'report-uri': ['/']
}
}
}
};
...would prevent scripts loading from external sites. SvelteKit will augment the
specified directives with nonces or hashes (depending on `mode`) for any inline
styles and scripts it generates.
To add a nonce for scripts and links manually included in `src/app.html`, you may
use the placeholder `%sveltekit.nonce%` (for example `<script
nonce="%sveltekit.nonce%">`).
When pages are prerendered, the CSP header is added via a `<meta http-equiv>` tag
(note that in this case, `frame-ancestors`, `report-uri` and `sandbox` directives
will be ignored).
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
mode?: 'hash' | 'nonce' | 'auto';
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
directives?: CspDirectives;
```
<div class="ts-block-property-details">
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
reportOnly?: CspDirectives;
```
<div class="ts-block-property-details">
</div>
</div>
</div>
## csrf
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
checkOrigin?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Whether to check the incoming `origin` header for `POST`, `PUT`, `PATCH`, or
`DELETE` form submissions and verify that it matches the server's origin.
</div>
</div>
</div>
## embedded
<div class="ts-block-property-bullets">
</div>
Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will
add its event listeners related to navigation etc on the parent of `%sveltekit.body
%` instead of `window`, and will pass `params` from the server rather than
inferring them from `location.pathname`.
Note that it is generally not supported to embed multiple SvelteKit apps on the
same page and use client-side SvelteKit features within them (things such as
pushing to the history state assume a single instance).
<div class="ts-block-property-children">
</div>
## env
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
dir?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
```ts
// @noErrors
publicPrefix?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
privatePrefix?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
</div>
## files
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
assets?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
a place to put static files that should have stable URLs and undergo no processing,
such as `favicon.ico` or `manifest.json`
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
hooks?: {/*…*/}
```
<div class="ts-block-property-details">
```ts
// @noErrors
client?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
server?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
universal?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div></div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
lib?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
params?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
routes?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
the files that define the structure of your app (see [Routing](/docs/kit/routing))
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
serviceWorker?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
appTemplate?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
errorTemplate?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
</div>
## inlineStyleThreshold
<div class="ts-block-property-bullets">
</div>
Inline CSS inside a `<style>` block at the head of the HTML. This option is a
number that specifies the maximum length of a CSS file in UTF-16 code units, as
specified by the
[String.length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/String/length) property, to be inlined. All CSS files needed for the
page and smaller than this value are merged and inlined in a `<style>` block.
<div class="ts-block-property-children">
</div>
## moduleExtensions
<div class="ts-block-property-bullets">
</div>
An array of file extensions that SvelteKit will treat as modules. Files with
extensions that match neither `config.extensions` nor `config.kit.moduleExtensions`
will be ignored by the router.
<div class="ts-block-property-children">
</div>
## outDir
<div class="ts-block-property-bullets">
</div>
The directory that SvelteKit writes files to during `dev` and `build`. You should
exclude this directory from version control.
<div class="ts-block-property-children">
</div>
## output
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
preloadStrategy?: 'modulepreload' | 'preload-js' | 'preload-mjs';
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
SvelteKit will preload the JavaScript modules needed for the initial page to avoid
import 'waterfalls', resulting in faster application startup. There
are three strategies with different trade-offs:
- `modulepreload` - uses `<link rel="modulepreload">`. This delivers the best
results in Chromium-based browsers, in Firefox 115+, and Safari 17+. It is ignored
in older browsers.
- `preload-js` - uses `<link rel="preload">`. Prevents waterfalls in Chromium and
Safari, but Chromium will parse each module twice (once as a script, once as a
module). Causes modules to be requested twice in Firefox. This is a good setting if
you want to maximise performance for users on iOS devices at the cost of a very
slight degradation for Chromium users.
- `preload-mjs` - uses `<link rel="preload">` but with the `.mjs` extension which
prevents double-parsing in Chromium. Some static webservers will fail to serve .mjs
files with a `Content-Type: application/javascript` header, which will cause your
application to break. If that doesn't apply to you, this is the option that will
deliver the best performance for the largest number of users, until `modulepreload`
is more widely supported.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
bundleStrategy?: 'split' | 'single' | 'inline';
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
The bundle strategy option affects how your app's JavaScript and CSS files are
loaded.
- If `'split'`, splits the app up into multiple .js/.css files so that they are
loaded lazily as the user navigates around the app. This is the default, and is
recommended for most scenarios.
- If `'single'`, creates just one .js bundle and one .css file containing code for
the entire app.
- If `'inline'`, inlines all JavaScript and CSS of the entire app into the HTML.
The result is usable without a server (i.e. you can just open the file in your
browser).
When using `'split'`, you can also adjust the bundling behaviour by setting
[`output.experimentalMinChunkSize`](https://rollupjs.org/configuration-options/
#output-experimentalminchunksize) and
[`output.manualChunks`](https://rollupjs.org/configuration-options/#output-
manualchunks) inside your Vite config's
[`build.rollupOptions`](https://vite.dev/config/build-options.html#build-
rollupoptions).
If you want to inline your assets, you'll need to set Vite's
[`build.assetsInlineLimit`](https://vite.dev/config/build-options.html#build-
assetsinlinelimit) option to an appropriate size then import your assets through
Vite.
```js
// @errors: 7031
/// file: vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
```svelte
/// file: src/routes/+layout.svelte
<script>
// import the asset through Vite
import favicon from './favicon.png';
</script>
<svelte:head>
<!-- this asset will be inlined as a base64 URL -->
<link rel="icon" href={favicon} />
</svelte:head>
```
</div>
</div>
</div>
## paths
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
assets?: '' | `http://${string}` | `https://${string}`;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
An absolute path that your app's files are served from. This is useful if your
files are served from a storage bucket of some kind.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
base?: '' | `/${string}`;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
A root-relative path that must start, but not end with `/` (e.g. `/base-path`),
unless it is the empty string. This specifies where your app is served from and
allows the app to live on a non-root path. Note that you need to prepend all your
root-relative links with the base value or they will point to the root of your
domain, not your `base` (this is how the browser works). You can use [`base` from
`$app/paths`](/docs/kit/$app-paths#base) for that: `<a href="{base}/your-
page">Link</a>`. If you find yourself writing this often, it may make sense to
extract this into a reusable component.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
relative?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
If `true`, `base` and `assets` imported from `$app/paths` will be replaced with
relative asset paths during server-side rendering, resulting in more portable HTML.
If `false`, `%sveltekit.assets%` and references to build artifacts will always be
root-relative paths, unless `paths.assets` is an external URL
[Single-page app](/docs/kit/single-page-apps) fallback pages will always use
absolute paths, regardless of this setting.
If your app uses a `<base>` element, you should set this to `false`, otherwise
asset URLs will incorrectly be resolved against the `<base>` URL rather than the
current page.
In 1.0, `undefined` was a valid value, which was set by default. In that case, if
`paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with
a relative path and use relative paths to reference build artifacts, but `base` and
`assets` imported from `$app/paths` would be as specified in your config.
</div>
</div>
</div>
## prerender
<div class="ts-block-property-bullets">
</div>
See [Prerendering](/docs/kit/page-options#prerender).
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
concurrency?: number;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
crawl?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Whether SvelteKit should find pages to prerender by following links from `entries`.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
entries?: Array<'*' | `/${string}`>;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
An array of pages to prerender, or start crawling from (if `crawl: true`). The `*`
string includes all routes containing no required `[parameters]` with optional
parameters included as being empty (since SvelteKit doesn't know what value any
parameters should have).
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
handleHttpError?: PrerenderHttpErrorHandlerValue;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
handleMissingId?: PrerenderMissingIdHandlerValue;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
How to respond when hash links from one prerendered page to another don't
correspond to an `id` on the destination page.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
How to respond when an entry generated by the `entries` export doesn't match the
route it was generated from.
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
origin?: string;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
</div>
## router
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
type?: 'pathname' | 'hash';
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
resolution?: 'client' | 'server';
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Alternatively, SvelteKit can determine the route on the server. This means that for
every navigation to a path that has not yet been visited, the server will be asked
to determine the route.
This has several advantages:
- The client does not need to load the routing manifest upfront, which can lead to
faster initial page loads
- The list of routes is hidden from public view
- The server has an opportunity to intercept each navigation (for example through a
middleware), enabling (for example) A/B testing opaque to SvelteKit
The drawback is that for unvisited paths, resolution will take slightly longer
(though this is mitigated by [preloading](/docs/kit/link-options#data-sveltekit-
preload-data)).
</div>
</div>
</div>
## serviceWorker
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
register?: boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
files?(filepath: string): boolean;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
Determine which files in your `static` directory will be available in `$service-
worker.files`.
</div>
</div>
</div>
## typescript
<div class="ts-block-property-bullets">
</div>
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
config?: (config: Record<string, any>) => Record<string, any> | void;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
A function that allows you to edit the generated `tsconfig.json`. You can mutate
the config (recommended) or return a new one.
This is useful for extending a shared `tsconfig.json` in a monorepo root, for
example.
</div>
</div>
</div>
## version
<div class="ts-block-property-bullets">
</div>
Client-side navigation can be buggy if you deploy a new version of your app while
people are using it. If the code for the new page is already loaded, it may have
stale content; if it isn't, the app's route manifest may point to a JavaScript file
that no longer exists.
SvelteKit helps you solve this problem through version management.
If SvelteKit encounters an error while loading the page and detects that a new
version has been deployed (using the `name` specified here, which defaults to a
timestamp of the build) it will fall back to traditional full-page navigation.
Not all navigations will result in an error though, for example if the JavaScript
for the next page is already loaded. If you still want to force a full-page
navigation in these cases, use techniques such as setting the `pollInterval` and
then using `beforeNavigate`:
```html
/// file: +layout.svelte
<script>
import { beforeNavigate } from '$app/navigation';
import { updated } from '$app/state';
If you set `pollInterval` to a non-zero value, SvelteKit will poll for new versions
in the background and set the value of [`updated.current`](/docs/kit/$app-
state#updated) `true` when it detects one.
<div class="ts-block-property-children">
<div class="ts-block-property">
```ts
// @noErrors
name?: string;
```
<div class="ts-block-property-details">
The current app version string. If specified, this must be deterministic (e.g. a
commit ref rather than `Math.random()` or `Date.now().toString()`), otherwise
defaults to a timestamp of the build.
For example, to use the current commit hash, you could do use `git rev-parse HEAD`:
```js
// @errors: 7031
/// file: svelte.config.js
import * as child_process from 'node:child_process';
export default {
kit: {
version: {
name: child_process.execSync('git rev-parse
HEAD').toString().trim()
}
}
};
```
</div>
</div>
<div class="ts-block-property">
```ts
// @noErrors
pollInterval?: number;
```
<div class="ts-block-property-details">
<div class="ts-block-property-bullets">
</div>
</div>
</div>
</div>
## docs/kit/98-reference/52-cli.md
---
However SvelteKit includes its own CLI for initialising your project:
## svelte-kit sync
`svelte-kit sync` creates the `tsconfig.json` and all generated types (which you
can import as `./$types` inside routing files) for your project. When you create a
new project, it is listed as the `prepare` script and will be run automatically as
part of the npm lifecycle, so you should not ordinarily have to run this command.
## docs/kit/98-reference/54-types.md
---
title: Types
---
## Generated types
The `RequestHandler` and `Load` types both accept a `Params` argument allowing you
to type the `params` object. For example this endpoint expects `foo`, `bar` and
`baz` params:
```js
/// file: src/routes/[foo]/[bar]/[baz]/+server.js
// @errors: 2355 2322 1360
/** @type {import('@sveltejs/kit').RequestHandler<{
foo: string;
bar: string;
baz: string
}>} */
export async function GET({ params }) {
// ...
}
```
Needless to say, this is cumbersome to write out, and less portable (if you were to
rename the `[foo]` directory to `[qux]`, the type would no longer reflect reality).
To solve this problem, SvelteKit generates `.d.ts` files for each of your endpoints
and pages:
```ts
/// file: .svelte-kit/types/src/routes/[foo]/[bar]/[baz]/$types.d.ts
/// link: true
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
};
These files can be imported into your endpoints and pages as siblings, thanks to
the [`rootDirs`](https://www.typescriptlang.org/tsconfig#rootDirs) option in your
TypeScript configuration:
```js
/// file: src/routes/[foo]/[bar]/[baz]/+server.js
// @filename: $types.d.ts
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
}
// @filename: index.js
// @errors: 2355 2322
//cut
/** @type {import('./$types').RequestHandler} */
export async function GET({ params }) {
// ...
}
```
```js
/// file: src/routes/[foo]/[bar]/[baz]/+page.js
// @filename: $types.d.ts
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
}
// @filename: index.js
// @errors: 2355
//cut
/** @type {import('./$types').PageLoad} */
export async function load({ params, fetch }) {
// ...
}
```
The return types of the load functions are then available through the `$types`
module as `PageData` and `LayoutData` respectively, while the union of the return
values of all `Actions` is available as `ActionData`.
Starting with version 2.16.0, two additional helper types are provided: `PageProps`
defines `data: PageData`, as well as `form: ActionData`, when there are actions
defined, while `LayoutProps` defines `data: LayoutData`, as well as `children:
Snippet`.
```svelte
<!file: src/routes/+page.svelte>
<script>
/** @type {import('./$types').PageProps} */
let { data, form } = $props();
</script>
```
> [!LEGACY]
> Before 2.16.0:
> ```svelte
> <!--- file: src/routes/+page.svelte --->
> <script>
> /** @type {{ data: import('./$types').PageData, form:
import('./$types').ActionData }} */
> let { data, form } = $props();
> </script>
> ```
>
> Using Svelte 4:
> ```svelte
> <!--- file: src/routes/+page.svelte --->
> <script>
> /** @type {import('./$types').PageData} */
> export let data;
> /** @type {import('./$types').ActionData} */
> export let form;
> </script>
> ```
>
> `{ "extends": "./.svelte-kit/tsconfig.json" }`
```json
/// file: .svelte-kit/tsconfig.json
{
"compilerOptions": {
"paths": {
"$lib": ["../src/lib"],
"$lib/*": ["../src/lib/*"]
},
"rootDirs": ["..", "./types"]
},
"include": [
"ambient.d.ts",
"non-ambient.d.ts",
"./types/**/$types.d.ts",
"../vite.config.js",
"../vite.config.ts",
"../src/**/*.js",
"../src/**/*.ts",
"../src/**/*.svelte",
"../tests/**/*.js",
"../tests/**/*.ts",
"../tests/**/*.svelte"
],
"exclude": [
"../node_modules/**",
"../src/service-worker.js",
"../src/service-worker/**/*.js",
"../src/service-worker.ts",
"../src/service-worker/**/*.ts",
"../src/service-worker.d.ts",
"../src/service-worker/**/*.d.ts"
]
}
```
Others are required for SvelteKit to work properly, and should also be left
untouched unless you know what you're doing:
```json
/// file: .svelte-kit/tsconfig.json
{
"compilerOptions": {
// this ensures that types are explicitly
// imported with `import type`, which is
// necessary as Svelte/Vite cannot
// otherwise compile components correctly
"verbatimModuleSyntax": true,
// Vite compiles one TypeScript module
// at a time, rather than compiling
// the entire module graph
"isolatedModules": true,
## $lib
### $lib/server
A subdirectory of `$lib`. SvelteKit will prevent you from importing any modules in
`$lib/server` into client-side code. See [server-only modules](server-only-
modules).
## app.d.ts
The `app.d.ts` file is home to the ambient types of your apps, i.e. types that are
available without explicitly importing them.
Always part of this file is the `App` namespace. This namespace contains several
types that influence the shape of certain SvelteKit features you interact with.
## Error
Defines the common shape of expected and unexpected errors. Expected errors are
thrown using the `error` function. Unexpected errors are handled by the
`handleError` hooks which should return this shape.
<div class="ts-block">
```dts
interface Error {/*…*/}
```
<div class="ts-block-property">
```dts
message: string;
```
<div class="ts-block-property-details"></div>
</div></div>
## Locals
The interface that defines `event.locals`, which can be accessed in server [hooks]
(/docs/kit/hooks) (`handle`, and `handleError`), server-only `load` functions, and
`+server.js` files.
<div class="ts-block">
```dts
interface Locals {}
```
</div>
## PageData
<div class="ts-block">
```dts
interface PageData {}
```
</div>
## PageState
The shape of the `page.state` object, which can be manipulated using the
[`pushState`](/docs/kit/$app-navigation#pushState) and
[`replaceState`](/docs/kit/$app-navigation#replaceState) functions from
`$app/navigation`.
<div class="ts-block">
```dts
interface PageState {}
```
</div>
## Platform
<div class="ts-block">
```dts
interface Platform {}
```
</div>
Instructions for LLMs: <SYSTEM>Always use Svelte 5 runes and Svelte 5 syntax. Runes
do not need to be imported, they are globals. $state() runes are always declared
using `let`, never with `const`. When passing a function to $derived, you must
always use $derived.by(() => ...). Error boundaries can only catch errors during
component rendering and at the top level of an $effect inside the error boundary.
Error boundaries do not catch errors in onclick or other event handlers.</SYSTEM>
---
## docs/cli/index.md
---
title: CLI
---
## docs/cli/10-introduction/index.md
---
title: Introduction
---
## docs/cli/10-introduction/10-overview.md
---
title: Overview
---
The command line interface (CLI), `sv`, is a toolkit for creating and maintaining
Svelte applications.
## Usage
```bash
npx sv <command> <args>
```
If you're inside a project where `sv` is already installed, this will use the local
installation, otherwise it will download the latest version and run it without
installing it, which is particularly useful for [`sv create`](sv-create).
## Acknowledgements
## docs/cli/10-introduction/20-faq.md
---
title: Frequently asked questions
---
Running `sv` looks slightly different for each package manager. Here is a list of
the most common commands:
Some package managers prefer to run locally installed tools instead of downloading
and executing packages from the registry. This issue mostly occurs with `npm` and
`yarn`. This usually results in an error message or looks like the command you were
trying to execute did not do anything.
Here is a list of issues with possible solutions that users have encountered in the
past:
## docs/cli/20-commands/index.md
---
title: Commands
---
## docs/cli/20-commands/10-sv-create.md
---
title: sv create
---
`sv create` sets up a new SvelteKit project, with options to [setup additional
functionality](sv-add#Official-add-ons).
## Usage
```bash
npx sv create [options] [path]
```
## Options
- `ts` — default to `.ts` files and use `lang="ts"` for `.svelte` components
- `jsdoc` — use [JSDoc syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-
supported-types.html) for types
### `--no-types`
### `--no-add-ons`
### `--no-install`
```js
// TODO: this gives type checking errors in the docs site when not commented out.
Need to release sv, install it in the site, and uncomment this.
// import { create } from 'sv';
## docs/cli/20-commands/20-sv-add.md
---
title: sv add
---
## Usage
```bash
npx sv add
```
```bash
npx sv add [add-ons]
```
You can select multiple space-separated add-ons from [the list below](#Official-
add-ons), or you can use the interactive prompt.
## Options
## Official add-ons
<!-- TODO this should be a separate section, each of these should have their own
page -->
- `drizzle`
- `eslint`
- `sveltekit-adapter`
- `lucia`
- `mdsvex`
- `paraglide`
- `playwright`
- `prettier`
- `storybook`
- `tailwindcss`
- `vitest`
## docs/cli/20-commands/30-sv-check.md
---
title: sv check
---
`sv check` finds errors and warnings in your project, such as:
- unused CSS
- accessibility hints
- JavaScript/TypeScript compiler errors
## Installation
You will need to have the `svelte-check` package installed in your project:
```bash
npm i -D svelte-check
```
## Usage
```bash
npx sv check
```
## Options
- `human`
- `human-verbose`
- `machine`
- `machine-verbose`
### `--watch`
### `--preserveWatchOutput`
Pass a path to a `tsconfig` or `jsconfig` file. The path can be relative to the
workspace path or absolute. Doing this means that only files matched by the
`files`/`include`/`exclude` pattern of the config file are diagnosed. It also means
that errors from TypeScript and JavaScript files are reported. If not given, will
traverse upwards from the project directory looking for the next
`jsconfig`/`tsconfig.json` file.
### `--no-tsconfig`
Use this if you only want to check the Svelte files found in the current directory
and below and ignore any `.js`/`.ts` files (they will not be type-checked)
```bash
npx sv check --ignore "dist,build"
```
<!-- TODO what the hell does this mean? is it possible to use --tsconfig AND --no-
tsconfig? if so what would THAT mean? -->
Only has an effect when used in conjunction with `--no-tsconfig`. When used in
conjunction with `--tsconfig`, this will only have effect on the files watched, not
on the files that are diagnosed, which is then determined by the `tsconfig.json`.
### `--fail-on-warnings`
If provided, warnings will cause `sv check` to exit with an error code.
```bash
npx sv check --compiler-warnings
"css_unused_selector:ignore,a11y_missing_attribute:error"
```
A quoted, comma-separated list of sources that should run diagnostics on your code.
By default, all are active:
<!-- TODO would be nice to have a clearer definition of what these are -->
- `js` (includes TypeScript)
- `svelte`
- `css`
Example:
```bash
npx sv check --diagnostic-sources "js,svelte"
```
## Troubleshooting
## Machine-readable output
Each row corresponds to a new record. Rows are made up of columns that are
separated by a
single space character. The first column of every row contains a timestamp in
milliseconds
which can be used for monitoring purposes. The second column gives us the "row
type", based
on which the number and types of subsequent columns may differ.
The first row is of type `START` and contains the workspace folder (wrapped in
quotes). Example:
```
1590680325583 START
"/home/user/language-tools/packages/language-server/test/plugins/typescript/
testfiles"
```
Any number of `ERROR` or `WARNING` records may follow. Their structure is identical
and depends on the output argument.
If the argument is `machine` it will tell us the filename, the starting line and
column numbers, and the error message. The filename is relative to the workspace
directory. The filename and the message are both wrapped in quotes. Example:
```
1590680326283 ERROR "codeactions.svelte" 1:16 "Cannot find module 'blubb' or its
corresponding type declarations."
1590680326778 WARNING "imported-file.svelte" 0:37 "Component has unused export
property 'prop'. If it is for external reference only, please consider using
`export const prop`"
```
```
1590680326283 {"type":"ERROR","fn":"codeaction.svelte","start":
{"line":1,"character":16},"end":{"line":1,"character":23},"message":"Cannot find
module 'blubb' or its corresponding type declarations.","code":2307,"source":"js"}
1590680326778 {"type":"WARNING","filename":"imported-file.svelte","start":
{"line":0,"character":37},"end":{"line":0,"character":51},"message":"Component has
unused export property 'prop'. If it is for external reference only, please
consider using `export
const prop`","code":"unused-export-let","source":"svelte"}
```
The output concludes with a `COMPLETED` message that summarizes total numbers of
files, errors and warnings that were encountered during the check. Example:
```
1590680326807 COMPLETED 20 FILES 21 ERRORS 1 WARNINGS 3 FILES_WITH_PROBLEMS
```
```
1590680328921 FAILURE "Connection closed"
```
## Credits
## FAQ
### Why is there no option to only check specific files (for example only staged
files)?
`svelte-check` needs to 'see' the whole project for checks to be valid. Suppose you
renamed a component prop but didn't update any of the places where the prop is used
— the usage sites are all errors now, but you would miss them if checks only ran on
changed files.
## docs/cli/20-commands/40-sv-migrate.md
---
title: sv migrate
---
Some migrations may annotate your codebase with tasks for completion that you can
find by searching for `@migration`.
## Usage
```bash
npx sv migrate
```
## Migrations
### `app-state`
### `svelte-5`
Upgrades a Svelte 4 app to use Svelte 5, and updates individual components to use
[runes](../svelte/what-are-runes) and other Svelte 5 syntax ([see migration guide]
(../svelte/v5-migration-guide)).
### `self-closing-tags`
Replaces all the self-closing non-void elements in your `.svelte` files. See the
[pull request](https://github.com/sveltejs/kit/pull/12128) for more details.
### `svelte-4`
### `sveltekit-2`
### `package`
Upgrades a library using `@sveltejs/package` version 1 to version 2. See the [pull
request](https://github.com/sveltejs/kit/pull/8922) for more details.
### `routes`