## 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
{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{state.value} doubled is {derived.value}
``` ## Variants ### `$effect.pre` Runs before DOM updates: ```svelte{message}
{/each}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 ```sveltethis 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{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.sveltecount: {count}
``` ## docs/svelte/03-template-syntax/01-basic-markup.md # Basic Markup in Svelte 5 ## Tags ```svelte{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{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}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 }} >hello {name}! {message}!
{/snippet} {@render hello('alice')} {@render hello('bob')} ``` Snippets are visible to siblings and their children: ```sveltefruit | qty | price | total | {/snippet} {#snippet row(d)}{d.name} | {d.qty} | {d.price} | {d.qty * d.price} | {/snippet}
---|
{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: ```sveltefades 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}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}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}
{/each}{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 ` ``` 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 ``` ## 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 ``` ### 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 ``` 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 - ` ``` ```svelteWelcome {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}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