## docs/svelte/01-introduction/01-overview.md # Svelte Overview Svelte is a UI framework that compiles components into optimized JavaScript. Use it for anything from standalone components to full stack apps with SvelteKit. ```svelte ``` For beginners, start with the [interactive tutorial](/tutorial). Try Svelte online in the [playground](/playground) or on [StackBlitz](https://sveltekit.new). ## docs/svelte/01-introduction/02-getting-started.md # Getting Started with Svelte 5 ## Quick Start ```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` ## Help Resources - [Discord](/chat) - [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte) ## docs/svelte/01-introduction/03-svelte-files.md # Svelte Components (.svelte files) Components are written in `.svelte` files with three optional sections: ```svelte ``` ## ` ``` You can `export` bindings from this block (except `export default`). ## ` ``` ## 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 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 reactive syntax from previous versions. ## 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 class Todo { // ... 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 let a = $state(1); let b = $state(2); // Accessing current values ``` For reactive objects: ```js function add(input) { return { get value() { return input.a + input.b; } }; } let input = $state({ a: 1, b: 2 }); let total = add(input); ``` ## Cross-module state Can't export directly reassigned state: ```js // Not allowed export let count = $state(0); export function increment() { count += 1; } ``` Instead, export objects: ```js // Allowed - updating property, not reassigning export const counter = $state({ count: 0 }); export function increment() { counter.count += 1; } ``` Or use 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 in Svelte 5 The `$derived` rune creates reactive values that automatically update when their dependencies change. ## Basic Usage ```svelte

{count} doubled is {doubled}

``` > Without `$derived`, `doubled` would not update when `count` changes. ## Complex Derivations with $derived.by For multi-line derivations, use `$derived.by`: ```svelte ``` `$derived(expression)` is equivalent to `$derived.by(() => expression)`. ## 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 converted to deeply reactive proxies. When accessing properties of a derived object that references a reactive state, mutations affect the underlying state. ## Update Propagation Svelte uses push-pull reactivity: - Changes are immediately pushed to dependents - Derived values are only recalculated when read - Updates are skipped if the new value is referentially identical to the previous value ```svelte ``` The button text only updates when `large` changes value, not on every `count` change. ## 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 operations (after `await` or in `setTimeout`) won't track dependencies - Only reruns when the object it reads changes, not when properties change - Dependencies are based on what was read in the previous run ```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 ``` Or with JSDoc: ```svelte ``` With separate type declaration: ```svelte ``` ## $props.id() Generates a unique ID for the component instance: ```svelte
``` ## docs/svelte/02-runes/06-$bindable.md # Svelte 5 Condensed: $bindable ## Basic Usage `$bindable` enables two-way data flow between parent and child components. ```svelte /// file: FancyInput.svelte ``` Parent component can bind to the prop: ```svelte /// file: App.svelte

{message}

``` ## Default Values Provide fallback values when no prop is passed: ```js /// file: FancyInput.svelte let { value = $bindable('fallback'), ...props } = $props(); ``` ## Key Points - Props normally flow one-way (parent to child) - `$bindable` allows data to flow up from child to parent - Parent components can choose whether to use `bind:` or not - Use sparingly to maintain clear data flow in your app - State proxies can be mutated in child components ## 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
page {p}
This div has no title attribute
``` ## Component Props ```svelte ``` ## Events ```svelte ``` - Event attributes are case sensitive (`onclick` โ‰  `onClick`) - Can use shorthand: `` - Can spread events: `` - `ontouchstart` and `ontouchmove` are passive by default ### Event Delegation Svelte uses event delegation for performance. Important notes: - When manually dispatching events, use `{ bubbles: true }` - Avoid `stopPropagation` with `addEventListener` - Use `on` from `svelte/events` instead of `addEventListener` Delegated events: `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

Hello {name}!

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

{(/^[A-Za-z ]+$/).test(value) ? x : y}
{@html potentiallyUnsafeHtmlString} ``` - `null` or `undefined` expressions are omitted - All others are coerced to strings - Escape curly braces with HTML entities: `{`, `{`, `{`, `}`, `}`, `}` ## Comments ```svelte

Hello world

Hello, {name}

``` - Use `` to disable warnings - Use `` 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} ``` Note: 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 ```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 a value changes - Triggering transitions on value changes: ```svelte {#key value}
    {value}
    {/key} ``` ## docs/svelte/03-template-syntax/05-await.md # {#await ...} ```svelte {#await expression}...{:then name}...{:catch name}...{/await} {#await expression}...{:then name}...{/await} {#await expression then name}...{/await} {#await expression catch name}...{/await} ``` Await blocks handle the three states of a Promise: ```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:** ```svelte {#await promise}

    waiting for the promise to resolve...

    {:then value}

    The value is {value}

    {/await} ``` ```svelte {#await promise then value}

    The value is {value}

    {/await} ``` ```svelte {#await promise catch error}

    The error is {error}

    {/await} ``` > Use with dynamic imports for lazy 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 destructuring (no rest parameters). ## Scope Snippets can access outer scope values: ```svelte {#snippet hello(name)}

    hello {name}! {message}!

    {/snippet} {@render hello('alice')} {@render hello('bob')} ``` Snippets are visible to siblings and their children. They can reference themselves and other snippets: ```svelte {#snippet countdown(n)} {#if n > 0} {n}... {@render countdown(n - 1)} {:else} {@render blastoff()} {/if} {/snippet} {#snippet blastoff()} ๐Ÿš€ {/snippet} {@render countdown(10)} ``` ## Passing Snippets to Components ### Explicit Props ```svelte {#snippet header()} fruit qty price total {/snippet} {#snippet row(d)} {d.name} {d.qty} {d.price} {d.qty * d.price} {/snippet} ``` ### Implicit Props Snippets declared inside a component become props on the component: ```svelte
    {#snippet header()} {/snippet} {#snippet row(d)} {/snippet}
    fruit qty price total{d.name} {d.qty} {d.price} {d.qty * d.price}
    ``` ### Implicit `children` Snippet Non-snippet content becomes the `children` snippet: ```svelte ``` ```svelte ``` > Don't create a prop named `children` if you also have content inside the component ### Optional Snippet Props Handle optional snippets with optional chaining: ```svelte {@render children?.()} ``` Or with fallback content: ```svelte {#if children} {@render children()} {:else} fallback content {/if} ``` ## Typing Snippets ```svelte ``` ## Exporting Snippets Top-level snippets can be exported from ` {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` > Requires Svelte 5.5.0+ ## Advanced Usage - Programmatic snippets can be created with `createRawSnippet` API - Snippets replace slots in Svelte 5 (slots are deprecated) ## 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 into your component: ```svelte
    {@html content}
    ``` > [!NOTE] Always sanitize HTML content to prevent XSS attacks. ## Limitations - Expression must be valid standalone HTML - Will not compile Svelte code - Cannot split HTML tags across multiple `{@html}` tags ## Styling Content rendered with `{@html ...}` is invisible to Svelte's style scoping: ```svelte ``` ## 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, triggers 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 ``` ### 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 in Svelte 5 Actions are functions called when an element is mounted, added with the `use:` directive. ## Basic Usage ```svelte
    ...
    ``` ## With Parameters ```svelte
    ...
    ``` > Note: Actions run once when mounted (not during SSR). They don't re-run if parameters change. ## Typing ```svelte
    ...
    ``` The `Action` interface accepts three optional type arguments: 1. Node type (can be `Element` for all elements) 2. Parameter type 3. 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 ```svelte {#if visible}
    fades in and out over two seconds
    {/if} ``` ## Custom Transitions ```js 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 } ``` CSS-based custom transition (preferred for performance): ```svelte {#if visible}
    whooshes in
    {/if} ``` JavaScript-based custom transition (use `css` when possible): ```svelte {#if visible}

    The quick brown fox jumps over the lazy dog

    {/if} ``` ## Transition Events Elements with transitions 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 one-way transitions that don't reverse when interrupted. ```svelte {#if visible}
    flies in, fades out
    {/if} ``` Key differences from `transition:`: - Transitions are not bidirectional - An `in` transition continues playing alongside the `out` transition - If an `out` transition is aborted, transitions restart from scratch ## 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 - `parameters`: Any custom parameters Return an object with either: - `css` method (preferred, runs off main thread) - `tick` function (runs during animation) ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` Using `tick` instead of `css`: ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` > Prefer `css` over `tick` for better performance on slower devices. ## 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` attributes, 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+) **Objects** - truthy keys are added: ```svelte
    ...
    ``` **Arrays** - truthy values are combined: ```svelte
    ...
    ``` **Combining with props**: ```svelte ``` Usage: ```svelte ``` ### TypeScript Support ```svelte
    ...
    ``` ## Class Directive (Legacy) ```svelte
    ...
    ``` Shorthand when name matches value: ```svelte
    ...
    ``` > Note: Prefer using the class attribute with objects/arrays 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 desugars to: ```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 errors in components to prevent app-wide crashes and enable recovery. - Catches errors during rendering, updating, and `$effect` execution - Does NOT catch errors in event handlers, timeouts, 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)}> ... ``` Managing error state 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 ``` **Read/Write Properties:** - `scrollX` - `scrollY` **Readonly Properties:** - `innerWidth` - `innerHeight` - `outerWidth` - `outerHeight` - `online` (alias for `window.navigator.onLine`) - `devicePixelRatio` > **Note:** Page won't scroll to initial bound values of `scrollX`/`scrollY`. 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 to `document.body` for events that don't fire on `window` (like `mouseenter`/`mouseleave`). Also supports [actions](use). **Rules:** - Must appear only at top level of component - Cannot be inside blocks or elements **Example:** ```svelte ``` ## 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 only 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 an element that's unknown at author time (e.g., from a CMS). ## Usage ```svelte Content inside the dynamic element ``` ## Key Points - Only `bind:this` binding is supported - If `this` is nullish, nothing renders - If `this` is a void element (e.g., `br`) with children, a runtime error occurs in dev mode ```svelte This text cannot appear inside an hr element ``` - Specify namespace explicitly when needed: ```svelte ``` - `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 the `$` prefix. ```svelte ``` ## When to Use Stores In Svelte 5, runes are preferred for most use cases: ```ts /// file: state.svelte.js export const userState = $state({ name: 'name', /* ... */ }); ``` ```svelte

    User name: {userState.name}

    ``` Use stores for complex async data streams or when manual control over updates is needed. ## svelte/store API ### `writable` Creates a store with values that can be set externally. ```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' ``` With start/stop functions: ```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 whose value cannot be set externally. ```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 one or more other stores. ```ts import { derived } from 'svelte/store'; const doubled = derived(a, ($a) => $a * 2); ``` Asynchronous derivation: ```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); }); ``` With 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 the current value of a store without subscribing. ```ts import { get } from 'svelte/store'; const value = get(store); ``` ## Store Contract A valid store must: 1. Have a `.subscribe` method that accepts a subscription function 2. Call the subscription function immediately with the current value 3. Return an unsubscribe function 4. 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 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 ## Component Lifecycle In Svelte 5, components have only two lifecycle phases: - Creation (mounting) - Destruction (unmounting) State updates trigger only the specific effects that depend on that state. ## `onMount` Runs after component is mounted to DOM. Not executed during SSR. ```svelte ``` > [!NOTE] Cleanup only works when function synchronously returns a value (not with async functions). ## `onDestroy` Runs before component unmounts. Only lifecycle hook that runs during SSR. ```svelte ``` ## `tick` Returns promise that resolves after pending state changes are applied. ```svelte ``` ## Deprecated: `beforeUpdate` / `afterUpdate` Shimmed for backward compatibility but not available in components using runes. - Use `$effect.pre` instead of `beforeUpdate` - Use `$effect` instead of `afterUpdate` ### Chat Window Example ```svelte
    {#each messages as message}

    {message}

    {/each}
    ``` ## docs/svelte/06-runtime/04-imperative-component-api.md # Imperative Component API ## `mount` Creates and mounts a component to a target 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` callbacks and action functions) 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 otherwise. ## `render` Server-side only. Returns HTML for server rendering: ```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` Reuses SSR-rendered HTML and makes it 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; ``` ### Writing Tests ```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 without preprocessors. Unsupported features: - enums - access modifiers with initializers - non-ECMAScript standard features ## 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` - `verbatimModuleSyntax`: `true` - `isolatedModules`: `true` ## Typing Components ### $props ```svelte ``` ### Generic Components ```svelte ``` ### Wrapper Components ```svelte ``` For elements without dedicated types: ```svelte ``` ## Typing Runes ### $state ```ts let count: number = $state(0); ``` For undefined initial values: ```ts class Counter { count = $state() as number; constructor(initial: number) { this.count = initial; } } ``` ## Component Types ### Component Type ```svelte ``` ### ComponentProps ```ts import type { Component, ComponentProps } from 'svelte'; import MyComponent from './MyComponent.svelte'; function withProps>( component: TComponent, props: ComponentProps ) {} withProps(MyComponent, { foo: 'bar' }); ``` ### Component Instance ```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; } } ``` Or by augmenting modules: ```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 {}; ``` Instructions for LLMs: 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.