## docs/svelte/01-introduction/01-overview.md # Svelte Overview Svelte is a UI framework that compiles components into optimized JavaScript. ```svelte ``` Use Svelte for anything from standalone components to full stack apps with [SvelteKit](../kit). New to Svelte? Start with the [interactive tutorial](/tutorial) or try the [playground](/playground) or [StackBlitz](https://sveltekit.new). ## docs/svelte/01-introduction/02-getting-started.md # Getting Started with Svelte 5 ## Quick Setup ```bash npx sv create myapp cd myapp npm install npm run dev ``` SvelteKit is the recommended framework for most projects. Alternatively: ```bash npm create vite@latest # Select svelte option ``` ## Editor Support - [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) - Command line: `sv check` ## Getting Help - [Discord chatroom](/chat) - [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte) # Svelte 5 Runes ## $state ```js let count = $state(0); count++; // Reactive update ``` ## $derived ```js let count = $state(0); let doubled = $derived.by(() => count * 2); ``` ## $effect ```js let count = $state(0); $effect(() => { console.log(`Count is ${count}`); }); ``` ## Error Boundaries ```svelte
{#if count > 5} {nonExistentVariable} {/if}
``` Note: Error boundaries only catch errors during component rendering and top-level $effect code, not in event handlers. # Key Syntax Rules - Use `onclick` instead of `on:click` - Runes are globals (no import needed) - Always use `let` with `$state()` - Use `$derived.by(() => ...)` for function-based derivations - Error boundaries have limited scope ## docs/svelte/01-introduction/03-svelte-files.md # Svelte Files ## ` ``` ## ` ``` ## ` ``` All three sections (script, styles, markup) are optional. ## docs/svelte/01-introduction/04-svelte-js-files.md # .svelte.js and .svelte.ts files Svelte 5 operates on `.svelte.js` and `.svelte.ts` files in addition to `.svelte` files. These files: - Behave like regular JS/TS modules - Support runes for reactive logic - Allow sharing reactive state across your app ```js // store.svelte.js export let $state count = 0; export const increment = () => count += 1; ``` > Note: You cannot export reassigned state across modules. ## docs/svelte/02-runes/01-what-are-runes.md # Svelte 5 Runes Runes are special compiler-controlled symbols in `.svelte` and `.svelte.js`/`.svelte.ts` files with a `$` prefix. ## Key Characteristics - No imports needed - built into Svelte - Not assignable to variables or passable as arguments - Only valid in specific positions (compiler will warn) - Always prefixed with `$` ```js let message = $state('hello'); ``` > Runes are new in Svelte 5 and replace the older reactive syntax. ## docs/svelte/02-runes/02-$state.md # Svelte 5 Runes - Condensed Documentation ## $state Creates reactive state that triggers UI updates when changed. ```svelte ``` ### Deep state Arrays and objects become deeply reactive state proxies: ```svelte ``` - Modifying nested properties triggers UI updates - New objects added to arrays are automatically proxified - Destructuring breaks reactivity ### Classes Use $state in class fields: ```js class Todo { done = $state(false); text = $state(); constructor(text) { this.text = text; } reset() { this.text = ''; this.done = false; } } ``` When using methods, handle `this` context: ```svelte ``` Or use arrow functions in class: ```js reset = () => { this.text = ''; this.done = false; } ``` ## $state.raw For non-deeply reactive state: ```js let person = $state.raw({ name: 'Heraclitus', age: 49 }); // No effect person.age += 1; // Works - creates new object person = { name: 'Heraclitus', age: 50 }; ``` ## $state.snapshot Create static copy of reactive state: ```svelte ``` ## Passing state State is passed by value, not by reference: ```js function add(a, b) { return a + b; } let a = $state(1); let b = $state(2); let total = add(a, b); // total = 3 a = 3; // total still 3 ``` ## Cross-module state Can't export directly reassigned state: ```js // Not allowed export let count = $state(0); export function increment() { count += 1; } ``` Instead, either: 1. Export object with properties: ```js export const counter = $state({ count: 0 }); export function increment() { counter.count += 1; } ``` 2. Export getter functions: ```js let count = $state(0); export function getCount() { return count; } export function increment() { count += 1; } ``` ## docs/svelte/02-runes/03-$derived.md # $derived Rune The `$derived` rune creates reactive values that automatically update when their dependencies change. ## Basic Usage ```svelte

{count} doubled is {doubled}

``` ## $derived.by For complex derivations that need multiple statements: ```svelte ``` ## Dependencies Any state read synchronously inside the `$derived` expression becomes a dependency. Use `untrack` to exempt state from being a dependency. ## Overriding Derived Values You can temporarily override derived values by reassigning them (useful for optimistic UI): ```svelte ``` ## Reactivity Behavior - Unlike `$state`, `$derived` values are not deeply reactive proxies - When accessing a property from reactive state, mutations to that property will affect the underlying state ## Update Propagation Svelte uses push-pull reactivity: - Dependencies are notified immediately when state changes - Derived values are only recalculated when read - Updates are skipped if the new value is referentially identical to the previous value ```svelte ``` ## docs/svelte/02-runes/04-$effect.md # Svelte 5 $effect Rune ## Basic Usage Effects run when state updates, useful for third-party libraries, canvas manipulation, or network requests. They only run in the browser. ```svelte ``` ## Lifecycle - Effects run after DOM mounting and in a microtask after state changes - Re-runs are batched and happen after DOM updates - Can return a teardown function that runs before effect re-runs or when destroyed ```svelte

{count}

``` ## Dependencies - Automatically tracks reactive values read synchronously - Async values (after `await` or in `setTimeout`) aren't tracked - Only reruns when the object it reads changes, not when properties change - Dependencies can change based on conditional code ```svelte

{state.value} doubled is {derived.value}

``` ## Variants ### `$effect.pre` Runs before DOM updates: ```svelte
{#each messages as message}

{message}

{/each}
``` ### `$effect.tracking` Tells if code is running in a tracking context: ```svelte

in template: {$effect.tracking()}

``` ### `$effect.root` Creates a non-tracked scope without auto-cleanup: ```js const destroy = $effect.root(() => { $effect(() => { // setup }); return () => { // cleanup }; }); // later... destroy(); ``` ## When Not To Use `$effect` Avoid using for state synchronization. Instead of: ```svelte ``` Use `$derived`: ```svelte ``` For linked values, use function bindings instead of effects: ```svelte ``` ## docs/svelte/02-runes/05-$props.md # $props in Svelte 5 The `$props` rune defines component inputs. ## Basic Usage ```svelte ``` ```svelte

this component is {adjective}

``` ## Fallback Values ```js let { adjective = 'happy' } = $props(); ``` > Note: Fallback values are not reactive state proxies ## Renaming Props ```js let { super: trouper = 'lights are gonna find me' } = $props(); ``` ## Rest Props ```js let { a, b, c, ...others } = $props(); ``` ## Updating Props Props update when parent values change. Child components can temporarily override prop values: ```svelte ``` ```svelte ``` ### Important Rules 1. You can reassign props but should not mutate them unless they are `$bindable` 2. Mutating regular objects has no effect 3. Mutating reactive state proxies works but triggers an `ownership_invalid_mutation` warning 4. Fallback values are not reactive state proxies, so mutations won't cause updates ## Type Safety ```svelte ``` With JSDoc: ```svelte ``` ## $props.id() Generates a unique ID for the component instance: ```svelte
``` ## docs/svelte/02-runes/06-$bindable.md # Svelte 5 Runes Documentation ## $bindable Enables two-way data binding between parent and child components. ```svelte /// file: FancyInput.svelte ``` Parent component can use `bind:` directive: ```svelte /// file: App.svelte

{message}

``` Specify fallback value when no prop is passed: ```js /// file: FancyInput.svelte let { value = $bindable('fallback'), ...props } = $props(); ``` > **Note**: Props are normally one-way (parent to child). Use `$bindable` sparingly to allow data flow from child to parent. ## docs/svelte/02-runes/07-$inspect.md # Svelte 5 Documentation: $inspect ## Basic Usage ```svelte ``` > **Note**: `$inspect` only works during development. In production, it becomes a no-op. ## $inspect(...).with Customize logging behavior with a callback: ```svelte ``` Quick trace shorthand: ```js $inspect(stuff).with(console.trace); ``` ## $inspect.trace(...) Traces reactive dependencies in development: ```svelte ``` Accepts an optional label parameter. ## docs/svelte/02-runes/08-$host.md # $host When compiling a component as a custom element, the `$host` rune provides access to the host element. ```svelte /// file: Stepper.svelte ``` ```svelte /// file: App.svelte count -= 1} onincrement={() => count += 1} >

count: {count}

``` ## docs/svelte/03-template-syntax/01-basic-markup.md # Basic Markup in Svelte 5 ## Tags ```svelte
``` - Lowercase tags (`
`) = HTML elements - Capitalized tags or dot notation (``, ``) = components ## Element Attributes ```svelte
``` - Values can be unquoted: `` - Can contain JS expressions: `page {p}` - Can be JS expressions: `` - Boolean attributes included if truthy, excluded if falsy - Other attributes included unless nullish (`null`/`undefined`) - Shorthand: `` instead of `` ## Component Props ```svelte ``` - Spread props: `` - Same shorthand as attributes: `{name}` instead of `name={name}` ## Events ```svelte ``` - Event attributes are case-sensitive - Same rules as attributes (shorthand, spreading) - `ontouchstart` and `ontouchmove` are passive by default ### Event Delegation Svelte uses event delegation for many common events: - `click`, `input`, `change`, `keydown`, `mousedown`, etc. Gotchas: - Manual dispatched events need `{bubbles: true}` - Avoid `stopPropagation` with `addEventListener` ## Text Expressions ```svelte

Hello {name}!

{a} + {b} = {a + b}.

``` - RegExp literals need parentheses: `{(/^[A-Za-z ]+$/).test(value) ? x : y}` - For HTML content: `{@html potentiallyUnsafeHtmlString}` ## Comments ```svelte ``` Special comments: - `` to disable warnings - `` for component documentation ## docs/svelte/03-template-syntax/02-if.md # {#if ...} ```svelte {#if expression}...{/if} {#if expression}...{:else if expression}...{/if} {#if expression}...{:else}...{/if} ``` Conditionally render content with if blocks: ```svelte {#if answer === 42}

what was the question?

{/if} ``` Chain conditions with `:else if` and `:else`: ```svelte {#if porridge.temperature > 100}

too hot!

{:else if 80 > porridge.temperature}

too cold!

{:else}

just right!

{/if} ``` Blocks can wrap elements or text within elements. ## docs/svelte/03-template-syntax/03-each.md # Svelte 5 Each Blocks ## Basic Usage ```svelte {#each expression as name}...{/each} {#each expression as name, index}...{/each} ``` Iterate over arrays, array-likes, or iterables (Map, Set, etc.): ```svelte

Shopping list

    {#each items as item}
  • {item.name} x {item.qty}
  • {/each}
``` With index: ```svelte {#each items as item, i}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} ``` ## Keyed Each Blocks ```svelte {#each expression as name (key)}...{/each} {#each expression as name, index (key)}...{/each} ``` Keys help Svelte efficiently update lists when data changes: ```svelte {#each items as item (item.id)}
  • {item.name} x {item.qty}
  • {/each} {#each items as item, i (item.id)}
  • {i + 1}: {item.name} x {item.qty}
  • {/each} ``` ## Destructuring ```svelte {#each items as { id, name, qty }, i (id)}
  • {i + 1}: {name} x {qty}
  • {/each} {#each objects as { id, ...rest }}
  • {id}
  • {/each} {#each items as [id, ...rest]}
  • {id}
  • {/each} ``` ## Each Without Item For repeating n times: ```svelte {#each { length: 8 }, rank} {#each { length: 8 }, file}
    {/each} {/each} ``` ## Else Blocks For empty lists: ```svelte {#each todos as todo}

    {todo.text}

    {:else}

    No tasks today!

    {/each} ``` ## docs/svelte/03-template-syntax/04-key.md # {#key ...} ```svelte {#key expression}...{/key} ``` Key blocks destroy and recreate their contents when an expression value changes: ```svelte {#key value} {/key} ``` Useful for: - Reinstantiating components when values change - Triggering transitions on value changes: ```svelte {#key value}
    {value}
    {/key} ``` ## docs/svelte/03-template-syntax/05-await.md # {#await ...} Await blocks handle the three states of a Promise: pending, fulfilled, or rejected. ```svelte {#await promise}

    waiting for the promise to resolve...

    {:then value}

    The value is {value}

    {:catch error}

    Something went wrong: {error.message}

    {/await} ``` > During SSR, only the pending branch renders. Non-Promise expressions only render the `:then` branch. ## Simplified Variants Omit `:catch` when error handling isn't needed: ```svelte {#await promise}

    waiting for the promise to resolve...

    {:then value}

    The value is {value}

    {/await} ``` Omit pending state: ```svelte {#await promise then value}

    The value is {value}

    {/await} ``` Show only error state: ```svelte {#await promise catch error}

    The error is {error}

    {/await} ``` > Use with `import()` for lazy component loading: > ```svelte > {#await import('./Component.svelte') then { default: Component }} > > {/await} > ``` ## docs/svelte/03-template-syntax/06-snippet.md # Svelte 5 Snippets ## {#snippet ...} ```svelte {#snippet name()}...{/snippet} {#snippet name(param1, param2, paramN)}...{/snippet} ``` Snippets create reusable markup chunks within components: ```svelte {#snippet figure(image)}
    {image.caption}
    {image.caption}
    {/snippet} {#each images as image} {#if image.href} {@render figure(image)} {:else} {@render figure(image)} {/if} {/each} ``` Snippets can have parameters with default values and support destructuring (no rest parameters). ## Scope Snippets can access values from outer scope: ```svelte {#snippet hello(name)}

    hello {name}! {message}!

    {/snippet} {@render hello('alice')} {@render hello('bob')} ``` Snippets are visible to siblings and their children: ```svelte
    {#snippet x()} {#snippet y()}...{/snippet} {@render y()} {/snippet} {@render y()}
    {@render x()} ``` Snippets can reference themselves and each other: ```svelte {#snippet blastoff()} ๐Ÿš€ {/snippet} {#snippet countdown(n)} {#if n > 0} {n}... {@render countdown(n - 1)} {:else} {@render blastoff()} {/if} {/snippet} {@render countdown(10)} ``` ## Passing to Components Snippets can be passed as props: ```svelte {#snippet header()} fruit qty price total {/snippet} {#snippet row(d)} {d.name} {d.qty} {d.price} {d.qty * d.price} {/snippet} ``` Snippets declared inside component tags become props automatically: ```svelte
    {#snippet header()} {/snippet} {#snippet row(d)} {/snippet}
    fruit qty price total{d.name} {d.qty} {d.price} {d.qty * d.price}
    ``` Non-snippet content becomes the `children` snippet: ```svelte ``` ```svelte ``` > [!NOTE] Avoid having props named `children` if you also have content inside the component Handle optional snippets: ```svelte {@render children?.()} ``` Or with fallback: ```svelte {#if children} {@render children()} {:else} fallback content {/if} ``` ## Typing Snippets ```svelte ``` With generics: ```svelte ``` ## Exporting Snippets Top-level snippets can be exported (Svelte 5.5.0+): ```svelte {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` ## Advanced - Programmatic snippets can be created with `createRawSnippet` API - Snippets replace slots from Svelte 4 (slots are deprecated in Svelte 5) ## docs/svelte/03-template-syntax/07-@render.md # {@render ...} Use `{@render ...}` to render [snippets](snippet). ```svelte {#snippet sum(a, b)}

    {a} + {b} = {a + b}

    {/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)} ``` The expression can be an identifier or any JavaScript expression: ```svelte {@render (cool ? coolSnippet : lameSnippet)()} ``` ## Optional snippets For potentially undefined snippets, use optional chaining: ```svelte {@render children?.()} ``` Or use an `{#if ...}` block with fallback content: ```svelte {#if children} {@render children()} {:else}

    fallback content

    {/if} ``` ## docs/svelte/03-template-syntax/08-@html.md # {@html ...} Use `{@html ...}` to inject raw HTML: ```svelte
    {@html content}
    ``` > [!NOTE] Always escape strings or use controlled values to prevent XSS attacks. ## Limitations - Expression must be valid standalone HTML - Will not compile Svelte code - Cannot be split across multiple tags ## Styling Content rendered with `{@html ...}` is invisible to Svelte's style scoping: ```svelte ``` Use `:global` modifier to target elements inside the HTML content. ## docs/svelte/03-template-syntax/09-@const.md # {@const ...} The `{@const ...}` tag defines a local constant within a block. ```svelte {#each boxes as box} {@const area = box.width * box.height} {box.width} * {box.height} = {area} {/each} ``` Only allowed as an immediate child of: - Blocks (`{#if ...}`, `{#each ...}`, `{#snippet ...}`, etc.) - Components (``) - `` ## docs/svelte/03-template-syntax/10-@debug.md # {@debug ...} The `{@debug ...}` tag provides debugging capabilities in Svelte components: ```svelte {@debug user}

    Hello {user.firstname}!

    ``` ## Usage - Logs values when they change and pauses execution if devtools are open - Accepts comma-separated variable names (not expressions): ```svelte {@debug user} {@debug user1, user2, user3} ``` - Without arguments, inserts a `debugger` statement triggered on any state change: ```svelte {@debug} ``` ## docs/svelte/03-template-syntax/11-bind.md # Svelte 5 and SvelteKit Condensed Documentation ## bind: Data flows down from parent to child. `bind:` allows data to flow upward. ```svelte ``` ### Function bindings (v5.9.0+) ```svelte value, (v) => value = v.toLowerCase()} />
    ...
    ``` ### Input bindings ```svelte
    ``` ### Group bindings ```svelte ``` ### File inputs ```svelte ``` ### Select bindings ```svelte ``` ### Media element bindings ```svelte ``` ### Other element bindings ```svelte
    Title Content
    ``` ### bind:this ```svelte ``` ### Component bindings ```svelte ``` ## docs/svelte/03-template-syntax/12-use.md # use: Directive Actions are functions called when an element is mounted, added with the `use:` directive. ```svelte
    ...
    ``` ## With Arguments ```svelte
    ...
    ``` Actions are called once (not during SSR) and won't run again if arguments change. ## Typing ```svelte
    ...
    ``` The `Action` interface accepts three optional type arguments: - Node type (can be `Element` for all elements) - Parameter type - Custom event handlers created by the action ## docs/svelte/03-template-syntax/13-transition.md # Svelte 5 Transitions ## Basic Usage Transitions are triggered when elements enter or leave the DOM due to state changes. ```svelte {#if visible}
    fades in and out
    {/if} ``` ## Local vs Global Transitions are local by default - they only play when their immediate block is created/destroyed. ```svelte {#if x} {#if y}

    fades in and out only when y changes

    fades in and out when x or y change

    {/if} {/if} ``` ## Parameters Transitions can accept parameters: ```svelte {#if visible}
    fades in and out over two seconds
    {/if} ``` ## Custom Transitions Custom transitions return an object with animation properties: ```svelte {#if visible}
    whooshes in
    {/if} ``` Use `css` function for better performance (runs off main thread). For complex animations, use `tick`: ```svelte {#if visible}

    The quick brown fox jumps over the lazy dog

    {/if} ``` Custom transitions receive an `options` object with `direction` (`in`, `out`, or `both`). ## Events Transition elements dispatch these events: - `introstart` - `introend` - `outrostart` - `outroend` ```svelte {#if visible}

    (status = 'intro started')} onoutrostart={() => (status = 'outro started')} onintroend={() => (status = 'intro ended')} onoutroend={() => (status = 'outro ended')} > Flies in and out

    {/if} ``` ## docs/svelte/03-template-syntax/14-in-and-out.md # in: and out: Directives These directives create unidirectional transitions, unlike bidirectional `transition:` directives. - `in:` transitions play when element enters - `out:` transitions play when element leaves - Both transitions run simultaneously during direction changes - Aborted transitions restart from scratch ```svelte {#if visible}
    flies in, fades out
    {/if} ``` ## docs/svelte/03-template-syntax/15-animate.md # animate: Animations trigger when contents of a keyed each block are re-ordered (not when elements are added/removed). ```svelte {#each list as item, index (item)}
  • {item}
  • {/each} ``` ## Animation Parameters ```svelte {#each list as item, index (item)}
  • {item}
  • {/each} ``` ## Custom animation functions ```js 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 } ``` Custom animations receive: - `node`: The HTML element - `animation`: Object with `from` and `to` DOMRect properties - `params`: Any parameters passed to the directive Return an object with: - `css` method: Creates a web animation (preferred for performance) - `tick` method: Called during animation (use only when CSS can't achieve the effect) The `t` argument is a value from 0-1 after easing, `u` equals `1-t`. ### CSS Example ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` ### Tick Example ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` > Prefer `css` over `tick` when possible - web animations run off the main thread for better performance. ## docs/svelte/03-template-syntax/17-style.md # style: directive The `style:` directive provides a shorthand for setting styles on elements. ## Basic Usage ```svelte
    ...
    ...
    ``` ## Dynamic Values ```svelte
    ...
    ``` ## Shorthand Form ```svelte
    ...
    ``` ## Multiple Styles ```svelte
    ...
    ``` ## Important Modifier ```svelte
    ...
    ``` ## Precedence When combined with `style` attribute, directives take precedence: ```svelte
    This will be red
    ``` ## docs/svelte/03-template-syntax/18-class.md # Svelte Class Handling ## Class Attribute ### Basic Usage ```svelte
    ...
    ``` > Note: Falsy values are stringified, but `undefined`/`null` omit the attribute entirely. ### Objects and Arrays (Svelte 5.16+) **Object syntax** - truthy keys become classes: ```svelte
    ...
    ``` **Array syntax** - truthy values are combined: ```svelte
    ...
    ``` **Combining with props**: ```svelte ``` **Usage with TypeScript**: ```svelte
    ...
    ``` ## Class Directive Legacy approach, less flexible than object/array syntax: ```svelte
    ...
    ``` Shorthand when name matches value: ```svelte
    ...
    ``` > Note: Prefer the attribute approach with object/array syntax over class directives in Svelte 5.16+. ## docs/svelte/04-styling/01-scoped-styles.md # Scoped Styles in Svelte ## Basic Scoping Styles in ` ``` ## Specificity - Scoped selectors get a specificity boost of 0-1-0 from the added class - Component styles override global styles with the same selector, even if loaded later - Multiple occurrences of the scoping class after the first use `:where(.svelte-xyz123)` to avoid further specificity increases ## Scoped Keyframes Keyframe animations are also scoped to the component: ```svelte ``` ## docs/svelte/04-styling/02-global-styles.md # Global Styles in Svelte ## :global(...) Apply styles globally to specific selectors: ```svelte ``` For global keyframes, prepend names with `-global-`: ```svelte ``` ## :global Apply styles to multiple selectors globally using a block: ```svelte ``` ## docs/svelte/04-styling/03-custom-properties.md # Custom Properties Pass CSS custom properties to components: ```svelte ``` This creates a wrapper element: ```svelte ``` For SVG elements, it uses `` instead: ```svelte ``` Inside components, access these properties with fallbacks: ```svelte ``` Custom properties can also be defined on parent elements (like `:root`) to apply globally. > Note: The wrapper element won't affect layout but may impact CSS selectors using the `>` combinator. ## docs/svelte/04-styling/04-nested-style-elements.md # Nested `
    ``` ## docs/svelte/05-special-elements/01-svelte-boundary.md # Svelte 5 Error Boundaries ## `` ```svelte ... ``` Error boundaries isolate parts of your app so errors don't break the entire application. - Catches errors during rendering, updating, or in `$effect` functions - Does NOT catch errors in event handlers, `setTimeout`, or async operations ## Properties ### `failed` Renders fallback UI with error details and reset function: ```svelte {#snippet failed(error, reset)} {/snippet} ``` ### `onerror` Handles errors programmatically: ```svelte report(e)}> ... ``` Using error and reset outside the boundary: ```svelte {#if error} {/if} ``` Errors in `onerror` propagate to parent boundaries. ## docs/svelte/05-special-elements/02-svelte-window.md # Svelte Window Element ## `` Adds event listeners to the `window` object without manual cleanup. ```svelte ``` Must appear at the top level of your component. ### Event Example ```svelte ``` ### Bindable Properties ```svelte ``` **Readonly bindings:** - `innerWidth` - `innerHeight` - `outerWidth` - `outerHeight` - `online` (alias for `window.navigator.onLine`) - `devicePixelRatio` **Writable bindings:** - `scrollX` - `scrollY` > Note: Page won't scroll to initial bound values. For initial scrolling, use `scrollTo()` in an `$effect`. ## docs/svelte/05-special-elements/03-svelte-document.md # ```svelte ``` Allows adding event listeners and actions to the `document` object. - Must appear only at the top level of your component - Never place inside blocks or elements - Useful for events that don't fire on `window` (e.g., `visibilitychange`) ```svelte ``` ## Bindable Properties (readonly) - `activeElement` - `fullscreenElement` - `pointerLockElement` - `visibilityState` ## docs/svelte/05-special-elements/04-svelte-body.md # ```svelte ``` Allows adding event listeners and actions to `document.body`. ```svelte ``` **Important:** - Only use at the top level of your component - Never place inside blocks or elements - Useful for events like `mouseenter`/`mouseleave` that don't fire on `window` ## docs/svelte/05-special-elements/05-svelte-head.md # ```svelte ... ``` Inserts elements into `document.head`. During SSR, head content is exposed separately from body content. **Rules:** - Must appear at top level of component - Cannot be inside blocks or elements **Example:** ```svelte Hello world! ``` ## docs/svelte/05-special-elements/06-svelte-element.md # ```svelte ``` Renders a dynamic element when the tag name is unknown at author time. ## Usage ```svelte ``` ## Key Points - Only supports `bind:this` binding - Nullish `this` values prevent rendering - Void elements (e.g., `br`, `hr`) cannot have children - Explicit namespace can be set with `xmlns` attribute: ```svelte ``` ## Limitations - `this` must be a valid DOM element tag - `#text` or `svelte:head` won't work ## docs/svelte/05-special-elements/07-svelte-options.md # ```svelte ``` ## Available Options - `runes={true|false}` - Forces component into runes or legacy mode - `namespace="html|svg|mathml"` - Sets component namespace (default: "html") - `customElement={...}` - Options for custom element compilation - `css="injected"` - Injects styles inline ```svelte ``` > Note: `immutable`, `accessors` options are deprecated in Svelte 5 and non-functional in runes mode. ## docs/svelte/06-runtime/01-stores.md # Svelte Stores ## Overview A store is an object that allows reactive access to a value via a store contract. Access store values in components with `$` prefix. ```svelte ``` ## When to Use Stores With Svelte 5 runes, stores are less necessary: - For logic extraction, use runes in `.svelte.js` or `.svelte.ts` files - For shared state, use `$state` objects ```ts /// file: state.svelte.js export const userState = $state({ name: 'name', /* ... */ }); ``` ```svelte

    User name: {userState.name}

    ``` Stores remain useful for complex async data streams or manual control over updates. ## svelte/store API ### `writable` Creates a store with values settable from outside components. ```js import { writable } from 'svelte/store'; const count = writable(0); count.subscribe((value) => { console.log(value); }); // logs '0' count.set(1); // logs '1' count.update((n) => n + 1); // logs '2' ``` Optional second argument for subscription handling: ```js import { writable } from 'svelte/store'; const count = writable(0, () => { console.log('got a subscriber'); return () => console.log('no more subscribers'); }); count.set(1); // does nothing const unsubscribe = count.subscribe((value) => { console.log(value); }); // logs 'got a subscriber', then '1' unsubscribe(); // logs 'no more subscribers' ``` ### `readable` Creates a store with values that can't be set from outside. ```ts import { readable } from 'svelte/store'; const time = readable(new Date(), (set) => { set(new Date()); const interval = setInterval(() => { set(new Date()); }, 1000); return () => clearInterval(interval); }); const ticktock = readable('tick', (set, update) => { const interval = setInterval(() => { update((sound) => (sound === 'tick' ? 'tock' : 'tick')); }, 1000); return () => clearInterval(interval); }); ``` ### `derived` Derives a store from other stores. ```ts import { derived } from 'svelte/store'; const doubled = derived(a, ($a) => $a * 2); ``` Async derivation with initial value: ```ts import { derived } from 'svelte/store'; const delayed = derived( a, ($a, set) => { setTimeout(() => set($a), 1000); }, 2000 ); const delayedIncrement = derived(a, ($a, set, update) => { set($a); setTimeout(() => update((x) => x + 1), 1000); }); ``` Cleanup function: ```ts import { derived } from 'svelte/store'; const tick = derived( frequency, ($frequency, set) => { const interval = setInterval(() => { set(Date.now()); }, 1000 / $frequency); return () => { clearInterval(interval); }; }, 2000 ); ``` Multiple source stores: ```ts import { derived } from 'svelte/store'; const summed = derived([a, b], ([$a, $b]) => $a + $b); const delayed = derived([a, b], ([$a, $b], set) => { setTimeout(() => set($a + $b), 1000); }); ``` ### `readonly` Makes a store readonly. ```js import { readonly, writable } from 'svelte/store'; const writableStore = writable(1); const readableStore = readonly(writableStore); readableStore.subscribe(console.log); writableStore.set(2); // console: 2 // readableStore.set(2); // ERROR ``` ### `get` Retrieves store value without subscribing. ```ts import { get } from 'svelte/store'; const value = get(store); ``` ## Store Contract A valid store must: 1. Have a `.subscribe` method that calls a subscription function with current value 2. Return an unsubscribe function 3. Optionally have a `.set` method (for writable stores) ## docs/svelte/06-runtime/02-context.md # Context Context allows components to access values from parent components without prop-drilling. ## Basic Usage ```svelte ``` ```svelte

    {message}, inside Child.svelte

    ``` Usage: ```svelte ``` Available functions: `setContext`, `getContext`, `hasContext`, `getAllContexts` ## Context with State ```svelte ``` โš ๏ธ Update properties directly rather than reassigning the object: ```svelte ``` ## Type-Safe Context ```js /// file: context.js // @filename: ambient.d.ts interface User {} // @filename: index.js //cut import { getContext, setContext } from 'svelte'; const key = {}; /** @param {User} user */ export function setUserContext(user) { setContext(key, user); } export function getUserContext() { return /** @type {User} */ (getContext(key)); } ``` ## Alternative to Global State Context is safer than global state for server-side rendering, as it's not shared between requests. ```js /// file: state.svelte.js export const myGlobalState = $state({ user: { // ... } // ... }); ``` Using global state during SSR can leak data between users: ```svelte ``` ## docs/svelte/06-runtime/03-lifecycle-hooks.md # Svelte 5 Lifecycle Hooks ## `onMount` Runs after component is mounted to the DOM. Not executed during SSR. ```svelte ``` Return a function for cleanup: ```svelte ``` > [!NOTE] Cleanup only works when function is returned synchronously (not with async functions). ## `onDestroy` Runs before component unmounts. Works in SSR components. ```svelte ``` ## `tick` Returns a promise that resolves after pending state changes are applied. ```svelte ``` ## Deprecated: `beforeUpdate` / `afterUpdate` Replaced by `$effect.pre` and `$effect` in Svelte 5. ### Chat Window Example ```svelte
    {#each messages as message}

    {message}

    {/each}
    ``` ## docs/svelte/06-runtime/04-imperative-component-api.md # Svelte 5 Imperative Component API ## `mount` Creates and mounts a component to a DOM element: ```js import { mount } from 'svelte'; import App from './App.svelte'; const app = mount(App, { target: document.querySelector('#app'), props: { some: 'property' } }); ``` **Note**: Effects (including `onMount` and actions) don't run during `mount`. Use `flushSync()` to force pending effects to run. ## `unmount` Removes a previously mounted component: ```js import { mount, unmount } from 'svelte'; import App from './App.svelte'; const app = mount(App, { target: document.body }); // later unmount(app, { outro: true }); ``` Returns a `Promise` that resolves after transitions complete (if `outro: true`) or immediately. ## `render` (Server-only) Renders a component to HTML strings: ```js import { render } from 'svelte/server'; import App from './App.svelte'; const result = render(App, { props: { some: 'property' } }); result.body; // HTML for result.head; // HTML for ``` ## `hydrate` Makes server-rendered HTML interactive: ```js import { hydrate } from 'svelte'; import App from './App.svelte'; const app = hydrate(App, { target: document.querySelector('#app'), props: { some: 'property' } }); ``` Like `mount`, effects don't run during `hydrate` - use `flushSync()` afterward if needed. ## docs/svelte/07-misc/02-testing.md # Svelte Testing Guide ## Unit and Integration Testing with Vitest ### Setup ```bash npm install -D vitest ``` Configure Vite: ```js // vite.config.js import { defineConfig } from'vitest/config'; export default defineConfig({ // Tell Vitest to use browser entry points resolve: process.env.VITEST ? { conditions: ['browser'] } : undefined }); ``` ### Testing JavaScript Functions ```js // 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); }); ``` ### Using Runes in Tests Filename must include `.svelte`: ```js // 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); }); ``` ### Testing Effects Wrap in `$effect.root` and use `flushSync()`: ```js // 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); let log = logger(() => count); flushSync(); expect(log.value).toEqual([0]); count = 1; flushSync(); expect(log.value).toEqual([0, 1]); }); cleanup(); }); ``` ## Component Testing ### Setup ```bash npm install -D jsdom ``` Update Vite config: ```js // vite.config.js import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { environment: 'jsdom' }, resolve: process.env.VITEST ? { conditions: ['browser'] } : undefined }); ``` ### Basic Component Test ```js // component.test.js import { flushSync, mount, unmount } from 'svelte'; import { expect, test } from 'vitest'; import Component from './Component.svelte'; test('Component', () => { const component = mount(Component, { target: document.body, props: { initial: 0 } }); expect(document.body.innerHTML).toBe(''); document.body.querySelector('button').click(); flushSync(); expect(document.body.innerHTML).toBe(''); unmount(component); }); ``` ### Using Testing Library ```js // 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'; test('Component', async () => { const user = userEvent.setup(); render(Component); const button = screen.getByRole('button'); expect(button).toHaveTextContent(0); await user.click(button); expect(button).toHaveTextContent(1); }); ``` ## E2E Testing with Playwright ### Setup Install via VS Code extension or: ```bash npm init playwright ``` Configure Playwright: ```js // playwright.config.js const config = { webServer: { command: 'npm run build && npm run preview', port: 4173 }, testDir: 'tests', testMatch: /(.+\.)?(test|spec)\.[jt]s/ }; export default config; ``` ### Basic Test ```js // tests/hello-world.spec.js import { expect, test } from '@playwright/test'; test('home page has expected h1', async ({ page }) => { await page.goto('/'); await expect(page.locator('h1')).toBeVisible(); }); ``` ## docs/svelte/07-misc/03-typescript.md # Svelte 5 TypeScript Guide ## Basic Usage Add `lang="ts"` to script tags: ```svelte ``` Only type-only features are supported by default. Features requiring code generation (enums, access modifiers with initializers) need a preprocessor. ## Setup ### SvelteKit/Vite (Recommended) ```ts // svelte.config.js import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { preprocess: vitePreprocess() }; export default config; ``` For non-type-only features: ```ts // svelte.config.js import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { preprocess: vitePreprocess({ script: true }) }; export default config; ``` ### tsconfig.json Requirements - `target`: At least `ES2022` or `ES2015` with `useDefineForClassFields: true` - `verbatimModuleSyntax: true` - `isolatedModules: true` ## Typing Components ### Typing $props ```svelte ``` ### Generic Components ```svelte ``` ### Wrapper Components ```svelte ``` For elements without dedicated types: ```svelte ``` ## Typing $state ```ts let count: number = $state(0); ``` For uninitialized state: ```ts class Counter { count = $state() as number; constructor(initial: number) { this.count = initial; } } ``` ## Component Types ```svelte ``` Extract component props: ```ts import type { Component, ComponentProps } from 'svelte'; import MyComponent from './MyComponent.svelte'; function withProps>( component: TComponent, props: ComponentProps ) {} ``` Component constructor/instance types: ```svelte ``` ## Extending DOM Types For custom elements or attributes: ```ts // additional-svelte-typings.d.ts declare namespace svelteHTML { interface IntrinsicElements { 'my-custom-element': { someattribute: string; 'on:event': (e: CustomEvent) => void }; } interface HTMLAttributes { onbeforeinstallprompt?: (event: any) => any; mycustomattribute?: any; } } ``` Alternative approach: ```ts // additional-svelte-typings.d.ts import { HTMLButtonAttributes } from 'svelte/elements'; declare module 'svelte/elements' { export interface SvelteHTMLElements { 'custom-button': HTMLButtonAttributes; } export interface HTMLButtonAttributes { veryexperimentalattribute?: string; } } export {}; ``` ## docs/kit/10-getting-started/10-introduction.md # SvelteKit Introduction ## What is SvelteKit? SvelteKit is a framework for building web applications using Svelte. Similar to Next.js (React) or Nuxt (Vue). ## What is Svelte? Svelte is a UI component framework that compiles components to optimized JavaScript and CSS. ## SvelteKit vs Svelte Svelte handles UI components. SvelteKit provides a complete application framework with: - Routing - Build optimizations - Offline support - Page preloading - Configurable rendering (SSR, CSR, prerendering) - Image optimization - HMR development experience via Vite ## Getting Started For beginners, check out the [interactive tutorial](/tutorial/kit) or get help in [Discord](/chat). ## docs/kit/10-getting-started/20-creating-a-project.md # Creating a SvelteKit Project ```bash npx sv create my-app cd my-app npm install npm run dev ``` This scaffolds a new project with optional TypeScript setup. Server runs on [localhost:5173](http://localhost:5173). ## Core Concepts - Pages are Svelte components - Pages are created in `src/routes` directory - Pages are server-rendered first, then hydrated client-side ## Editor Setup - Recommended: VS Code with [Svelte extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) - [Other editor support](https://sveltesociety.dev/resources#editor-support) ## docs/kit/10-getting-started/25-project-types.md # Project Types in SvelteKit SvelteKit offers configurable rendering to build various application types. Rendering settings can be mixed for optimal performance. ## Default Rendering - First page: Server-side rendering (SSR) - Subsequent pages: Client-side rendering (CSR) - Benefits: Better SEO, perceived performance, and smooth navigation ## Static Site Generation - Use `adapter-static` for fully prerendered sites - Selectively prerender pages with `prerender` option - For large sites, use Incremental Static Regeneration with `adapter-vercel` ## Single-Page App ```js // In src/routes/+layout.js export const ssr = false; ``` ## Multi-Page App ```js // In src/routes/+page.js export const csr = false; ``` Or use `data-sveltekit-reload` on links to force server rendering. ## Deployment Options ### Separate Backend - Deploy SvelteKit frontend separately with `adapter-node` or serverless adapter - Skip `server` files when using external backend ### Serverless - Use `adapter-auto` (default) for zero-config deployment - Platform-specific: `adapter-vercel`, `adapter-netlify`, `adapter-cloudflare` - Some offer edge rendering for improved latency ### Self-Hosted - Use `adapter-node` for your own server/VPS or containers ## Other Project Types ### Library - Create Svelte libraries with `@sveltejs/package` ### Offline/PWA - Full support for service workers ### Mobile Apps - Use Tauri or Capacitor with SvelteKit SPA - Consider `bundleStrategy: 'single'` to limit requests ### Desktop Apps - Tauri, Wails, or Electron with SvelteKit SPA ### Browser Extensions - Use `adapter-static` or community adapters ### Embedded Devices - Consider `bundleStrategy: 'single'` to reduce concurrent requests ## docs/kit/10-getting-started/30-project-structure.md # Project Structure in SvelteKit A typical SvelteKit project structure: ```bash my-project/ โ”œ src/ โ”‚ โ”œ lib/ โ”‚ โ”‚ โ”œ server/ # Server-only code โ”‚ โ”‚ โ”” [lib files] # Shared components/utilities โ”‚ โ”œ params/ # Param matchers โ”‚ โ”œ routes/ # Application routes โ”‚ โ”œ app.html # Page template โ”‚ โ”œ error.html # Error page โ”‚ โ”œ hooks.client.js โ”‚ โ”œ hooks.server.js โ”‚ โ”” service-worker.js โ”œ static/ # Static assets โ”œ tests/ # Tests โ”œ package.json โ”œ svelte.config.js โ”œ tsconfig.json โ”” vite.config.js ``` ## Key Files ### src/app.html Template with placeholders: - `%sveltekit.head%` - Links, scripts, and `` content - `%sveltekit.body%` - Rendered page markup (place inside a container element) - `%sveltekit.assets%` - Path to assets - `%sveltekit.nonce%` - CSP nonce - `%sveltekit.env.[NAME]%` - Environment variables (must start with public prefix) ### src/error.html Fallback error page with placeholders: - `%sveltekit.status%` - HTTP status - `%sveltekit.error.message%` - Error message ### src/lib Library code importable via `$lib` alias. Server-only code goes in `lib/server/` and is importable via `$lib/server`. ### src/routes Contains application routes and route-specific components. ### static Static assets served as-is (favicon, robots.txt, etc.) ### Configuration Files - **package.json**: Must include `@sveltejs/kit`, `svelte`, and `vite` as `devDependencies` - **svelte.config.js**: Svelte and SvelteKit configuration - **vite.config.js**: Vite configuration with `@sveltejs/kit/vite` plugin - **tsconfig.json**: TypeScript configuration (extends `.svelte-kit/tsconfig.json`) ### Generated Files The `.svelte-kit` directory contains generated files that can be safely deleted (they'll be regenerated). ## docs/kit/10-getting-started/40-web-standards.md # Svelte Web Standards ## Fetch APIs SvelteKit uses standard `fetch` for network requests in hooks, server routes, and browser. > Special `fetch` version in `load` functions, server hooks, and API routes allows direct endpoint invocation during SSR without HTTP calls, preserving credentials. ### Request ```js // Access in hooks and server routes export function GET({ request }) { const data = await request.json(); // or request.formData() } ``` ### Response ```js // Return from server routes export function GET() { return new Response('Hello', { status: 200 }); } ``` ### Headers ```js /// file: src/routes/what-is-my-user-agent/+server.js import { json } from '@sveltejs/kit'; /** @type {import('./$types').RequestHandler} */ export function GET({ request }) { // log all headers console.log(...request.headers); // create a JSON Response using a header we received return json({ // retrieve a specific header userAgent: request.headers.get('user-agent') }, { // set a header on the response headers: { 'x-custom-header': 'potato' } }); } ``` ## FormData ```js /// file: src/routes/hello/+server.js import { json } from '@sveltejs/kit'; /** @type {import('./$types').RequestHandler} */ export async function POST(event) { const body = await event.request.formData(); // log all fields console.log([...body]); return json({ // get a specific field's value name: body.get('name') ?? 'world' }); } ``` ## Stream APIs Use `ReadableStream`, `WritableStream`, and `TransformStream` for large responses or chunked data. ## URL APIs Access URL properties via `event.url` in hooks/server routes, `page.url` in pages, and `from`/`to` in navigation events. ### URLSearchParams ```js const foo = url.searchParams.get('foo'); ``` ## Web Crypto ```js const uuid = crypto.randomUUID(); ``` ## docs/kit/20-core-concepts/10-routing.md # SvelteKit Routing ## +page ### +page.svelte Defines a page component rendered on server (SSR) and browser (CSR). ```svelte

    Hello and welcome to my site!

    About my site ``` Receive data from load functions: ```svelte

    {data.title}

    {@html data.content}
    ``` ### +page.js Load data for pages: ```js import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export function load({ params }) { if (params.slug === 'hello-world') { return { title: 'Hello world!', content: 'Welcome to our blog. Lorem ipsum dolor sit amet...' }; } error(404, 'Not found'); } ``` Configure page behavior with exports: - `export const prerender = true|false|'auto'` - `export const ssr = true|false` - `export const csr = true|false` ### +page.server.js Server-only load functions: ```js import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageServerLoad} */ export async function load({ params }) { const post = await getPostFromDatabase(params.slug); if (post) { return post; } error(404, 'Not found'); } ``` Also supports form actions and page options. ## +error Custom error pages: ```svelte

    {page.status}: {page.error.message}

    ``` SvelteKit walks up the tree to find the closest error boundary. ## +layout ### +layout.svelte Shared UI elements across multiple pages: ```svelte {@render children()} ``` Nested layouts: ```svelte

    Settings

    {@render children()} ``` ### +layout.js Load data for layouts: ```js /** @type {import('./$types').LayoutLoad} */ export function load() { return { sections: [ { slug: 'profile', title: 'Profile' }, { slug: 'notifications', title: 'Notifications' } ] }; } ``` ### +layout.server.js Server-only layout data loading, same pattern as +page.server.js. ## +server API routes with HTTP verb handlers: ```js import { error } from '@sveltejs/kit'; /** @type {import('./$types').RequestHandler} */ export function GET({ url }) { const min = Number(url.searchParams.get('min') ?? '0'); const max = Number(url.searchParams.get('max') ?? '1'); const d = max - min; if (isNaN(d) || d < 0) { error(400, 'min and max must be numbers, and min must be less than max'); } const random = min + Math.random() * d; return new Response(String(random)); } ``` Handling POST requests: ```js import { json } from '@sveltejs/kit'; /** @type {import('./$types').RequestHandler} */ export async function POST({ request }) { const { a, b } = await request.json(); return json(a + b); } ``` Fallback handler for unhandled methods: ```js /** @type {import('./$types').RequestHandler} */ export async function fallback({ request }) { return text(`I caught your ${request.method} request!`); } ``` Content negotiation happens automatically when +server.js and +page files share a directory. ## $types TypeScript definitions for routes: - `PageProps`/`LayoutProps` - Component props - `PageLoad`/`PageServerLoad`/`LayoutLoad`/`LayoutServerLoad` - Load function types - `RequestHandler` - Server endpoint handlers ## Other files - Any other files in route directories are ignored by SvelteKit - Use `$lib` for shared components and utilities ## docs/kit/20-core-concepts/20-load.md # Loading Data in SvelteKit ## Page Data Load data for pages using `+page.js` or `+page.server.js`: ```js // src/routes/blog/[slug]/+page.js export function load({ params }) { return { post: { title: `Title for ${params.slug} goes here`, content: `Content for ${params.slug} goes here` } }; } ``` ```svelte

    {data.post.title}

    {@html data.post.content}
    ``` ## Layout Data Load data for layouts using `+layout.js` or `+layout.server.js`: ```js // src/routes/blog/[slug]/+layout.server.js export async function load() { return { posts: await db.getPostSummaries() }; } ``` ```svelte
    {@render children()}
    ``` Child components can access parent layout data: ```svelte ``` ## Universal vs Server Load Functions **Server load functions** (`+page.server.js`, `+layout.server.js`): - Always run on the server - Can access database, filesystem, private env vars - Must return serializable data - Have access to `cookies`, `locals`, etc. **Universal load functions** (`+page.js`, `+layout.js`): - Run on server during SSR, then in browser - Useful for fetching from external APIs - Can return non-serializable data (like component constructors) - Receive data from server load functions via `data` property ## URL Data Access URL information in load functions: ```js export function load({ url, route, params }) { // url - URL instance with pathname, searchParams, etc. // route.id - current route path (e.g., '/a/[b]/[...c]') // params - derived from url.pathname and route.id } ``` ## Making Fetch Requests Use the provided `fetch` function for data fetching: ```js export async function load({ fetch, params }) { const res = await fetch(`/api/items/${params.id}`); const item = await res.json(); return { item }; } ``` ## Headers and Cookies Set response headers: ```js export async function load({ fetch, setHeaders }) { const response = await fetch(url); setHeaders({ 'cache-control': response.headers.get('cache-control') }); return response.json(); } ``` Access cookies in server load functions: ```js export async function load({ cookies }) { const sessionid = cookies.get('sessionid'); return { user: await db.getUser(sessionid) }; } ``` ## Parent Data Access data from parent load functions: ```js export async function load({ parent }) { const { a } = await parent(); return { b: a + 1 }; } ``` ## Errors and Redirects Throw errors: ```js import { error } from '@sveltejs/kit'; export function load({ locals }) { if (!locals.user) { error(401, 'not logged in'); } } ``` Redirect users: ```js import { redirect } from '@sveltejs/kit'; export function load({ locals }) { if (!locals.user) { redirect(307, '/login'); } } ``` ## Streaming with Promises Server load functions can stream promises: ```js export async function load({ params }) { return { comments: loadComments(params.slug), // streamed as it resolves post: await loadPost(params.slug) }; } ``` Use in templates: ```svelte {#await data.comments} Loading comments... {:then comments} {#each comments as comment}

    {comment.content}

    {/each} {:catch error}

    Error: {error.message}

    {/await} ``` ## Rerunning Load Functions Load functions rerun when: - Referenced params or URL properties change - A parent load function reran and this function calls `await parent()` - A dependency was invalidated Manually invalidate load functions: ```js // In load function export function load({ fetch, depends }) { depends('app:random'); // custom identifier const response = await fetch('https://api.example.com/random-number'); return { number: await response.json() }; } // In component import { invalidate } from '$app/navigation'; function rerunLoadFunction() { invalidate('app:random'); } ``` ## Authentication Best practices: - Use hooks for protecting multiple routes - Use auth guards in `+page.server.js` for route-specific protection - Use `getRequestEvent()` for shared auth logic ```js // src/lib/server/auth.js import { redirect } from '@sveltejs/kit'; import { getRequestEvent } from '$app/server'; export function requireLogin() { const { locals, url } = getRequestEvent(); if (!locals.user) { redirect(307, `/login?${new URLSearchParams({ redirectTo: url.pathname + url.search })}`); } return locals.user; } ``` ## docs/kit/20-core-concepts/30-form-actions.md # Svelte Form Actions ## Default Actions A `+page.server.js` file can export actions for `POST` requests via `
    `. ```js /// file: src/routes/login/+page.server.js /** @satisfies {import('./$types').Actions} */ export const actions = { default: async (event) => { // TODO log the user in } }; ``` ```svelte
    ``` From other pages, specify the action path: ```html /// file: src/routes/+layout.svelte
    ``` ## Named Actions ```js /// file: src/routes/login/+page.server.js /** @satisfies {import('./$types').Actions} */ export const actions = { login: async (event) => { // TODO log the user in }, register: async (event) => { // TODO register the user } }; ``` Invoke with query parameter: ```svelte
    ``` Use `formaction` to target different actions with the same form: ```svelte /// file: src/routes/login/+page.svelte
    ``` ## Action Anatomy Actions receive a `RequestEvent` object and can return data available through the `form` prop: ```js /// file: src/routes/login/+page.server.js 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'); const user = await db.getUser(email); cookies.set('sessionid', await db.createSession(user), { path: '/' }); return { success: true }; } }; ``` ```svelte {#if form?.success}

    Successfully logged in! Welcome back, {data.user.name}

    {/if} ``` ### Validation Errors Return validation errors with the `fail` function: ```js /// file: src/routes/login/+page.server.js import { fail } from '@sveltejs/kit'; /** @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 }); } const user = await db.getUser(email); if (!user || user.password !== db.hash(password)) { return fail(400, { email, incorrect: true }); } // Success logic } }; ``` ```svelte /// file: src/routes/login/+page.svelte
    {#if form?.missing}

    The email field is required

    {/if} {#if form?.incorrect}

    Invalid credentials!

    {/if}
    ``` ### Redirects ```js /// file: src/routes/login/+page.server.js import { fail, redirect } from '@sveltejs/kit'; /** @satisfies {import('./$types').Actions} */ export const actions = { login: async ({ cookies, request, url }) => { // Validation logic if (url.searchParams.has('redirectTo')) { redirect(303, url.searchParams.get('redirectTo')); } return { success: true }; } }; ``` ## Loading Data After an action runs, the page's `load` functions run. Note that `handle` runs before the action but not before the subsequent `load`: ```js /// file: src/routes/account/+page.server.js /** @type {import('./$types').PageServerLoad} */ export function load(event) { return { user: event.locals.user }; } /** @satisfies {import('./$types').Actions} */ export const actions = { logout: async (event) => { event.cookies.delete('sessionid', { path: '/' }); event.locals.user = null; } }; ``` ## Progressive Enhancement ### use:enhance The simplest way to enhance forms: ```svelte /// file: src/routes/login/+page.svelte
    ``` Without arguments, `use:enhance` will: - Update `form` and `page.form` (only for same-page actions) - Reset the form - Invalidate all data on success - Handle redirects and errors - Reset focus ### Customizing use:enhance ```svelte { // Pre-submission logic return async ({ result, update }) => { // Post-submission logic }; }} > ``` For custom handling: ```svelte { return async ({ result }) => { if (result.type === 'redirect') { goto(result.location); } else { await applyAction(result); } }; }} > ``` ### Custom Event Listener ```svelte
    ``` To target a page action instead of a server endpoint: ```js const response = await fetch(this.action, { method: 'POST', body: data, headers: { 'x-sveltekit-action': 'true' } }); ``` ## GET Forms For forms that don't need to POST data: ```html
    ``` This navigates to `/search?q=...` using client-side routing without invoking an action. ## docs/kit/20-core-concepts/40-page-options.md # Svelte 5 Page Options ## Core Concepts ### Rendering Modes SvelteKit supports three rendering strategies: - **Server-Side Rendering (SSR)**: Default, renders on server first - **Client-Side Rendering (CSR)**: Hydrates server-rendered HTML - **Prerendering**: Generates static HTML at build time Options can be set in `+page.js`, `+page.server.js`, `+layout.js`, or `+layout.server.js`. Child pages override parent layouts. ## Page Options ### prerender ```js // Static generation at build time export const prerender = true; // Force prerender export const prerender = false; // Prevent prerendering export const prerender = 'auto'; // Prerender but keep in SSR manifest ``` **Notes:** - Prerendering crawls your app starting from the root - Pages must render the same content for all users - Cannot use `url.searchParams` during prerendering - Pages with form actions cannot be prerendered - During prerendering, `building` from `$app/environment` is `true` #### Entries for Dynamic Routes ```js /// file: src/routes/blog/[slug]/+page.server.js /** @type {import('./$types').EntryGenerator} */ export function entries() { return [ { slug: 'hello-world' }, { slug: 'another-blog-post' } ]; } export const prerender = true; ``` #### Route Conflicts - Use file extensions for server routes (e.g., `foo.json/+server.js`) - Pages are written as `foo/index.html` instead of `foo` ### ssr ```js export const ssr = false; // Disable server-side rendering ``` Renders an empty shell page on the server. Useful for browser-only code but generally not recommended. ### csr ```js export const csr = false; // Disable client-side rendering ``` When disabled: - No JavaScript is sent to the client - ` ``` ```svelte

    Welcome {user().name}

    ``` > Pass functions to `setContext` to maintain reactivity across boundaries. ## Component State Preservation SvelteKit reuses components during navigation. Make values reactive: ```svelte ``` Correct approach: ```svelte ``` To force component remounting on navigation: ```svelte {#key page.url.pathname} {/key} ``` ## State Storage Options - **URL Parameters**: For state that should survive reloads (filters, sorting) - Access via `url` in load functions or `page.url.searchParams` in components - **Snapshots**: For ephemeral UI state (accordion open/closed) - Persists during navigation but not page refresh ## docs/kit/25-build-and-deploy/10-building-your-app.md # SvelteKit App Building Guide ## Building Your App SvelteKit builds in two stages when running `vite build`: 1. Vite creates optimized production builds of server code, browser code, and service worker 2. An adapter tunes the build for your target environment ### During the Build Skip code execution during build phase: ```js import { building } from '$app/environment'; import { setupMyDatabase } from '$lib/server/database'; if (!building) { setupMyDatabase(); } export function load() { // ... } ``` ### Preview Your App Preview production build locally with `vite preview` (or `npm run preview`). Note: Preview runs in Node and doesn't perfectly reproduce deployment environment (adapter-specific features like `platform` object aren't available). ## docs/kit/25-build-and-deploy/20-adapters.md # Adapters Adapters convert your SvelteKit app for deployment to specific platforms. ## Official Adapters - `@sveltejs/adapter-cloudflare` - Cloudflare Workers/Pages - `@sveltejs/adapter-netlify` - Netlify - `@sveltejs/adapter-node` - Node servers - `@sveltejs/adapter-static` - Static site generation (SSG) - `@sveltejs/adapter-vercel` - Vercel [Community adapters](https://sveltesociety.dev/packages?category=sveltekit-adapters) are available for other platforms. ## Configuration Specify your adapter in `svelte.config.js`: ```js /// file: svelte.config.js import adapter from 'svelte-adapter-foo'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { adapter: adapter({ // adapter options go here }) } }; export default config; ``` ## Platform-specific Context Some adapters provide platform-specific information via the `platform` property in the `RequestEvent` object used in hooks and server routes. Refer to each adapter's documentation for details. ## docs/kit/25-build-and-deploy/55-single-page-apps.md # Single-page apps in SvelteKit ## Basic Setup Convert any SvelteKit app to a SPA by disabling SSR in the root layout: ```js /// file: src/routes/+layout.js export const ssr = false; ``` > **Note**: Not recommended for most cases due to SEO, performance, and accessibility issues. ## Using adapter-static For apps without server-side logic, use `adapter-static` with a fallback page: ```js /// file: svelte.config.js import adapter from '@sveltejs/adapter-static'; export default { kit: { adapter: adapter({ fallback: '200.html' // platform-specific }) } }; ``` The fallback page loads your app and navigates to the correct route. The filename varies by hosting platform. ## Apache Configuration For Apache, add a `static/.htaccess` file: ``` RewriteEngine On RewriteBase / RewriteRule ^200\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /200.html [L] ``` ## Selective Prerendering Enable prerendering for specific pages: ```js /// file: src/routes/my-prerendered-page/+page.js export const prerender = true; export const ssr = true; ``` ## docs/kit/30-advanced/10-advanced-routing.md # Advanced Routing in SvelteKit ## Rest Parameters Use rest syntax for unknown number of route segments: ```bash /[org]/[repo]/tree/[branch]/[...file] ``` For `/sveltejs/kit/tree/main/documentation/docs/04-advanced-routing.md`: ```js { org: 'sveltejs', repo: 'kit', branch: 'main', file: 'documentation/docs/04-advanced-routing.md' } ``` > Note: `src/routes/a/[...rest]/z/+page.svelte` matches `/a/z`, `/a/b/z`, etc. Always validate rest parameters. ### Custom 404 Pages For custom 404s with nested routes, create a catch-all route: ```js /// file: src/routes/marx-brothers/[...path]/+page.js import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export function load(event) { error(404, 'Not Found'); } ``` ## Optional Parameters Make parameters optional with double brackets: `[[lang]]/home` This matches both `/home` and `/en/home`. > Note: Optional parameters can't follow rest parameters. ## Matching Ensure parameters are well-formed with matchers: ```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'; } ``` Use in routes: ``` src/routes/fruits/[page=fruit] ``` ## Sorting When multiple routes match a path, SvelteKit prioritizes: 1. More specific routes (fewer parameters) 2. Routes with matchers 3. Non-optional, non-rest parameters 4. Alphabetical order for ties ## Encoding Use hexadecimal escape sequences for special characters: - `[x+5c]` for `\` - `[x+2f]` for `/` - `[x+3a]` for `:` - etc. Example: `/smileys/:-)` โ†’ `src/routes/smileys/[x+3a]-[x+29]/+page.svelte` Unicode escapes also work: `src/routes/[u+d83e][u+dd2a]/+page.svelte` = `src/routes/๐Ÿคช/+page.svelte` ## Advanced Layouts ### (group) Group routes without affecting URL paths: ```tree src/routes/ โ”‚ (app)/ โ”‚ โ”œ dashboard/ โ”‚ โ”œ item/ โ”‚ โ”” +layout.svelte โ”‚ (marketing)/ โ”‚ โ”œ about/ โ”‚ โ”œ testimonials/ โ”‚ โ”” +layout.svelte โ”œ admin/ โ”” +layout.svelte ``` ### Breaking Out of Layouts Use `@` to specify which layout to inherit: - `+page@[id].svelte` - inherits from segment's layout - `+page@item.svelte` - inherits from parent segment's layout - `+page@(app).svelte` - inherits from group layout - `+page@.svelte` - inherits from root layout Example: ```tree src/routes/ โ”œ (app)/ โ”‚ โ”œ item/ โ”‚ โ”‚ โ”œ [id]/ โ”‚ โ”‚ โ”‚ โ”œ embed/ โ”‚ โ”‚ โ”‚ โ”‚ โ”” +page@(app).svelte โ”‚ โ”‚ โ”‚ โ”” +layout.svelte โ”‚ โ”‚ โ”” +layout.svelte โ”‚ โ”” +layout.svelte โ”” +layout.svelte ``` Layouts can also break out with `+layout@.svelte`. Consider composition as an alternative to complex layout grouping: ```svelte {@render children()} ``` ## docs/kit/30-advanced/20-hooks.md # Svelte 5 and SvelteKit Hooks ## Server Hooks (`src/hooks.server.js`) ### handle Processes requests and determines responses. ```js export async function handle({ event, resolve }) { if (event.url.pathname.startsWith('/custom')) { return new Response('custom response'); } const response = await resolve(event); return response; } ``` `resolve` accepts optional parameters: - `transformPageChunk({ html, done })` - Transforms HTML chunks - `filterSerializedResponseHeaders(name, value)` - Controls which headers are included in serialized responses - `preload({ type, path })` - Determines which files to preload ### handleFetch Modifies fetch requests in server-side `load` or `action` functions. ```js export async function handleFetch({ request, fetch }) { if (request.url.startsWith('https://api.yourapp.com/')) { request = new Request( request.url.replace('https://api.yourapp.com/', 'http://localhost:9999/'), request ); } return fetch(request); } ``` ### locals Add custom data to the request via `event.locals`. ```js export async function handle({ event, resolve }) { event.locals.user = await getUserInformation(event.cookies.get('sessionid')); const response = await resolve(event); response.headers.set('x-custom-header', 'potato'); return response; } ``` ## Shared Hooks (both server and client) ### handleError Handles unexpected errors during loading or rendering. ```js export async function handleError({ error, event, status, message }) { const errorId = crypto.randomUUID(); // Log to service like Sentry Sentry.captureException(error, { extra: { event, errorId, status } }); return { message: 'Whoops!', errorId }; } ``` ### init Runs once when server is created or app starts in browser. ```js export async function init() { await db.connect(); } ``` ## Universal Hooks (`src/hooks.js`) ### reroute Changes how URLs translate to routes. ```js const translated = { '/en/about': '/en/about', '/de/ueber-uns': '/de/about', '/fr/a-propos': '/fr/about', }; export function reroute({ url }) { if (url.pathname in translated) { return translated[url.pathname]; } } ``` Can be async since v2.18: ```js export async function reroute({ url, fetch }) { if (url.pathname === '/api/reroute') return; const api = new URL('/api/reroute', url); api.searchParams.set('pathname', url.pathname); const result = await fetch(api).then(r => r.json()); return result.pathname; } ``` ### transport Passes custom types across server/client boundary. ```js export const transport = { Vector: { encode: (value) => value instanceof Vector && [value.x, value.y], decode: ([x, y]) => new Vector(x, y) } }; ``` ## docs/kit/30-advanced/25-errors.md # Svelte Errors ## Error Objects SvelteKit handles two types of errors: - Expected errors (created with `error` helper) - Unexpected errors (other exceptions) Both are represented as `{ message: string }` objects by default, but can be extended. ## Expected Errors ```js import { error } from '@sveltejs/kit'; import * as db from '$lib/server/database'; export async function load({ params }) { const post = await db.getPost(params.slug); if (!post) { error(404, { message: 'Not found' }); } return { post }; } ``` Access errors in components: ```svelte

    {page.error.message}

    ``` Shorthand for simple errors: ```js error(404, 'Not found'); // Same as error(404, { message: 'Not found' }) ``` ## Unexpected Errors Unexpected errors are any other exceptions. For security, their details aren't exposed to users. Default error shape for users: ```json { "message": "Internal Error" } ``` Customize via the `handleError` hook. ## Error Responses Error handling depends on context: - In `handle` or `+server.js`: Returns fallback error page or JSON - In `load` functions: Renders nearest `+error.svelte` component - In root `+layout.js/+layout.server.js`: Uses fallback error page ### Custom Fallback Error Page Create `src/error.html`: ```html %sveltekit.error.message%

    My custom error page

    Status: %sveltekit.status%

    Message: %sveltekit.error.message%

    ``` ## Type Safety Customize error types in TypeScript: ```ts declare global { namespace App { interface Error { code: string; id: string; } } } export {}; ``` ## docs/kit/30-advanced/30-link-options.md # SvelteKit Link Options ## Preloading Data Control when SvelteKit preloads data for links: ```html
    %sveltekit.body%
    Get current stonk values ``` - `"hover"`: Preload on mouse hover or touchstart - `"tap"`: Preload only on touchstart or mousedown Preloading is skipped when `navigator.connection.saveData` is true. ## Preloading Code Control when SvelteKit preloads code for links: ```html About ``` - `"eager"`: Preload immediately - `"viewport"`: Preload when link enters viewport - `"hover"`: Preload on hover - `"tap"`: Preload on tap/click Note: `viewport` and `eager` only apply to links present in DOM immediately after navigation. ## Other Link Behaviors ### Full-page reload ```html Path ``` Forces a full-page navigation. Links with `rel="external"` behave the same and are ignored during prerendering. ### Replace history state ```html Path ``` Uses `replaceState` instead of `pushState` to avoid creating a new history entry. ### Keep focus ```html
    ``` Maintains focus on the current element after navigation. Avoid using on links. ### Prevent scrolling ```html Path ``` Prevents automatic scrolling to top after navigation. ## Disabling Options Disable options for specific elements: ```html
    a
    d
    ``` Conditional application: ```svelte
    ``` ## docs/kit/30-advanced/40-service-workers.md # Service Workers in SvelteKit Service workers act as proxy servers for network requests, enabling offline support and faster navigation through precaching. ## Basic Setup SvelteKit automatically registers `src/service-worker.js` (or `src/service-worker/index.js`). ```js // Manual registration (if you disable automatic registration) if ('serviceWorker' in navigator) { addEventListener('load', function () { navigator.serviceWorker.register('./path/to/service-worker.js'); }); } ``` ## Inside the Service Worker Access the `$service-worker` module for paths to assets, build files, and prerendered pages. ```js /// import { build, files, version } from '$service-worker'; // Create a unique cache name for this deployment const CACHE = `cache-${version}`; const ASSETS = [ ...build, // the app itself ...files // everything in `static` ]; self.addEventListener('install', (event) => { // Create a new cache and add all files to it async function addFilesToCache() { const cache = await caches.open(CACHE); await cache.addAll(ASSETS); } event.waitUntil(addFilesToCache()); }); self.addEventListener('activate', (event) => { // Remove previous cached data from disk async function deleteOldCaches() { for (const key of await caches.keys()) { if (key !== CACHE) await caches.delete(key); } } event.waitUntil(deleteOldCaches()); }); self.addEventListener('fetch', (event) => { // ignore POST requests etc if (event.request.method !== 'GET') return; async function respond() { const url = new URL(event.request.url); const cache = await caches.open(CACHE); // `build`/`files` can always be served from the cache if (ASSETS.includes(url.pathname)) { const response = await cache.match(url.pathname); if (response) { return response; } } // for everything else, try the network first, but // fall back to the cache if we're offline try { const response = await fetch(event.request); // if we're offline, fetch can return a value that is not a Response // instead of throwing - and we can't pass this non-Response to respondWith if (!(response instanceof Response)) { throw new Error('invalid response from fetch'); } if (response.status === 200) { cache.put(event.request, response.clone()); } return response; } catch (err) { const response = await cache.match(event.request); if (response) { return response; } // if there's no cache, then just error out throw err; } } event.respondWith(respond()); }); ``` > Be careful with caching! Stale data may be worse than unavailable data. ## Development Mode Service workers are bundled for production only. For development, only browsers supporting modules in service workers will work. ```js import { dev } from '$app/environment'; navigator.serviceWorker.register('/service-worker.js', { type: dev ? 'module' : 'classic' }); ``` > `build` and `prerendered` are empty arrays during development ## Type Safety ```js /// /// /// /// const sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (self)); ``` ## Alternatives - [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html) for Workbox integration - [MDN Service Worker 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 # Server-only modules ## Private environment variables [`$env/static/private`]($env-static-private) and [`$env/dynamic/private`]($env-dynamic-private) can only be imported into server-side modules like `hooks.server.js` or `+page.server.js`. ## Server-only utilities [`$app/server`]($app-server) module with its [`read`]($app-server#read) function can only be imported by server code. ## Your modules Make your modules server-only by: - Adding `.server` to filename: `secrets.server.js` - Placing in `$lib/server`: `$lib/server/secrets.js` ## How it works SvelteKit prevents importing server-only code in public-facing components: ```js /// file: $lib/server/secrets.js export const atlantisCoordinates = [/* redacted */]; ``` ```js /// file: src/routes/utils.js export { atlantisCoordinates } from '$lib/server/secrets.js'; export const add = (a, b) => a + b; ``` ```html /// file: src/routes/+page.svelte ``` This produces an error showing the import chain: ``` Cannot import $lib/server/secrets.js into public-facing code: src/routes/+page.svelte src/routes/utils.js $lib/server/secrets.js ``` Works with dynamic imports too, with one caveat: during development, illegal imports may not be detected on first load if there are multiple dynamic imports in the chain. > [!NOTE] Import detection is disabled during testing when `process.env.TEST === 'true'`. ## docs/kit/30-advanced/65-snapshots.md # Snapshots Preserve ephemeral DOM state (form inputs, scroll positions) between navigations. ```svelte