{"blocks":[{"breadcrumbs":["Docs","AI","Introduction","Overview"],"href":"/docs/ai/overview","content":"The following pages will help you set up and use the AI tools officially maintained by the Svelte team.There are four tools, designed to help your agent write correct, robust Svelte code. They are designed to work together, but each can be used individually:[Instructions](instructions): small prompt always injected into your session to make your agent more aware of the available tools\n[MCP Server](mcp): with tools, prompts and resources to give your agent more context, by pulling directly from the official Svelte documentation and using static analysis to correct common generative AI pitfalls\n[Skills](skills): lazy-loaded descriptions that teach your agent Svelte best practices, and how to use the [`@sveltejs/mcp` cli](cli)\n[Subagents](subagent): focused agents that can be invoked in parallel to execute atomic operations in a separate context window","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md"],"href":"/docs/ai/instructions","content":"To get the most out of the MCP server and skills we recommend including the following prompt in your `AGENTS.md` (or `CLAUDE.md` or `GEMINI.md`, if using Claude Code or Gemini). This will tell your agent which tools are available and when it is appropriate to use them.[!NOTE] This is already setup for you when using `npx sv add mcp`\nYou are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively:","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md","Available Svelte MCP Tools:"],"href":"/docs/ai/instructions#Available-Svelte-MCP-Tools:","content":"","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md","Available Svelte MCP Tools:","1. list-sections"],"href":"/docs/ai/instructions#Available-Svelte-MCP-Tools:-1.-list-sections","content":"Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths.\nWhen asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections.","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md","Available Svelte MCP Tools:","2. get-documentation"],"href":"/docs/ai/instructions#Available-Svelte-MCP-Tools:-2.-get-documentation","content":"Retrieves full documentation content for specific sections. Accepts single or multiple sections.\nAfter calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task.","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md","Available Svelte MCP Tools:","3. svelte-autofixer"],"href":"/docs/ai/instructions#Available-Svelte-MCP-Tools:-3.-svelte-autofixer","content":"Analyzes Svelte code and returns issues and suggestions.\nYou MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned.","rank":null},{"breadcrumbs":["Docs","AI","Instructions","AGENTS.md","Available Svelte MCP Tools:","4. playground-link"],"href":"/docs/ai/instructions#Available-Svelte-MCP-Tools:-4.-playground-link","content":"Generates a Svelte Playground link with the provided code.\nAfter completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.<!-- prettier-ignore-end -->","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Overview"],"href":"/docs/ai/mcp","content":"The Svelte MCP (Model Context Protocol) server can help your agent write better Svelte code. It works by providing relevant documentation, and statically analysing generated code so that it can suggest fixes and best practices.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Overview","Setup"],"href":"/docs/ai/mcp#Setup","content":"The setup varies based on the version of the MCP you prefer — remote or local — and your chosen MCP client (e.g. Claude Code, Codex CLI or GitHub Copilot):[local setup](local-setup) using `@sveltejs/mcp`\n[remote setup](remote-setup) using `https://mcp.svelte.dev/mcp`","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Overview","Usage"],"href":"/docs/ai/mcp#Usage","content":"If your MCP client supports it, we also recommend using the svelte-task prompt to instruct the LLM on the best way to use the MCP server.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup"],"href":"/docs/ai/local-setup","content":"The local (or stdio) version of the MCP server is available via the `@sveltejs/mcp` npm package. You can either install it globally and then reference it in your configuration or run it with npx:npx -y @sveltejs/mcpHere's how to set it up in some common MCP clients:","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Claude Code"],"href":"/docs/ai/local-setup#Claude-Code","content":"To include the local MCP version in Claude Code, simply run the following command:claude mcp add -t stdio -s [scope] svelte -- npx -y @sveltejs/mcpThe [scope] must be user, project or local.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Claude Desktop"],"href":"/docs/ai/local-setup#Claude-Desktop","content":"In the Settings > Developer section, click on Edit Config. It will open the folder with a claude_desktop_config.json file in it. Edit the file to include the following configuration:{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"command\": \"npx\",\n\t\t\t\"args\": [\"-y\", \"@sveltejs/mcp\"]\n\t\t}\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Codex CLI"],"href":"/docs/ai/local-setup#Codex-CLI","content":"Add the following to your config.toml (which defaults to ~/.codex/config.toml, but refer to the configuration documentation for more advanced setups):[mcp_servers.svelte]\ncommand = \"npx\"\nargs = [\"-y\", \"@sveltejs/mcp\"]","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Copilot CLI"],"href":"/docs/ai/local-setup#Copilot-CLI","content":"Use the Copilot CLI to interactively add the MCP server:/mcp addAlternatively, create or edit ~/.copilot/mcp-config.json and add the following configuration:{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"command\": \"npx\",\n\t\t\t\"args\": [\"-y\", \"@sveltejs/mcp\"]\n\t\t}\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Gemini CLI"],"href":"/docs/ai/local-setup#Gemini-CLI","content":"To include the local MCP version in Gemini CLI, simply run the following command:gemini mcp add -t stdio -s [scope] svelte npx -y @sveltejs/mcpThe [scope] must be user, project or local.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","OpenCode"],"href":"/docs/ai/local-setup#OpenCode","content":"You can automatically configure the MCP server using the OpenCode plugin (recommended). If you prefer to configure the MCP server manually, run:opencode mcp addand follow the instructions, selecting 'Local' under the 'Select MCP server type' prompt:opencode mcp add\n\n┌  Add MCP server\n│\n◇  Enter MCP server name\n│  svelte\n│\n◇  Select MCP server type\n│  Local\n│\n◆  Enter command to run\n│  npx -y @sveltejs/mcp","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","VS Code"],"href":"/docs/ai/local-setup#VS-Code","content":"Open the command palette\nSelect \"MCP: Add Server...\"\nSelect \"Command (stdio)\"\nInsert `npx -y @sveltejs/mcp` in the input and press `Enter`\nWhen prompted for a name, insert `svelte`\nSelect if you want to add it as a `Global` or `Workspace` MCP server","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Cursor"],"href":"/docs/ai/local-setup#Cursor","content":"You can automatically configure the MCP server using the Cursor plugin (recommended). If you prefer to configure the MCP server manually you can:Open the command palette\nSelect \"View: Open MCP Settings\"\nClick on \"Add custom MCP\"It will open a file with your MCP servers where you can add the following configuration:{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"command\": \"npx\",\n\t\t\t\"args\": [\"-y\", \"@sveltejs/mcp\"]\n\t\t}\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Zed"],"href":"/docs/ai/local-setup#Zed","content":"Install the Svelte MCP Server extension.\n\nOpen the command palette\nSearch and select \"agent:open settings\"\nIn settings panel look for `Model Context Protocol (MCP) Servers`\nClick on \"Add Server\"\nSelect: \"Add Custom Server\"It will open a popup with MCP server config where you can add the following configuration:{\n\t\"svelte\": {\n\t\t\"command\": \"npx\",\n\t\t\"args\": [\"-y\", \"@sveltejs/mcp\"]\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Local setup","Other clients"],"href":"/docs/ai/local-setup#Other-clients","content":"If we didn't include the MCP client you are using, refer to their documentation for stdio servers and use npx as the command and -y @sveltejs/mcp as the arguments.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup"],"href":"/docs/ai/remote-setup","content":"The remote version of the MCP server is available at https://mcp.svelte.dev/mcp.Here's how to set it up in some common MCP clients:","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Claude Code"],"href":"/docs/ai/remote-setup#Claude-Code","content":"To include the remote MCP version in Claude Code, simply run the following command:claude mcp add -t http -s [scope] svelte https://mcp.svelte.dev/mcpYou can choose your preferred scope (it must be user, project or local) and name.If you prefer you can also install the svelte plugin in the Svelte Claude Code Marketplace that will give you both the remote server and useful skills.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Claude Desktop"],"href":"/docs/ai/remote-setup#Claude-Desktop","content":"Open Settings > Connectors\nClick on Add Custom Connector\nWhen prompted for a name, enter `svelte`\nUnder the Remote MCP server URL input, use `https://mcp.svelte.dev/mcp`\nClick Add","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Codex CLI"],"href":"/docs/ai/remote-setup#Codex-CLI","content":"Add the following to your config.toml (which defaults to ~/.codex/config.toml, but refer to the configuration documentation for more advanced setups):experimental_use_rmcp_client = true\n[mcp_servers.svelte]\nurl = \"https://mcp.svelte.dev/mcp\"","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Copilot CLI"],"href":"/docs/ai/remote-setup#Copilot-CLI","content":"Use the Copilot CLI to interactively add the MCP server:/mcp addAlternatively, create or edit ~/.copilot/mcp-config.json and add the following configuration:{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"url\": \"https://mcp.svelte.dev/mcp\"\n\t\t}\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Gemini CLI"],"href":"/docs/ai/remote-setup#Gemini-CLI","content":"To use the remote MCP server with Gemini CLI, simply run the following command:gemini mcp add -t http -s [scope] svelte https://mcp.svelte.dev/mcpThe [scope] must be user or project.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","OpenCode"],"href":"/docs/ai/remote-setup#OpenCode","content":"You can automatically configure the MCP server using the OpenCode plugin (recommended). If you prefer to configure the MCP server manually, run:opencode mcp addand follow the instructions, selecting 'Remote' under the 'Select MCP server type' prompt:opencode mcp add\n\n┌  Add MCP server\n│\n◇  Enter MCP server name\n│  svelte\n│\n◇  Select MCP server type\n│  Remote\n│\n◇  Enter MCP server URL\n│  https://mcp.svelte.dev/mcp","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","VS Code"],"href":"/docs/ai/remote-setup#VS-Code","content":"Open the command palette\nSelect \"MCP: Add Server...\"\nSelect \"HTTP (HTTP or Server-Sent-Events)\"\nInsert `https://mcp.svelte.dev/mcp` in the input and press `Enter`\nInsert your preferred name\nSelect if you want to add it as a `Global` or `Workspace` MCP server","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Cursor"],"href":"/docs/ai/remote-setup#Cursor","content":"You can automatically configure the MCP server using the Cursor plugin (recommended). If you prefer to configure the MCP server manually you can:Open the command palette\nSelect \"View: Open MCP Settings\"\nClick on \"Add custom MCP\"It will open a file with your MCP servers where you can add the following configuration:{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"url\": \"https://mcp.svelte.dev/mcp\"\n\t\t}\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","GitHub Coding Agent"],"href":"/docs/ai/remote-setup#GitHub-Coding-Agent","content":"Open your repository in GitHub\nGo to Settings\nOpen Copilot > Coding agent\nEdit the MCP configuration{\n\t\"mcpServers\": {\n\t\t\"svelte\": {\n\t\t\t\"type\": \"http\",\n\t\t\t\"url\": \"https://mcp.svelte.dev/mcp\",\n\t\t\t\"tools\": [\"*\"]\n\t\t}\n\t}\n}Click _Save MCP configuration_","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Remote setup","Other clients"],"href":"/docs/ai/remote-setup#Other-clients","content":"If we didn't include the MCP client you are using, refer to their documentation for remote servers and use https://mcp.svelte.dev/mcp as the URL.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Tools"],"href":"/docs/ai/tools","content":"The following tools are provided by the MCP server to the model you are using, which can decide to call one or more of them during a session:","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Tools","list-sections"],"href":"/docs/ai/tools#list-sections","content":"Provides a list of all the available documentation sections.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Tools","get-documentation"],"href":"/docs/ai/tools#get-documentation","content":"Allows the model to get the full (and up-to-date) documentation for the requested sections directly from svelte.dev/docs.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Tools","svelte-autofixer"],"href":"/docs/ai/tools#svelte-autofixer","content":"Uses static analysis to provide suggestions for code that your LLM generates. It can be invoked in an agentic loop by your model until all issues and suggestions are resolved.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Tools","playground-link"],"href":"/docs/ai/tools#playground-link","content":"Generates an ephemeral playground link with the generated code. It's useful when the generated code is not written to a file in your project and you want to quickly test the generated solution. The code is not stored anywhere except the URL itself (which will often, as a consequence, be quite large).","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Resources"],"href":"/docs/ai/resources","content":"This is the list of available resources provided by the MCP server. Resources are included by the user (not by the LLM) and are useful if you want to include specific knowledge in your session. For example, if you know that the component will need to use transitions you can include the transition documentation directly without asking the LLM to do it for you.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Resources","doc-section"],"href":"/docs/ai/resources#doc-section","content":"This dynamic resource allows you to add every section of the Svelte documentation as a resource. The URI looks like this svelte://slug-of-the-docs.md and the returned resource will contain the llms.txt version of the specific page you selected.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Prompts"],"href":"/docs/ai/prompts","content":"This is the list of available prompts provided by the MCP server. Prompts are selected by the user and are sent as a user message. They can be useful to write repetitive instructions for the LLM on how to properly use the MCP server.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","Prompts","svelte-task"],"href":"/docs/ai/prompts#svelte-task","content":"This prompt should be used whenever you are asking the model to work on a Svelte-related task. It will instruct the LLM which documentation sections are available, which tools to invoke, when to invoke them, and how to interpret the results.\n\nYou are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool `get-documentation` with one of the following paths. However: before invoking the `get-documentation` tool, try to answer the users query using your own knowledge and the `svelte-autofixer` tool. Be mindful of how many section you request, since it is token-intensive!\n<available-docs>\n\n- title: Overview, use_cases: use title and path to estimate use case, path: ai/overview\n- title: Local setup, use_cases: use title and path to estimate use case, path: ai/local-setup\n- title: Remote setup, use_cases: use title and path to estimate use case, path: ai/remote-setup\n- title: Tools, use_cases: use title and path to estimate use case, path: ai/tools\n- title: Resources, use_cases: use title and path to estimate use case, path: ai/resources\n- title: Prompts, use_cases: use title and path to estimate use case, path: ai/prompts\n- title: Overview, use_cases: use title and path to estimate use case, path: ai/plugin\n- title: Subagent, use_cases: use title and path to estimate use case, path: ai/subagent\n- title: Overview, use_cases: use title and path to estimate use case, path: ai/opencode-plugin\n- title: Subagent, use_cases: use title and path to estimate use case, path: ai/opencode-subagent\n- title: Overview, use_cases: use title and path to estimate use case, path: ai/skills\n- title: Overview, use_cases: project setup, creating new svelte apps, scaffolding, cli tools, initializing projects, path: cli/overview\n- title: Frequently asked questions, use_cases: project setup, initializing new svelte projects, troubleshooting cli installation, package manager configuration, path: cli/faq\n- title: sv create, use_cases: project setup, starting new sveltekit app, initializing project, creating from playground, choosing project template, path: cli/sv-create\n- title: sv add, use_cases: project setup, adding features to existing projects, integrating tools, testing setup, styling setup, authentication, database setup, deployment adapters, path: cli/sv-add\n- title: sv check, use_cases: code quality, ci/cd pipelines, error checking, typescript projects, pre-commit hooks, finding unused css, accessibility auditing, production builds, path: cli/sv-check\n- title: sv migrate, use_cases: migration, upgrading svelte versions, upgrading sveltekit versions, modernizing codebase, svelte 3 to 4, svelte 4 to 5, sveltekit 1 to 2, adopting runes, refactoring deprecated apis, path: cli/sv-migrate\n- title: devtools-json, use_cases: development setup, chrome devtools integration, browser-based editing, local development workflow, debugging setup, path: cli/devtools-json\n- title: drizzle, use_cases: database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries, path: cli/drizzle\n- title: eslint, use_cases: code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects, path: cli/eslint\n- title: better-auth, use_cases: use title and path to estimate use case, path: cli/better-auth\n- title: mcp, use_cases: use title and path to estimate use case, path: cli/mcp\n- title: mdsvex, use_cases: blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages, path: cli/mdsvex\n- title: paraglide, use_cases: internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content, path: cli/paraglide\n- title: playwright, use_cases: browser testing, e2e testing, integration testing, test automation, quality assurance, ci/cd pipelines, testing user flows, path: cli/playwright\n- title: prettier, use_cases: code formatting, project setup, code style consistency, team collaboration, linting configuration, path: cli/prettier\n- title: storybook, use_cases: component development, design systems, ui library, isolated component testing, documentation, visual testing, component showcase, path: cli/storybook\n- title: sveltekit-adapter, use_cases: deployment, production builds, hosting setup, choosing deployment platform, configuring adapters, static site generation, node server, vercel, cloudflare, netlify, path: cli/sveltekit-adapter\n- title: tailwindcss, use_cases: project setup, styling, css framework, rapid prototyping, utility-first css, design systems, responsive design, adding tailwind to svelte, path: cli/tailwind\n- title: vitest, use_cases: testing, unit tests, component testing, test setup, quality assurance, ci/cd pipelines, test-driven development, path: cli/vitest\n- title: add-on, use_cases: use title and path to estimate use case, path: cli/add-on\n- title: sv-utils, use_cases: use title and path to estimate use case, path: cli/sv-utils\n- title: Introduction, use_cases: learning sveltekit, project setup, understanding framework basics, choosing between svelte and sveltekit, getting started with full-stack apps, path: kit/introduction\n- title: Creating a project, use_cases: project setup, starting new sveltekit app, initial development environment, first-time sveltekit users, scaffolding projects, path: kit/creating-a-project\n- title: Project types, use_cases: deployment, project setup, choosing adapters, ssg, spa, ssr, serverless, mobile apps, desktop apps, pwa, offline apps, browser extensions, separate backend, docker containers, path: kit/project-types\n- title: Project structure, use_cases: project setup, understanding file structure, organizing code, starting new project, learning sveltekit basics, path: kit/project-structure\n- title: Web standards, use_cases: always, any sveltekit project, data fetching, forms, api routes, server-side rendering, deployment to various platforms, path: kit/web-standards\n- title: Routing, use_cases: routing, navigation, multi-page apps, project setup, file structure, api endpoints, data loading, layouts, error pages, always, path: kit/routing\n- title: Loading data, use_cases: data fetching, api calls, database queries, dynamic routes, page initialization, loading states, authentication checks, ssr data, form data, content rendering, path: kit/load\n- title: Form actions, use_cases: forms, user input, data submission, authentication, login systems, user registration, progressive enhancement, validation errors, path: kit/form-actions\n- title: Page options, use_cases: prerendering static sites, ssr configuration, spa setup, client-side rendering control, url trailing slash handling, adapter deployment config, build optimization, path: kit/page-options\n- title: State management, use_cases: sveltekit, server-side rendering, ssr, state management, authentication, data persistence, load functions, context api, navigation, component lifecycle, path: kit/state-management\n- title: Remote functions, use_cases: data fetching, server-side logic, database queries, type-safe client-server communication, forms, user input, mutations, authentication, crud operations, optimistic updates, path: kit/remote-functions\n- title: Building your app, use_cases: production builds, deployment preparation, build process optimization, adapter configuration, preview before deployment, path: kit/building-your-app\n- title: Adapters, use_cases: deployment, production builds, hosting setup, choosing deployment platform, configuring adapters, path: kit/adapters\n- title: Zero-config deployments, use_cases: deployment, production builds, hosting setup, choosing deployment platform, ci/cd configuration, path: kit/adapter-auto\n- title: Node servers, use_cases: deployment, production builds, node.js hosting, custom server setup, environment configuration, reverse proxy setup, docker deployment, systemd services, path: kit/adapter-node\n- title: Static site generation, use_cases: static site generation, ssg, prerendering, deployment, github pages, spa mode, blogs, documentation sites, marketing sites, path: kit/adapter-static\n- title: Single-page apps, use_cases: spa mode, single-page apps, client-only rendering, static hosting, mobile app wrappers, no server-side logic, adapter-static setup, fallback pages, path: kit/single-page-apps\n- title: Cloudflare, use_cases: deployment, cloudflare workers, cloudflare pages, hosting setup, production builds, serverless deployment, edge computing, path: kit/adapter-cloudflare\n- title: Cloudflare Workers, use_cases: deploying to cloudflare workers, cloudflare workers sites deployment, legacy cloudflare adapter, wrangler configuration, cloudflare platform bindings, path: kit/adapter-cloudflare-workers\n- title: Netlify, use_cases: deployment, netlify hosting, production builds, serverless functions, edge functions, static site hosting, path: kit/adapter-netlify\n- title: Vercel, use_cases: deployment, vercel hosting, production builds, serverless functions, edge functions, isr, image optimization, environment variables, path: kit/adapter-vercel\n- title: Writing adapters, use_cases: custom deployment, building adapters, unsupported platforms, adapter development, custom hosting environments, path: kit/writing-adapters\n- title: Advanced routing, use_cases: advanced routing, dynamic routes, file viewers, nested paths, custom 404 pages, url validation, route parameters, multi-level navigation, path: kit/advanced-routing\n- title: Hooks, use_cases: authentication, logging, error tracking, request interception, api proxying, custom routing, internationalization, database initialization, middleware logic, session management, path: kit/hooks\n- title: Errors, use_cases: error handling, custom error pages, 404 pages, api error responses, production error logging, error tracking, type-safe errors, path: kit/errors\n- title: Link options, use_cases: routing, navigation, multi-page apps, performance optimization, link preloading, forms with get method, search functionality, focus management, scroll behavior, path: kit/link-options\n- title: Service workers, use_cases: offline support, pwa, caching strategies, performance optimization, precaching assets, network resilience, progressive web apps, path: kit/service-workers\n- title: Server-only modules, use_cases: api keys, environment variables, sensitive data protection, backend security, preventing data leaks, server-side code isolation, path: kit/server-only-modules\n- title: Snapshots, use_cases: forms, user input, preserving form data, multi-step forms, navigation state, preventing data loss, textarea content, input fields, comment systems, surveys, path: kit/snapshots\n- title: Shallow routing, use_cases: modals, dialogs, image galleries, overlays, history-driven ui, mobile-friendly navigation, photo viewers, lightboxes, drawer menus, path: kit/shallow-routing\n- title: Observability, use_cases: performance monitoring, debugging, observability, tracing requests, production diagnostics, analyzing slow requests, finding bottlenecks, monitoring server-side operations, path: kit/observability\n- title: Packaging, use_cases: building component libraries, publishing npm packages, creating reusable svelte components, library development, package distribution, path: kit/packaging\n- title: Auth, use_cases: authentication, login systems, user management, session handling, jwt tokens, protected routes, user credentials, authorization checks, path: kit/auth\n- title: Performance, use_cases: performance optimization, slow loading pages, production deployment, debugging performance issues, reducing bundle size, improving load times, path: kit/performance\n- title: Icons, use_cases: icons, ui components, styling, css frameworks, tailwind, unocss, performance optimization, dependency management, path: kit/icons\n- title: Images, use_cases: image optimization, responsive images, performance, hero images, product photos, galleries, cms integration, cdn setup, asset management, path: kit/images\n- title: Accessibility, use_cases: always, any sveltekit project, screen reader support, keyboard navigation, multi-page apps, client-side routing, internationalization, multilingual sites, path: kit/accessibility\n- title: SEO, use_cases: seo optimization, search engine ranking, content sites, blogs, marketing sites, public-facing apps, sitemaps, amp pages, meta tags, performance optimization, path: kit/seo\n- title: Frequently asked questions, use_cases: troubleshooting package imports, library compatibility issues, client-side code execution, external api integration, middleware setup, database configuration, view transitions, yarn configuration, path: kit/faq\n- title: Integrations, use_cases: project setup, css preprocessors, postcss, scss, sass, less, stylus, typescript setup, adding integrations, tailwind, testing, auth, linting, formatting, path: kit/integrations\n- title: Breakpoint Debugging, use_cases: debugging, breakpoints, development workflow, troubleshooting issues, vscode setup, ide configuration, inspecting code execution, path: kit/debugging\n- title: Migrating to SvelteKit v2, use_cases: migration, upgrading from sveltekit 1 to 2, breaking changes, version updates, path: kit/migrating-to-sveltekit-2\n- title: Migrating from Sapper, use_cases: migrating from sapper, upgrading legacy projects, sapper to sveltekit conversion, project modernization, path: kit/migrating\n- title: Additional resources, use_cases: troubleshooting, getting help, finding examples, learning sveltekit, project templates, common issues, community support, path: kit/additional-resources\n- title: Glossary, use_cases: rendering strategies, performance optimization, deployment configuration, seo requirements, static sites, spas, server-side rendering, prerendering, edge deployment, pwa development, path: kit/glossary\n- title: @sveltejs/kit, use_cases: forms, form actions, server-side validation, form submission, error handling, redirects, json responses, http errors, server utilities, path: kit/@sveltejs-kit\n- title: @sveltejs/kit/hooks, use_cases: middleware, request processing, authentication chains, logging, multiple hooks, request/response transformation, path: kit/@sveltejs-kit-hooks\n- title: @sveltejs/kit/node/polyfills, use_cases: node.js environments, custom servers, non-standard runtimes, ssr setup, web api compatibility, polyfill requirements, path: kit/@sveltejs-kit-node-polyfills\n- title: @sveltejs/kit/node, use_cases: node.js adapter, custom server setup, http integration, streaming files, node deployment, server-side rendering with node, path: kit/@sveltejs-kit-node\n- title: @sveltejs/kit/vite, use_cases: project setup, vite configuration, initial sveltekit setup, build tooling, path: kit/@sveltejs-kit-vite\n- title: $app/environment, use_cases: always, conditional logic, client-side code, server-side code, build-time logic, prerendering, development vs production, environment detection, path: kit/$app-environment\n- title: $app/forms, use_cases: forms, user input, data submission, progressive enhancement, custom form handling, form validation, path: kit/$app-forms\n- title: $app/navigation, use_cases: routing, navigation, multi-page apps, programmatic navigation, data reloading, preloading, shallow routing, navigation lifecycle, scroll handling, view transitions, path: kit/$app-navigation\n- title: $app/paths, use_cases: static assets, images, fonts, public files, base path configuration, subdirectory deployment, cdn setup, asset urls, links, navigation, path: kit/$app-paths\n- title: $app/server, use_cases: remote functions, server-side logic, data fetching, form handling, api endpoints, client-server communication, prerendering, file reading, batch queries, path: kit/$app-server\n- title: $app/state, use_cases: routing, navigation, multi-page apps, loading states, url parameters, form handling, error states, version updates, page metadata, shallow routing, path: kit/$app-state\n- title: $app/stores, use_cases: legacy projects, sveltekit pre-2.12, migration from stores to runes, maintaining older codebases, accessing page data, navigation state, app version updates, path: kit/$app-stores\n- title: $app/types, use_cases: routing, navigation, type safety, route parameters, dynamic routes, link generation, pathname validation, multi-page apps, path: kit/$app-types\n- title: $env/dynamic/private, use_cases: api keys, secrets management, server-side config, environment variables, backend logic, deployment-specific settings, private data handling, path: kit/$env-dynamic-private\n- title: $env/dynamic/public, use_cases: environment variables, client-side config, runtime configuration, public api keys, deployment-specific settings, multi-environment apps, path: kit/$env-dynamic-public\n- title: $env/static/private, use_cases: server-side api keys, backend secrets, database credentials, private configuration, build-time optimization, server endpoints, authentication tokens, path: kit/$env-static-private\n- title: $env/static/public, use_cases: environment variables, public config, client-side data, api endpoints, build-time configuration, public constants, path: kit/$env-static-public\n- title: $lib, use_cases: project setup, component organization, importing shared components, reusable ui elements, code structure, path: kit/$lib\n- title: $service-worker, use_cases: offline support, pwa, service workers, caching strategies, progressive web apps, offline-first apps, path: kit/$service-worker\n- title: Configuration, use_cases: project setup, configuration, adapters, deployment, build settings, environment variables, routing customization, prerendering, csp security, csrf protection, path configuration, typescript setup, path: kit/configuration\n- title: Command Line Interface, use_cases: project setup, typescript configuration, generated types, ./$types imports, initial project configuration, path: kit/cli\n- title: Types, use_cases: typescript, type safety, route parameters, api endpoints, load functions, form actions, generated types, jsconfig setup, path: kit/types\n- title: Overview, use_cases: always, any svelte project, getting started, learning svelte, introduction, project setup, understanding framework basics, path: svelte/overview\n- title: Getting started, use_cases: project setup, starting new svelte project, initial installation, choosing between sveltekit and vite, editor configuration, path: svelte/getting-started\n- title: .svelte files, use_cases: always, any svelte project, component creation, project setup, learning svelte basics, path: svelte/svelte-files\n- title: .svelte.js and .svelte.ts files, use_cases: shared reactive state, reusable reactive logic, state management across components, global stores, custom reactive utilities, path: svelte/svelte-js-files\n- title: What are runes?, use_cases: always, any svelte 5 project, understanding core syntax, learning svelte 5, migration from svelte 4, path: svelte/what-are-runes\n- title: $state, use_cases: always, any svelte project, core reactivity, state management, counters, forms, todo apps, interactive ui, data updates, class-based components, path: svelte/$state\n- title: $derived, use_cases: always, any svelte project, computed values, reactive calculations, derived data, transforming state, dependent values, path: svelte/$derived\n- title: $effect, use_cases: canvas drawing, third-party library integration, dom manipulation, side effects, intervals, timers, network requests, analytics tracking, path: svelte/$effect\n- title: $props, use_cases: always, any svelte project, passing data to components, component communication, reusable components, component props, path: svelte/$props\n- title: $bindable, use_cases: forms, user input, two-way data binding, custom input components, parent-child communication, reusable form fields, path: svelte/$bindable\n- title: $inspect, use_cases: debugging, development, tracking state changes, reactive state monitoring, troubleshooting reactivity issues, path: svelte/$inspect\n- title: $host, use_cases: custom elements, web components, dispatching custom events, component library, framework-agnostic components, path: svelte/$host\n- title: Basic markup, use_cases: always, any svelte project, basic markup, html templating, component structure, attributes, events, props, text rendering, path: svelte/basic-markup\n- title: {#if ...}, use_cases: always, conditional rendering, showing/hiding content, dynamic ui, user permissions, loading states, error handling, form validation, path: svelte/if\n- title: {#each ...}, use_cases: always, lists, arrays, iteration, product listings, todos, tables, grids, dynamic content, shopping carts, user lists, comments, feeds, path: svelte/each\n- title: {#key ...}, use_cases: animations, transitions, component reinitialization, forcing component remount, value-based ui updates, resetting component state, path: svelte/key\n- title: {#await ...}, use_cases: async data fetching, api calls, loading states, promises, error handling, lazy loading components, dynamic imports, path: svelte/await\n- title: {#snippet ...}, use_cases: reusable markup, component composition, passing content to components, table rows, list items, conditional rendering, reducing duplication, path: svelte/snippet\n- title: {@render ...}, use_cases: reusable ui patterns, component composition, conditional rendering, fallback content, layout components, slot alternatives, template reuse, path: svelte/@render\n- title: {@html ...}, use_cases: rendering html strings, cms content, rich text editors, markdown to html, blog posts, wysiwyg output, sanitized html injection, dynamic html content, path: svelte/@html\n- title: {@attach ...}, use_cases: tooltips, popovers, dom manipulation, third-party libraries, canvas drawing, element lifecycle, interactive ui, custom directives, wrapper components, path: svelte/@attach\n- title: {@const ...}, use_cases: computed values in loops, derived calculations in blocks, local variables in each iterations, complex list rendering, path: svelte/@const\n- title: {@debug ...}, use_cases: debugging, development, troubleshooting, tracking state changes, monitoring variables, reactive data inspection, path: svelte/@debug\n- title: bind:, use_cases: forms, user input, two-way data binding, interactive ui, media players, file uploads, checkboxes, radio buttons, select dropdowns, contenteditable, dimension tracking, path: svelte/bind\n- title: use:, use_cases: custom directives, dom manipulation, third-party library integration, tooltips, click outside, gestures, focus management, element lifecycle hooks, path: svelte/use\n- title: transition:, use_cases: animations, interactive ui, modals, dropdowns, notifications, conditional content, show/hide elements, smooth state changes, path: svelte/transition\n- title: in: and out:, use_cases: animation, transitions, interactive ui, conditional rendering, independent enter/exit effects, modals, tooltips, notifications, path: svelte/in-and-out\n- title: animate:, use_cases: sortable lists, drag and drop, reorderable items, todo lists, kanban boards, playlist editors, priority queues, animated list reordering, path: svelte/animate\n- title: style:, use_cases: dynamic styling, conditional styles, theming, dark mode, responsive design, interactive ui, component styling, path: svelte/style\n- title: class, use_cases: always, conditional styling, dynamic classes, tailwind css, component styling, reusable components, responsive design, path: svelte/class\n- title: await, use_cases: async data fetching, loading states, server-side rendering, awaiting promises in components, async validation, concurrent data loading, path: svelte/await-expressions\n- title: Scoped styles, use_cases: always, styling components, scoped css, component-specific styles, preventing style conflicts, animations, keyframes, path: svelte/scoped-styles\n- title: Global styles, use_cases: global styles, third-party libraries, css resets, animations, styling body/html, overriding component styles, shared keyframes, base styles, path: svelte/global-styles\n- title: Custom properties, use_cases: theming, custom styling, reusable components, design systems, dynamic colors, component libraries, ui customization, path: svelte/custom-properties\n- title: Nested <style> elements, use_cases: component styling, scoped styles, dynamic styles, conditional styling, nested style tags, custom styling logic, path: svelte/nested-style-elements\n- title: <svelte:boundary>, use_cases: error handling, async data loading, loading states, error recovery, flaky components, error reporting, resilient ui, path: svelte/svelte-boundary\n- title: <svelte:window>, use_cases: keyboard shortcuts, scroll tracking, window resize handling, responsive layouts, online/offline detection, viewport dimensions, global event listeners, path: svelte/svelte-window\n- title: <svelte:document>, use_cases: document events, visibility tracking, fullscreen detection, pointer lock, focus management, document-level interactions, path: svelte/svelte-document\n- title: <svelte:body>, use_cases: mouse tracking, hover effects, cursor interactions, global body events, drag and drop, custom cursors, interactive backgrounds, body-level actions, path: svelte/svelte-body\n- title: <svelte:head>, use_cases: seo optimization, page titles, meta tags, social media sharing, dynamic head content, multi-page apps, blog posts, product pages, path: svelte/svelte-head\n- title: <svelte:element>, use_cases: dynamic content, cms integration, user-generated content, configurable ui, runtime element selection, flexible components, path: svelte/svelte-element\n- title: <svelte:options>, use_cases: migration, custom elements, web components, legacy mode compatibility, runes mode setup, svg components, mathml components, css injection control, path: svelte/svelte-options\n- title: Stores, use_cases: shared state, cross-component data, reactive values, async data streams, manual control over updates, rxjs integration, extracting logic, path: svelte/stores\n- title: Context, use_cases: shared state, avoiding prop drilling, component communication, theme providers, user context, authentication state, configuration sharing, deeply nested components, path: svelte/context\n- title: Lifecycle hooks, use_cases: component initialization, cleanup tasks, timers, subscriptions, dom measurements, chat windows, autoscroll features, migration from svelte 4, path: svelte/lifecycle-hooks\n- title: Imperative component API, use_cases: project setup, client-side rendering, server-side rendering, ssr, hydration, testing, programmatic component creation, tooltips, dynamic mounting, path: svelte/imperative-component-api\n- title: Hydratable data, use_cases: use title and path to estimate use case, path: svelte/hydratable\n- title: Best practices, use_cases: use title and path to estimate use case, path: svelte/best-practices\n- title: Testing, use_cases: testing, quality assurance, unit tests, integration tests, component tests, e2e tests, vitest setup, playwright setup, test automation, path: svelte/testing\n- title: TypeScript, use_cases: typescript setup, type safety, component props typing, generic components, wrapper components, dom type augmentation, project configuration, path: svelte/typescript\n- title: Custom elements, use_cases: web components, custom elements, component library, design system, framework-agnostic components, embedding svelte in non-svelte apps, shadow dom, path: svelte/custom-elements\n- title: Svelte 4 migration guide, use_cases: upgrading svelte 3 to 4, version migration, updating dependencies, breaking changes, legacy project maintenance, path: svelte/v4-migration-guide\n- title: Svelte 5 migration guide, use_cases: migrating from svelte 4 to 5, upgrading projects, learning svelte 5 syntax changes, runes migration, event handler updates, path: svelte/v5-migration-guide\n- title: Frequently asked questions, use_cases: getting started, learning svelte, beginner setup, project initialization, vs code setup, formatting, testing, routing, mobile apps, troubleshooting, community support, path: svelte/faq\n- title: svelte, use_cases: migration from svelte 4 to 5, upgrading legacy code, component lifecycle hooks, context api, mounting components, event dispatchers, typescript component types, path: svelte/svelte\n- title: svelte/action, use_cases: typescript types, actions, use directive, dom manipulation, element lifecycle, custom behaviors, third-party library integration, path: svelte/svelte-action\n- title: svelte/animate, use_cases: animated lists, sortable items, drag and drop, reordering elements, todo lists, kanban boards, playlist management, smooth position transitions, path: svelte/svelte-animate\n- title: svelte/attachments, use_cases: library development, component libraries, programmatic element manipulation, migrating from actions to attachments, spreading props onto elements, path: svelte/svelte-attachments\n- title: svelte/compiler, use_cases: build tools, custom compilers, ast manipulation, preprocessors, code transformation, migration scripts, syntax analysis, bundler plugins, dev tools, path: svelte/svelte-compiler\n- title: svelte/easing, use_cases: animations, transitions, custom easing, smooth motion, interactive ui, modals, dropdowns, carousels, page transitions, scroll effects, path: svelte/svelte-easing\n- title: svelte/events, use_cases: window events, document events, global event listeners, event delegation, programmatic event handling, cleanup functions, media queries, path: svelte/svelte-events\n- title: svelte/legacy, use_cases: migration from svelte 4 to svelte 5, upgrading legacy code, event modifiers, class components, imperative component instantiation, path: svelte/svelte-legacy\n- title: svelte/motion, use_cases: animation, smooth transitions, interactive ui, sliders, counters, physics-based motion, drag gestures, accessibility, reduced motion, path: svelte/svelte-motion\n- title: svelte/reactivity/window, use_cases: responsive design, viewport tracking, scroll effects, window resize handling, online/offline detection, zoom level tracking, path: svelte/svelte-reactivity-window\n- title: svelte/reactivity, use_cases: reactive data structures, state management with maps/sets, game boards, selection tracking, url manipulation, query params, real-time clocks, media queries, responsive design, path: svelte/svelte-reactivity\n- title: svelte/server, use_cases: server-side rendering, ssr, static site generation, seo optimization, initial page load, pre-rendering, node.js server, custom server setup, path: svelte/svelte-server\n- title: svelte/store, use_cases: state management, shared data, reactive stores, cross-component communication, global state, computed values, data synchronization, legacy svelte projects, path: svelte/svelte-store\n- title: svelte/transition, use_cases: animations, transitions, interactive ui, modals, dropdowns, tooltips, notifications, svg animations, list animations, page transitions, path: svelte/svelte-transition\n- title: Compiler errors, use_cases: animation, transitions, keyed each blocks, list animations, path: svelte/compiler-errors\n- title: Compiler warnings, use_cases: accessibility, a11y compliance, wcag standards, screen readers, keyboard navigation, aria attributes, semantic html, interactive elements, path: svelte/compiler-warnings\n- title: Runtime errors, use_cases: debugging errors, error handling, troubleshooting runtime issues, migration to svelte 5, component binding, effects and reactivity, path: svelte/runtime-errors\n- title: Runtime warnings, use_cases: debugging state proxies, console logging reactive values, inspecting state changes, development troubleshooting, path: svelte/runtime-warnings\n- title: Overview, use_cases: migrating from svelte 3/4 to svelte 5, maintaining legacy components, understanding deprecated features, gradual upgrade process, path: svelte/legacy-overview\n- title: Reactive let/var declarations, use_cases: migration, legacy svelte projects, upgrading from svelte 4, understanding old reactivity, maintaining existing code, learning runes differences, path: svelte/legacy-let\n- title: Reactive $: statements, use_cases: legacy mode, migration from svelte 4, reactive statements, computed values, derived state, side effects, path: svelte/legacy-reactive-assignments\n- title: export let, use_cases: legacy mode, migration from svelte 4, maintaining older projects, component props without runes, exporting component methods, renaming reserved word props, path: svelte/legacy-export-let\n- title: $$props and $$restProps, use_cases: legacy mode migration, component wrappers, prop forwarding, button components, reusable ui components, spreading props to child elements, path: svelte/legacy-$$props-and-$$restProps\n- title: on:, use_cases: legacy mode, event handling, button clicks, forms, user interactions, component communication, event forwarding, event modifiers, path: svelte/legacy-on\n- title: <slot>, use_cases: legacy mode, migrating from svelte 4, component composition, reusable components, passing content to components, modals, layouts, wrappers, path: svelte/legacy-slots\n- title: $$slots, use_cases: legacy mode, conditional slot rendering, optional content sections, checking if slots provided, migrating from legacy to runes, path: svelte/legacy-$$slots\n- title: <svelte:fragment>, use_cases: named slots, component composition, layout systems, avoiding wrapper divs, legacy svelte projects, slot content organization, path: svelte/legacy-svelte-fragment\n- title: <svelte:component>, use_cases: dynamic components, component switching, conditional rendering, legacy mode migration, tabbed interfaces, multi-step forms, path: svelte/legacy-svelte-component\n- title: <svelte:self>, use_cases: recursive components, tree structures, nested menus, file explorers, comment threads, hierarchical data, path: svelte/legacy-svelte-self\n- title: Imperative component API, use_cases: migration from svelte 3/4 to 5, legacy component api, maintaining old projects, understanding deprecated patterns, path: svelte/legacy-component-api\n\n</available-docs>\n\nThese are the available documentation sections that `list-sections` will return, you do not need to call it again.\n\nEvery time you write a Svelte component or a Svelte module you MUST invoke the `svelte-autofixer` tool providing the code. The tool will return a list of issues or suggestions. If there are any issues or suggestions you MUST fix them and call the tool again with the updated code. You MUST keep doing this until the tool returns no issues or suggestions. Only then you can return the code to the user.\n\nThis is the task you will work on:\n\n<task>\n[YOUR TASK HERE]\n</task>\n\nIf you are not writing the code into a file, once you have the final version of the code ask the user if it wants to generate a playground link to quickly check the code in it and if it answer yes call the `playground-link` tool and return the url to the user nicely formatted. The playground link MUST be generated only once you have the final version of the code and you are ready to share it, it MUST include an entry point file called `App.svelte` where the main component should live. If you have multiple files to include in the playground link you can include them all at the root.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","CLI"],"href":"/docs/ai/cli","content":"The @sveltejs/mcp npm package normally launches the local stdio MCP server:npx -y @sveltejs/mcpIf you invoke it with a subcommand, it behaves like a regular CLI and prints the result directly in your terminal instead. This is useful for agents, scripts and quick manual checks.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","CLI","Usage"],"href":"/docs/ai/cli#Usage","content":"npx -y @sveltejs/mcp <command> [options]Available commands:`list-sections`\n`get-documentation <sections>`\n`svelte-autofixer <code_or_path>`You can learn more about the commands withnpx -y @sveltejs/mcp --help\nnpx -y @sveltejs/mcp <command> --help\nnpx -y @sveltejs/mcp --version","rank":null},{"breadcrumbs":["Docs","AI","MCP server","CLI","list-sections"],"href":"/docs/ai/cli#list-sections","content":"Lists all available Svelte and SvelteKit documentation sections.npx -y @sveltejs/mcp list-sectionsThe output is a structured text list of sections, including each section's title, use_cases, and documentation path. This is the same catalog the MCP tool uses before calling get-documentation.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","CLI","get-documentation"],"href":"/docs/ai/cli#get-documentation","content":"Fetches the full documentation for one or more sections.npx -y @sveltejs/mcp get-documentation 'svelte/$state'\n# or\nnpx -y @sveltejs/mcp get-documentation 'svelte/$state,svelte/await-expressions'Each section can be matched by title or by documentation path. If a section cannot be found, the CLI returns an error plus similar matches when available.","rank":null},{"breadcrumbs":["Docs","AI","MCP server","CLI","svelte-autofixer"],"href":"/docs/ai/cli#svelte-autofixer","content":"Runs the Svelte autofixer against either inline code or a file path:npx -y @sveltejs/mcp svelte-autofixer 'src/routes/+page.svelte'If the argument is an existing path, the CLI reads the file automatically. Otherwise it treats the argument as raw Svelte code.Because most shells expand $, inline code should be quoted or escaped correctly. In practice, passing a file path is usually easier than passing source directly.Available options:`--svelte-version <4|5>` - choose which Svelte version to validate against (defaults to `5`)\n`--async` - enable async Svelte analysis for Svelte 5 projectsThe command prints an object with:`issues`\n`suggestions`\n`require_another_tool_call_after_fixing`This makes it easy to use in an agentic loop: run the autofixer, apply fixes, then run it again until it reports no remaining issues or suggestions.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview"],"href":"/docs/ai/skills","content":"This is the list of available skills provided by the Svelte MCP package. Skills are sets of instructions that AI agents can load on-demand to help with specific tasks.Skills are available in both the Claude Code plugin (installed via the marketplace) and the OpenCode plugin (@sveltejs/opencode). They can also be manually installed in your .claude/skills or .opencode/skills folder.You can download the latest skills from the releases page of the repo, or find them in the `tools/skills` folder.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","svelte-code-writer"],"href":"/docs/ai/skills#svelte-code-writer","content":"CLI tools for Svelte 5 documentation lookup and code analysis. MUST be used whenever creating, editing or analyzing any Svelte component (.svelte) or Svelte module (.svelte.ts/.svelte.js). If possible, this skill should be executed within the svelte-file-editor agent for optimal results.\nOpen Releases page\n\n\n# Svelte 5 Code Writer","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","CLI Tools"],"href":"/docs/ai/skills#CLI-Tools","content":"You have access to @sveltejs/mcp CLI for Svelte-specific assistance. Use these commands via npx:","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","CLI Tools","List Documentation Sections"],"href":"/docs/ai/skills#CLI-Tools-List-Documentation-Sections","content":"npx @sveltejs/mcp list-sectionsLists all available Svelte 5 and SvelteKit documentation sections with titles and paths.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","CLI Tools","Get Documentation"],"href":"/docs/ai/skills#CLI-Tools-Get-Documentation","content":"npx @sveltejs/mcp get-documentation \"<section1>,<section2>,...\"Retrieves full documentation for specified sections. Use after list-sections to fetch relevant docs.Example:npx @sveltejs/mcp get-documentation \"$state,$derived,$effect\"","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","CLI Tools","Svelte Autofixer"],"href":"/docs/ai/skills#CLI-Tools-Svelte-Autofixer","content":"npx @sveltejs/mcp svelte-autofixer \"<code_or_path>\" [options]Analyzes Svelte code and suggests fixes for common issues.Options:`--async` - Enable async Svelte mode (default: false)\n`--svelte-version` - Target version: 4 or 5 (default: 5)Examples:# Analyze inline code (escape $ as \\$)\nnpx @sveltejs/mcp svelte-autofixer '<script>let count = \\$state(0);</script>'\n\n# Analyze a file\nnpx @sveltejs/mcp svelte-autofixer ./src/lib/Component.svelte\n\n# Target Svelte 4\nnpx @sveltejs/mcp svelte-autofixer ./Component.svelte --svelte-version 4Important: When passing code with runes ($state, $derived, etc.) via the terminal, escape the $ character as \\$ to prevent shell variable substitution.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Workflow"],"href":"/docs/ai/skills#Workflow","content":"**Uncertain about syntax?** Run `list-sections` then `get-documentation` for relevant topics\n**Reviewing/debugging?** Run `svelte-autofixer` on the code to detect issues\n**Always validate** - Run `svelte-autofixer` before finalizing any Svelte component<!-- prettier-ignore-end -->\n\n</details>","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","svelte-core-bestpractices"],"href":"/docs/ai/skills#svelte-core-bestpractices","content":"Guidance on writing fast, robust, modern Svelte code. Load this skill whenever in a Svelte project and asked to write/edit or analyze a Svelte component or module. Covers reactivity, event handling, styling, integration with libraries and more.\nOpen Releases page","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","$state"],"href":"/docs/ai/skills#$state","content":"Only use the $state rune for variables that should be reactive — in other words, variables that cause an $effect, $derived or template expression to update. Everything else can be a normal variable.Objects and arrays ($state({...}) or $state([...])) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you're dealing with large objects that are only ever reassigned (rather than mutated), use $state.raw instead. This is often the case with API responses, for example.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","$derived"],"href":"/docs/ai/skills#$derived","content":"To compute something from state, use $derived rather than $effect:// do this\nlet square = $derived(num * num);\n\n// don't do this\nlet square;\n\n$effect(() => {\n\tsquare = num * num;\n});[!NOTE] `$derived` is given an expression, _not_ a function. If you need to use a function (because the expression is complex, for example) use `$derived.by`.Deriveds are writable — you can assign to them, just like $state, except that they will re-evaluate when their expression changes.If the derived expression is an object or array, it will be returned as-is — it is not made deeply reactive. You can, however, use $state inside $derived.by in the rare cases that you need this.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","$effect"],"href":"/docs/ai/skills#$effect","content":"Effects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.If you need to sync state to an external library such as D3, it is often neater to use [`{@attach ...}`](references/@attach.md)\nIf you need to run some code in response to user interaction, put the code directly in an event handler or use a [function binding](references/bind.md) as appropriate\nIf you need to log values for debugging purposes, use [`$inspect`](references/$inspect.md)\nIf you need to observe something external to Svelte, use [`createSubscriber`](references/svelte-reactivity.md)Never wrap the contents of an effect in if (browser) {...} or similar — effects do not run on the server.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","$props"],"href":"/docs/ai/skills#$props","content":"Treat props as though they will change. For example, values that depend on props should usually use $derived: \nlet { type } = $props();\n\n// do this\nlet color = $derived(type === 'danger' ? 'red' : 'green');\n\n// don't do this — `color` will not update if `type` changes\nlet color = type === 'danger' ? 'red' : 'green';","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","$inspect.trace"],"href":"/docs/ai/skills#$inspect.trace","content":"$inspect.trace is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add $inspect.trace(label) as the first line of an $effect or $derived.by (or any function they call) to trace their dependencies and discover which one triggered an update.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Events"],"href":"/docs/ai/skills#Events","content":"Any element attribute starting with on is treated as an event listener:<button onclick={() => {...}}>click me</button>\n\n<!-- attribute shorthand also works -->\n<button {onclick}>...</button>\n\n<!-- so do spread attributes -->\n<button {...props}>...</button>If you need to attach listeners to window or document you can use <svelte:window> and <svelte:document>:<svelte:window onkeydown={...} />\n<svelte:document onvisibilitychange={...} />Avoid using onMount or $effect for this.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Snippets"],"href":"/docs/ai/skills#Snippets","content":"Snippets are a way to define reusable chunks of markup that can be instantiated with the `{@render ...}` tag, or passed to components as props. They must be declared within the template.{#snippet greeting(name)}\n\t<p>hello {name}!</p>\n{/snippet}\n\n{@render greeting('world')}[!NOTE] Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside `<script>`. A snippet that doesn't reference component state is also available in a `<script module>`, in which case it can be exported for use by other components.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Each blocks"],"href":"/docs/ai/skills#Each-blocks","content":"Prefer to use keyed each blocks — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.[!NOTE] The key _must_ uniquely identify the object. Do not use the index as a key.Avoid destructuring if you need to mutate the item (with something like bind:value={item.count}, for example).","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Using JavaScript variables in CSS"],"href":"/docs/ai/skills#Using-JavaScript-variables-in-CSS","content":"If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the style: directive.<div style:--columns={columns}>...</div>You can then reference var(--columns) inside the component's <style>.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Styling child components"],"href":"/docs/ai/skills#Styling-child-components","content":"The CSS in a component's <style> is scoped to that component. If a parent component needs to control the child's styles, the preferred way is to use CSS custom properties:<!-- Parent.svelte -->\n<Child --color=\"red\" />\n\n<!-- Child.svelte -->\n<h1>Hello</h1>\n\n<style>\n\th1 {\n\t\tcolor: var(--color);\n\t}\n</style>If this is impossible (for example, the child component comes from a library) you can use :global to override styles:<div>\n\t<Child />\n</div>\n\n<style>\n\tdiv :global {\n\t\th1 {\n\t\t\tcolor: red;\n\t\t}\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Context"],"href":"/docs/ai/skills#Context","content":"Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.Use createContext rather than setContext and getContext, as it provides type safety.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Async Svelte"],"href":"/docs/ai/skills#Async-Svelte","content":"If using version 5.36 or higher, you can use await expressions and hydratable to use promises directly inside components. Note that these require the experimental.async option to be enabled in svelte.config.js as they are not yet considered fully stable.","rank":null},{"breadcrumbs":["Docs","AI","Skills","Overview","Avoid legacy features"],"href":"/docs/ai/skills#Avoid-legacy-features","content":"Always use runes mode for new code, and avoid features that have more modern replacements:use `$state` instead of implicit reactivity (e.g. `let count = 0; count += 1`)\nuse `$derived` and `$effect` instead of `$:` assignments and statements (but only use effects when there is no better solution)\nuse `$props` instead of `export let`, `$$props` and `$$restProps`\nuse `onclick={...}` instead of `on:click={...}`\nuse `{#snippet ...}` and `{@render ...}` instead of `<slot>` and `$$slots` and `<svelte:fragment>`\nuse `<DynamicComponent>` instead of `<svelte:component this={DynamicComponent}>`\nuse `import Self from './ThisComponent.svelte'` and `<Self>` instead of `<svelte:self>`\nuse classes with `$state` fields to share reactivity between components, instead of using stores\nuse `{@attach ...}` instead of `use:action`\nuse clsx-style arrays and objects in `class` attributes, instead of the `class:` directive<!-- prettier-ignore-end -->\n\n</details>","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview"],"href":"/docs/ai/subagent","content":"Since creating, editing or analyzing a Svelte file is an atomic operation we recommend creating a subagent that your main agent can invoke whenever it needs to interact with a Svelte component. Subagents use a separate context window, allowing them to fetch documentation, iterate with `svelte-autofixer` and write to the filesystem without wasting context in the main agent.Delegation should happen automatically when appropriate, but you can also explicitly request the subagent be used for Svelte-related tasks.You can write your own or take inspiration from the one available in the `sveltejs/ai-tools` repository: a specialized subagent called svelte-file-editor designed for creating, editing, and reviewing Svelte files.\n\n---\nname: svelte-file-editor\ndescription: Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when creating, editing, or reviewing any .svelte file or .svelte.ts/.svelte.js module and MUST use the tools from the MCP server or the `svelte-file-editor` skill if they are available. Fetches relevant documentation and validates code using the Svelte MCP server tools.\n---\n\nYou are a Svelte 5 expert responsible for writing, editing, and validating Svelte components and modules. You have access to the Svelte MCP server which provides documentation and code analysis tools. Always use the tools from the svelte MCP server to fetch documentation with `get_documentation` and validating the code with `svelte_autofixer`. If the autofixer returns any issue or suggestions try to solve them.\n\nIf the MCP tools are not available you can use the `svelte-code-writer` skill to learn how to use the `@sveltejs/mcp` cli to access the same tools.\n\nIf the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Available MCP Tools"],"href":"/docs/ai/subagent#Available-MCP-Tools","content":"","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Available MCP Tools","1. list-sections"],"href":"/docs/ai/subagent#Available-MCP-Tools-1.-list-sections","content":"Lists all available Svelte 5 and SvelteKit documentation sections with titles and paths. Use this first to discover what documentation is available.","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Available MCP Tools","2. get-documentation"],"href":"/docs/ai/subagent#Available-MCP-Tools-2.-get-documentation","content":"Retrieves full documentation for specified sections. Accepts a single section name or an array of section names. Use after list-sections to fetch relevant docs for the task at hand.Example sections: $state, $derived, $effect, $props, $bindable, snippets, routing, load functions","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Available MCP Tools","3. svelte-autofixer"],"href":"/docs/ai/subagent#Available-MCP-Tools-3.-svelte-autofixer","content":"Analyzes Svelte code and returns suggestions to fix issues. Pass the component code directly to this tool. It will detect common mistakes like:Using `$effect` instead of `$derived` for computations\nMissing cleanup in effects\nSvelte 4 syntax (`on:click`, `export let`, `<slot>`)\nMissing keys in `{#each}` blocks\nAnd more","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow"],"href":"/docs/ai/subagent#Workflow","content":"When invoked to work on a Svelte file:","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow","1. Gather Context (if needed)"],"href":"/docs/ai/subagent#Workflow-1.-Gather-Context-(if-needed)","content":"If you're uncertain about Svelte 5 syntax or patterns, use the MCP tools:Call `list-sections` to see available documentation\nCall `get-documentation` with relevant section names","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow","2. Read the Target File"],"href":"/docs/ai/subagent#Workflow-2.-Read-the-Target-File","content":"Read the file to understand the current implementation.","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow","3. Make Changes"],"href":"/docs/ai/subagent#Workflow-3.-Make-Changes","content":"Apply edits following Svelte 5 best practices:","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow","4. Validate Changes"],"href":"/docs/ai/subagent#Workflow-4.-Validate-Changes","content":"After editing, ALWAYS call svelte-autofixer with the updated code to check for issues.","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Workflow","5. Fix Any Issues"],"href":"/docs/ai/subagent#Workflow-5.-Fix-Any-Issues","content":"If the autofixer reports problems, fix them and re-validate until no issues remain.","rank":null},{"breadcrumbs":["Docs","AI","Subagents","Overview","Output Format"],"href":"/docs/ai/subagent#Output-Format","content":"After completing your work, provide:Summary of changes made\nAny issues found and fixed by the autofixer\nRecommendations for further improvements (if any)<!-- prettier-ignore-end -->\n\n</details>","rank":null},{"breadcrumbs":["Docs","AI","Plugins","Claude Code"],"href":"/docs/ai/claude-plugin","content":"The open source repository containing the code for the MCP server is also a Claude Code plugin marketplace.The marketplace allows you to install the svelte plugin which will give you the remote MCP server, skills to instruct the LLM on how to properly write Svelte 5 code, and a specialized agent for editing Svelte files.If possible, we recommend that you instruct the LLM to execute MCP calls with the agent (you can explicitly mention an agent in your message to delegate work to it) when creating or editing .svelte files or .svelte.ts/.svelte.js modules — this will help save context by handling Svelte-specific tasks more efficiently.","rank":null},{"breadcrumbs":["Docs","AI","Plugins","Claude Code","Installation"],"href":"/docs/ai/claude-plugin#Installation","content":"To add the repository as a marketplace, launch Claude Code and type the following:/plugin marketplace add sveltejs/ai-toolsThen, install the Svelte plugin:/plugin install svelte","rank":null},{"breadcrumbs":["Docs","AI","Plugins","OpenCode"],"href":"/docs/ai/opencode-plugin","content":"OpenCode has a plugin system that allows developers to add MCP servers, agents and commands programmatically. Svelte has an OpenCode plugin published under @sveltejs/opencode.","rank":null},{"breadcrumbs":["Docs","AI","Plugins","OpenCode","Installation"],"href":"/docs/ai/opencode-plugin#Installation","content":"To install the plugin you can edit your OpenCode config (either the global or the local one), adding @sveltejs/opencode to the list of plugins.{\n\t\"$schema\": \"https://opencode.ai/config.json\",\n\t\"plugin\": [\"@sveltejs/opencode\"]\n}That's it! You now have the Svelte MCP server, skills, and the svelte-file-editor subagent configured for you.","rank":null},{"breadcrumbs":["Docs","AI","Plugins","OpenCode","Configuration"],"href":"/docs/ai/opencode-plugin#Configuration","content":"By default, everything is enabled, but you can configure the plugin by adding a configuration file:locally, in `.opencode/svelte.json`\nglobally, in `~/.config/opencode/svelte.json` (or, if you have specified the environment variable, in `$OPENCODE_CONFIG_DIR/svelte.json`){\n\t\"$schema\": \"https://svelte.dev/opencode/schema.json\",\n\t\"mcp\": {\n\t\t\"type\": \"remote\", // or \"local\" — defaults to remote\n\t\t\"enabled\": true\n\t},\n\t\"subagent\": {\n\t\t\"enabled\": true,\n\t\t\"agents\": {\n\t\t\t\"svelte-file-editor\": {\n\t\t\t\t\"model\": \"<other-model>\", // defaults to the same as main agent\n\t\t\t\t\"temperature\": 1, // defaults to unset\n\t\t\t\t\"top_p\": 0.7, // defaults to unset\n\t\t\t\t\"maxSteps\": 20 // defaults to unlimited\n\t\t\t}\n\t\t}\n\t},\n\t\"skills\": {\n\t\t// this can be `true`, or an array of skills to enable\n\t\t// e.g. [\"svelte-core-bestpractices\"]\n\t\t\"enabled\": true\n\t},\n\t\"instructions\": {\n\t\t\"enabled\": true\n\t}\n}","rank":null},{"breadcrumbs":["Docs","AI","Plugins","Cursor"],"href":"/docs/ai/cursor-plugin","content":"Cursor has a plugin system that can bundle rules, skills, agents, commands, MCP servers, and hooks.The Svelte plugin gives you the remote Svelte MCP server, Cursor skills, an always-on rule that tells the model how to use the Svelte MCP tools correctly, and the svelte-file-editor subagent for working on .svelte files and .svelte.ts/.svelte.js modules. The source is available in the `sveltejs/ai-tools` repo.","rank":null},{"breadcrumbs":["Docs","AI","Plugins","Cursor","Installation"],"href":"/docs/ai/cursor-plugin#Installation","content":"Install the plugin from the Cursor Marketplace with the following command:/add-plugin sveltePlugins can be installed either for the current project or at user level.Once installed, Cursor will discover the plugin components automatically:the Svelte MCP server is added from the plugin's `.mcp.json`\nrules and skills appear in Cursor's rules UI\nthe `svelte-file-editor` agent becomes available in chat[!NOTE] The Cursor CLI does not support plugins yet. Plugin support in [Cloud Agents](https://cursor.com/docs/cloud-agent) is limited to MCP servers.","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Overview"],"href":"/docs/cli/overview","content":"The command line interface (CLI), sv, is a toolkit for creating and maintaining Svelte applications.","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Overview","Usage"],"href":"/docs/cli/overview#Usage","content":"The easiest way to run sv is with `npx` (or the equivalent command if you're using a different package manager — for example, pnpm dlx if you're using pnpm):npx sv <command> <args>If you're inside a project where sv is already installed, this will use the local installation, otherwise it will download the latest version and run it without installing it, which is particularly useful for `sv create`.","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Overview","Acknowledgements"],"href":"/docs/cli/overview#Acknowledgements","content":"Thank you to Christopher Brown who originally owned the sv name on npm for graciously allowing it to be used for the Svelte CLI. You can find the original sv package at `@chbrown/sv`.","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Frequently asked questions"],"href":"/docs/cli/faq","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Frequently asked questions","How do I run the `sv` CLI?"],"href":"/docs/cli/faq#How-do-I-run-the-sv-CLI","content":"Running sv looks slightly different for each package manager. Here is a list of the most common commands:**npm** : `npx sv create`\n**pnpm** : `pnpm dlx sv create`\n**Bun** : `bunx sv create`\n**Deno** : `deno run npm:sv create`\n**Yarn** : `yarn dlx sv create`","rank":null},{"breadcrumbs":["Docs","CLI","Introduction","Frequently asked questions","`npx sv` is not working"],"href":"/docs/cli/faq#npx-sv-is-not-working","content":"Some package managers prefer to run locally installed tools instead of downloading and executing packages from the registry. This issue mostly occurs with npm and yarn. This usually results in an error message or looks like the command you were trying to execute did not do anything.Here is a list of issues with possible solutions that users have encountered in the past:[`npx sv` create does nothing](https://github.com/sveltejs/cli/issues/472)\n[`sv` command name collides with `runit`](https://github.com/sveltejs/cli/issues/259)\n[`sv` in windows powershell conflicts with `Set-Variable`](https://github.com/sveltejs/cli/issues/317)","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create"],"href":"/docs/cli/sv-create","content":"sv create sets up a new SvelteKit project, with options to setup additional functionality.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Usage"],"href":"/docs/cli/sv-create#Usage","content":"npx sv create [options] [path]","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options"],"href":"/docs/cli/sv-create#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--from-playground <url>"],"href":"/docs/cli/sv-create#Options-from-playground-url","content":"Create a SvelteKit project from a playground URL. This downloads all playground files, detects external dependencies, and sets up a complete SvelteKit project structure with everything ready to go.Example:npx sv create --from-playground=\"https://svelte.dev/playground/hello-world\"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--template <name>"],"href":"/docs/cli/sv-create#Options-template-name","content":"Which project template to use:`minimal` — barebones scaffolding for your new app\n`demo` — showcase app with a word guessing game that works without JavaScript\n`library` — template for a Svelte library, set up with `svelte-package`\n<!-- TODO: JYC: Uncomment this when the addon template is ready -->\n<!-- - `addon` — template for a community add-on, ready to be tested & published -->","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--types <option>"],"href":"/docs/cli/sv-create#Options-types-option","content":"Whether and how to add typechecking to the project:`ts` — default to `.ts` files and use `lang=\"ts\"` for `.svelte` components\n`jsdoc` — use [JSDoc syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) for types","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--no-types"],"href":"/docs/cli/sv-create#Options-no-types","content":"Prevent typechecking from being added. Not recommended!","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--add [add-ons...]"],"href":"/docs/cli/sv-create#Options-add-add-ons","content":"Add add-ons to the project in the create command. Following the same format as sv add.Example:npx sv create --add eslint prettier [path]","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--no-add-ons"],"href":"/docs/cli/sv-create#Options-no-add-ons","content":"Run the command without the interactive add-ons prompt","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--install <package-manager>"],"href":"/docs/cli/sv-create#Options-install-package-manager","content":"Installs dependencies with a specified package manager:`npm`\n`pnpm`\n`yarn`\n`bun`\n`deno`","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--no-install"],"href":"/docs/cli/sv-create#Options-no-install","content":"Prevents installing dependencies.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv create","Options","--no-dir-check"],"href":"/docs/cli/sv-create#Options-no-dir-check","content":"Skip checking whether the target directory is empty.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add"],"href":"/docs/cli/sv-add","content":"sv add updates an existing project with new functionality.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Usage"],"href":"/docs/cli/sv-add#Usage","content":"npx sv addnpx sv add [add-ons]You can select multiple space-separated add-ons from the list below, or you can use the interactive prompt.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options"],"href":"/docs/cli/sv-add#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options","-C`, `--cwd"],"href":"/docs/cli/sv-add#Options-C-cwd","content":"Path to the root of your Svelte(Kit) project.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options","--no-git-check"],"href":"/docs/cli/sv-add#Options-no-git-check","content":"Even if some files are dirty, no prompt will be shown","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options","--no-download-check"],"href":"/docs/cli/sv-add#Options-no-download-check","content":"Skip all download confirmation prompts[!IMPORTANT]\nSvelte maintainers have not reviewed community add-ons for malicious code. Use at your discretion","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options","--install <package-manager>"],"href":"/docs/cli/sv-add#Options-install-package-manager","content":"Installs dependencies with a specified package manager:`npm`\n`pnpm`\n`yarn`\n`bun`\n`deno`","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Options","--no-install"],"href":"/docs/cli/sv-add#Options-no-install","content":"Prevents installing dependencies","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Official add-ons"],"href":"/docs/cli/sv-add#Official-add-ons","content":"[`better-auth`](better-auth)\n[`drizzle`](drizzle)\n[`eslint`](eslint)\n[`mcp`](mcp)\n[`mdsvex`](mdsvex)\n[`paraglide`](paraglide)\n[`playwright`](playwright)\n[`prettier`](prettier)\n[`storybook`](storybook)\n[`sveltekit-adapter`](sveltekit-adapter)\n[`tailwindcss`](tailwind)\n[`vitest`](vitest)","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv add","Community add-ons"],"href":"/docs/cli/sv-add#Community-add-ons","content":"[!NOTE]\nCommunity add-ons are currently **experimental**. The API may change. Don't use them in production yet![!NOTE]\nSvelte maintainers have not reviewed community add-ons for malicious code!Community add-ons are npm packages published by the community. Look out for add-ons from your favourite libraries and tools. (soon) Many developers are building sv add-ons to make their integrations a one-liner. You can find them on npmx by searching for the keyword: sv-add.# Install a community add-on by org name (it will look at @org/sv)\nnpx sv add @supacool\n\n# Use a local add-on (for development or internal use)\nnpx sv add file:../path/to/my-addon\n\n# Mix and match official and community add-ons\nnpx sv add eslint @supacool\n\n# Also works when creating a new project directly\nnpx sv create --add eslint @supacool[!NOTE]\nOn Windows PowerShell, `@` is a special character that should be escaped with single quotes. For example: `npx sv add '@supacool'`.Want to create your own? Check the Add-on Docs.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check"],"href":"/docs/cli/sv-check","content":"sv check finds errors and warnings in your project, such as:unused CSS\naccessibility hints\nJavaScript/TypeScript compiler errorsRequires Node 16 or later.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Installation"],"href":"/docs/cli/sv-check#Installation","content":"You will need to have the svelte-check package installed in your project:npm i -D svelte-check","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Usage"],"href":"/docs/cli/sv-check#Usage","content":"npx sv check","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options"],"href":"/docs/cli/sv-check#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--workspace <path>"],"href":"/docs/cli/sv-check#Options-workspace-path","content":"Path to your workspace. All subdirectories except node_modules and those listed in --ignore are checked.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--output <format>"],"href":"/docs/cli/sv-check#Options-output-format","content":"How to display errors and warnings. See machine-readable output.`human`\n`human-verbose`\n`machine`\n`machine-verbose`","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--watch"],"href":"/docs/cli/sv-check#Options-watch","content":"Keeps the process alive and watches for changes.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--preserveWatchOutput"],"href":"/docs/cli/sv-check#Options-preserveWatchOutput","content":"Prevents the screen from being cleared in watch mode.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--tsconfig <path>"],"href":"/docs/cli/sv-check#Options-tsconfig-path","content":"Pass a path to a tsconfig or jsconfig file. The path can be relative to the workspace path or absolute. Doing this means that only files matched by the files/include/exclude pattern of the config file are diagnosed. It also means that errors from TypeScript and JavaScript files are reported. If not given, will traverse upwards from the project directory looking for the next jsconfig/tsconfig.json file.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--no-tsconfig"],"href":"/docs/cli/sv-check#Options-no-tsconfig","content":"Use this if you only want to check the Svelte files found in the current directory and below and ignore any .js/.ts files (they will not be type-checked)","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--ignore <paths>"],"href":"/docs/cli/sv-check#Options-ignore-paths","content":"Files/folders to ignore, relative to workspace root. Paths should be comma-separated and quoted. Example:npx sv check --ignore \"dist,build\"\nOnly has an effect when used in conjunction with --no-tsconfig. When used in conjunction with --tsconfig, this will only have effect on the files watched, not on the files that are diagnosed, which is then determined by the tsconfig.json.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--fail-on-warnings"],"href":"/docs/cli/sv-check#Options-fail-on-warnings","content":"If provided, warnings will cause sv check to exit with an error code.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--compiler-warnings <warnings>"],"href":"/docs/cli/sv-check#Options-compiler-warnings-warnings","content":"A quoted, comma-separated list of code:behaviour pairs where code is a compiler warning code and behaviour is either ignore or error:npx sv check --compiler-warnings \"css_unused_selector:ignore,a11y_missing_attribute:error\"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--diagnostic-sources <sources>"],"href":"/docs/cli/sv-check#Options-diagnostic-sources-sources","content":"A quoted, comma-separated list of sources that should run diagnostics on your code. By default, all are active:\n`js` (includes TypeScript)\n`svelte`\n`css`Example:npx sv check --diagnostic-sources \"js,svelte\"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Options","--threshold <level>"],"href":"/docs/cli/sv-check#Options-threshold-level","content":"Filters the diagnostics:`warning` (default) — both errors and warnings are shown\n`error` — only errors are shown","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Troubleshooting"],"href":"/docs/cli/sv-check#Troubleshooting","content":"See the language-tools documentation for more information on preprocessor setup and other troubleshooting.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Machine-readable output"],"href":"/docs/cli/sv-check#Machine-readable-output","content":"Setting the --output to machine or machine-verbose will format output in a way that is easier to read\nby machines, e.g. inside CI pipelines, for code quality checks, etc.Each row corresponds to a new record. Rows are made up of columns that are separated by a\nsingle space character. The first column of every row contains a timestamp in milliseconds\nwhich can be used for monitoring purposes. The second column gives us the \"row type\", based\non which the number and types of subsequent columns may differ.The first row is of type START and contains the workspace folder (wrapped in quotes). Example:1590680325583 START \"/home/user/language-tools/packages/language-server/test/plugins/typescript/testfiles\"Any number of ERROR or WARNING records may follow. Their structure is identical and depends on the output argument.If the argument is machine it will tell us the filename, the starting line and column numbers, and the error message. The filename is relative to the workspace directory. The filename and the message are both wrapped in quotes. Example:1590680326283 ERROR \"codeactions.svelte\" 1:16 \"Cannot find module 'blubb' or its corresponding type declarations.\"\n1590680326778 WARNING \"imported-file.svelte\" 0:37 \"Component has unused export property 'prop'. If it is for external reference only, please consider using `export const prop`\"If the argument is machine-verbose it will tell us the filename, the starting line and column numbers, the ending line and column numbers, the error message, the code of diagnostic, the human-friendly description of the code and the human-friendly source of the diagnostic (eg. svelte/typescript). The filename is relative to the workspace directory. Each diagnostic is represented as an ndjson line prefixed by the timestamp of the log. Example:1590680326283 {\"type\":\"ERROR\",\"fn\":\"codeaction.svelte\",\"start\":{\"line\":1,\"character\":16},\"end\":{\"line\":1,\"character\":23},\"message\":\"Cannot find module 'blubb' or its corresponding type declarations.\",\"code\":2307,\"source\":\"js\"}\n1590680326778 {\"type\":\"WARNING\",\"filename\":\"imported-file.svelte\",\"start\":{\"line\":0,\"character\":37},\"end\":{\"line\":0,\"character\":51},\"message\":\"Component has unused export property 'prop'. If it is for external reference only, please consider using `export\nconst prop`\",\"code\":\"unused-export-let\",\"source\":\"svelte\"}The output concludes with a COMPLETED message that summarizes total numbers of files, errors and warnings that were encountered during the check. Example:1590680326807 COMPLETED 20 FILES 21 ERRORS 1 WARNINGS 3 FILES_WITH_PROBLEMSIf the application experiences a runtime error, this error will appear as a FAILURE record. Example:1590680328921 FAILURE \"Connection closed\"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","Credits"],"href":"/docs/cli/sv-check#Credits","content":"Vue's [VTI](https://github.com/vuejs/vetur/tree/master/vti) which laid the foundation for `svelte-check`","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","FAQ"],"href":"/docs/cli/sv-check#FAQ","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv check","FAQ","Why is there no option to only check specific files (for example only staged files)?"],"href":"/docs/cli/sv-check#FAQ-Why-is-there-no-option-to-only-check-specific-files-(for-example-only-staged-files)","content":"svelte-check needs to 'see' the whole project for checks to be valid. Suppose you renamed a component prop but didn't update any of the places where the prop is used — the usage sites are all errors now, but you would miss them if checks only ran on changed files.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate"],"href":"/docs/cli/sv-migrate","content":"sv migrate migrates Svelte(Kit) codebases. It delegates to the `svelte-migrate` package.Some migrations may annotate your codebase with tasks for completion that you can find by searching for @migration.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Usage"],"href":"/docs/cli/sv-migrate#Usage","content":"npx sv migrateYou can also specify a migration directly via the CLI:npx sv migrate [migration]","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations"],"href":"/docs/cli/sv-migrate#Migrations","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","app-state"],"href":"/docs/cli/sv-migrate#Migrations-app-state","content":"Migrates $app/stores usage to $app/state in .svelte files. See the migration guide for more details.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","svelte-5"],"href":"/docs/cli/sv-migrate#Migrations-svelte-5","content":"Upgrades a Svelte 4 app to use Svelte 5, and updates individual components to use runes and other Svelte 5 syntax (see migration guide).","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","self-closing-tags"],"href":"/docs/cli/sv-migrate#Migrations-self-closing-tags","content":"Replaces all the self-closing non-void elements in your .svelte files. See the pull request for more details.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","svelte-4"],"href":"/docs/cli/sv-migrate#Migrations-svelte-4","content":"Upgrades a Svelte 3 app to use Svelte 4 (see migration guide).","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","sveltekit-2"],"href":"/docs/cli/sv-migrate#Migrations-sveltekit-2","content":"Upgrades a SvelteKit 1 app to SvelteKit 2 (see migration guide).","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","package"],"href":"/docs/cli/sv-migrate#Migrations-package","content":"Upgrades a library using @sveltejs/package version 1 to version 2. See the pull request for more details.","rank":null},{"breadcrumbs":["Docs","CLI","Commands","sv migrate","Migrations","routes"],"href":"/docs/cli/sv-migrate#Migrations-routes","content":"Upgrades a pre-release SvelteKit app to use the filesystem routing conventions in SvelteKit 1. See the pull request for more details.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","better-auth"],"href":"/docs/cli/better-auth","content":"Better Auth is a framework-agnostic authentication library for TypeScript.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","better-auth","Usage"],"href":"/docs/cli/better-auth#Usage","content":"npx sv add better-auth","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","better-auth","What you get"],"href":"/docs/cli/better-auth#What-you-get","content":"a complete auth setup for SvelteKit with Drizzle as the database adapter\nemail/password authentication enabled by default\noptional demo registration and login pages","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","better-auth","Options"],"href":"/docs/cli/better-auth#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","better-auth","Options","demo"],"href":"/docs/cli/better-auth#Options-demo","content":"Which demo pages to include. Available values: password (Email & Password), github (GitHub OAuth).# Email & Password only (default)\nnpx sv add better-auth=\"demo:password\"\n\n# GitHub OAuth only\nnpx sv add better-auth=\"demo:github\"\n\n# Both Email & Password and GitHub OAuth\nnpx sv add better-auth=\"demo:password,github\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle"],"href":"/docs/cli/drizzle","content":"Drizzle ORM is a TypeScript ORM offering both relational and SQL-like query APIs, and which is serverless-ready by design.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","Usage"],"href":"/docs/cli/drizzle#Usage","content":"npx sv add drizzle","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","What you get"],"href":"/docs/cli/drizzle#What-you-get","content":"a setup that keeps your database access in SvelteKit's server files\nan `.env` file to store your credentials\ncompatibility with the Better Auth add-on\nan optional Docker configuration to help with running a local database","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","Options"],"href":"/docs/cli/drizzle#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","Options","database"],"href":"/docs/cli/drizzle#Options-database","content":"Which database variant to use:`postgresql` — the most popular open source database\n`mysql` — another popular open source database\n`sqlite` — file-based database not requiring a database servernpx sv add drizzle=\"database:postgresql\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","Options","client"],"href":"/docs/cli/drizzle#Options-client","content":"The SQL client to use, depends on database:For `postgresql`: `postgres.js`, `neon`,\nFor `mysql`: `mysql2`, `planetscale`\nFor `sqlite`: `better-sqlite3`, `libsql`, `turso`npx sv add drizzle=\"database:postgresql+client:postgres.js\"Drizzle is compatible with well over a dozen database drivers. We just offer a few of the most common ones here for simplicity, but if you'd like to use another one you can choose one as a placeholder and swap it out for another after setup by choosing from Drizzle's full list of compatible drivers.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","drizzle","Options","docker"],"href":"/docs/cli/drizzle#Options-docker","content":"Whether to add Docker Compose configuration. Only available for `database` postgresql or mysqlnpx sv add drizzle=\"database:postgresql+client:postgres.js+docker:yes\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","eslint"],"href":"/docs/cli/eslint","content":"ESLint finds and fixes problems in your code.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","eslint","Usage"],"href":"/docs/cli/eslint#Usage","content":"npx sv add eslint","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","eslint","What you get"],"href":"/docs/cli/eslint#What-you-get","content":"the relevant packages installed including `eslint-plugin-svelte`\nan `eslint.config.js` file\nupdated `.vscode/extensions.json`\nconfigured to work with TypeScript and `prettier` if you're using those packages","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp"],"href":"/docs/cli/mcp","content":"Svelte MCP can help your LLM write better Svelte code.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp","Usage"],"href":"/docs/cli/mcp#Usage","content":"npx sv add mcp","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp","What you get"],"href":"/docs/cli/mcp#What-you-get","content":"An MCP configuration for [local](https://svelte.dev/docs/ai/local-setup) or [remote](https://svelte.dev/docs/ai/remote-setup) setup\nA [README for agents](https://agents.md/) to help you use the MCP server effectively","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp","Options"],"href":"/docs/cli/mcp#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp","Options","ide"],"href":"/docs/cli/mcp#Options-ide","content":"The IDE you want to use like 'claude-code', 'cursor', 'gemini', 'opencode', 'vscode', 'other'.npx sv add mcp=\"ide:cursor,vscode\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mcp","Options","setup"],"href":"/docs/cli/mcp#Options-setup","content":"The setup you want to use.npx sv add mcp=\"setup:local\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mdsvex"],"href":"/docs/cli/mdsvex","content":"mdsvex is a markdown preprocessor for Svelte components - basically MDX for Svelte. It allows you to use Svelte components in your markdown, or markdown in your Svelte components.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mdsvex","Usage"],"href":"/docs/cli/mdsvex#Usage","content":"npx sv add mdsvex","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","mdsvex","What you get"],"href":"/docs/cli/mdsvex#What-you-get","content":"mdsvex installed and configured in your `svelte.config.js`","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide"],"href":"/docs/cli/paraglide","content":"Paraglide from Inlang is a compiler-based i18n library that emits tree-shakable message functions with small bundle sizes, no async waterfalls, full type-safety, and more.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide","Usage"],"href":"/docs/cli/paraglide#Usage","content":"npx sv add paraglide","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide","What you get"],"href":"/docs/cli/paraglide#What-you-get","content":"Inlang project settings\nparaglide Vite plugin\nSvelteKit `reroute` and `handle` hooks\n`text-direction` and `lang` attributes in `app.html`\nupdated `.gitignore`\nan optional demo page showing how to use paraglide","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide","Options"],"href":"/docs/cli/paraglide#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide","Options","languageTags"],"href":"/docs/cli/paraglide#Options-languageTags","content":"The languages you'd like to support specified as IETF BCP 47 language tags.npx sv add paraglide=\"languageTags:en,es\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","paraglide","Options","demo"],"href":"/docs/cli/paraglide#Options-demo","content":"Whether to generate an optional demo page showing how to use paraglide.npx sv add paraglide=\"demo:yes\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","playwright"],"href":"/docs/cli/playwright","content":"Playwright browser testing.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","playwright","Usage"],"href":"/docs/cli/playwright#Usage","content":"npx sv add playwright","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","playwright","What you get"],"href":"/docs/cli/playwright#What-you-get","content":"scripts added in your `package.json`\na Playwright config file\nan updated `.gitignore`\na demo test","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","prettier"],"href":"/docs/cli/prettier","content":"Prettier is an opinionated code formatter.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","prettier","Usage"],"href":"/docs/cli/prettier#Usage","content":"npx sv add prettier","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","prettier","What you get"],"href":"/docs/cli/prettier#What-you-get","content":"scripts in your `package.json`\n`.prettierignore` and `.prettierrc` files\nupdates to your eslint config if you're using that package","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","storybook"],"href":"/docs/cli/storybook","content":"Storybook is a frontend component workshop.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","storybook","Usage"],"href":"/docs/cli/storybook#Usage","content":"npx sv add storybook","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","storybook","What you get"],"href":"/docs/cli/storybook#What-you-get","content":"`npx storybook init` run for you from the same convenient `sv` CLI used for all other add-ons\n[Storybook for SvelteKit](https://storybook.js.org/docs/get-started/frameworks/sveltekit) or [Storybook for Svelte & Vite](https://storybook.js.org/docs/get-started/frameworks/svelte-vite) with default config provided, easy mocking of many SvelteKit modules, automatic link handling, and more.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter"],"href":"/docs/cli/sveltekit-adapter","content":"SvelteKit adapters allow you to deploy your site to numerous platforms. This add-on allows you to configure officially provided SvelteKit adapters, but a number of community-provided adapters are also available.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter","Usage"],"href":"/docs/cli/sveltekit-adapter#Usage","content":"npx sv add sveltekit-adapter","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter","What you get"],"href":"/docs/cli/sveltekit-adapter#What-you-get","content":"the chosen SvelteKit adapter installed and configured in your `svelte.config.js`","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter","Options"],"href":"/docs/cli/sveltekit-adapter#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter","Options","adapter"],"href":"/docs/cli/sveltekit-adapter#Options-adapter","content":"Which SvelteKit adapter to use:`auto` — [`@sveltejs/adapter-auto`](/docs/kit/adapter-auto) automatically chooses the proper adapter to use, but is less configurable\n`node` — [`@sveltejs/adapter-node`](/docs/kit/adapter-node) generates a standalone Node server\n`static` — [`@sveltejs/adapter-static`](/docs/kit/adapter-static) allows you to use SvelteKit as a static site generator (SSG)\n`vercel` — [`@sveltejs/adapter-vercel`](/docs/kit/adapter-vercel) allows you to deploy to Vercel\n`cloudflare` — [`@sveltejs/adapter-cloudflare`](/docs/kit/adapter-cloudflare) allows you to deploy to Cloudflare\n`netlify` — [`@sveltejs/adapter-netlify`](/docs/kit/adapter-netlify) allows you to deploy to Netlifynpx sv add sveltekit-adapter=\"adapter:node\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","sveltekit-adapter","Options","cloudflare target"],"href":"/docs/cli/sveltekit-adapter#Options-cloudflare-target","content":"Whether to deploy to Cloudflare Workers or Pages. Only available for cloudflare adapter.npx sv add sveltekit-adapter=\"adapter:cloudflare+cfTarget:workers\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","tailwindcss"],"href":"/docs/cli/tailwind","content":"Tailwind CSS allows you to rapidly build modern websites without ever leaving your HTML.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","tailwindcss","Usage"],"href":"/docs/cli/tailwind#Usage","content":"npx sv add tailwindcss","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","tailwindcss","What you get"],"href":"/docs/cli/tailwind#What-you-get","content":"Tailwind setup following the [Tailwind for SvelteKit guide](https://tailwindcss.com/docs/installation/framework-guides/sveltekit)\nTailwind Vite plugin\nupdated `layout.css` and `+layout.svelte` (for SvelteKit) or `app.css` and `App.svelte` (for non-SvelteKit Vite apps)\nintegration with `prettier` if using that package","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","tailwindcss","Options"],"href":"/docs/cli/tailwind#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","tailwindcss","Options","plugins"],"href":"/docs/cli/tailwind#Options-plugins","content":"Which plugin to use:`typography` — [`@tailwindcss/typography`](https://github.com/tailwindlabs/tailwindcss-typography)\n`forms` — [`@tailwindcss/forms`](https://github.com/tailwindlabs/tailwindcss-forms)npx sv add tailwindcss=\"plugins:typography\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","vitest"],"href":"/docs/cli/vitest","content":"Vitest is a Vite-native testing framework.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","vitest","Usage"],"href":"/docs/cli/vitest#Usage","content":"npx sv add vitest","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","vitest","What you get"],"href":"/docs/cli/vitest#What-you-get","content":"the relevant packages installed and scripts added to your `package.json`\nclient/server-aware testing setup for Svelte in your Vite config file\ndemo tests","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","vitest","Options"],"href":"/docs/cli/vitest#Options","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","vitest","Options","usages"],"href":"/docs/cli/vitest#Options-usages","content":"Which test types to use:`unit` — unit testing\n`component` — component testingnpx sv add vitest=\"usages:unit,component\"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]"],"href":"/docs/cli/community","content":"[!NOTE]\nCommunity add-ons are currently **experimental**. The API may change. Don't use them in production yet!This guide covers how to create, test, and publish community add-ons for sv.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Quick start"],"href":"/docs/cli/community#Quick-start","content":"The easiest way to create an add-on is by using the addon template:npx sv create --template addon [path]The newly created project will have a README.md and CONTRIBUTING.md to guide you along.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Project structure"],"href":"/docs/cli/community#Project-structure","content":"Typically, an add-on looks like this:import { transforms } from '@sveltejs/sv-utils';\nimport { defineAddon, defineAddonOptions } from 'sv';\n\nexport default defineAddon({\n\tid: 'addon-name',\n\n\tshortDescription: 'a better description of what your addon does ;)',\n\n\toptions: defineAddonOptions()\n\t\t.add('who', {\n\t\t\tquestion: 'To whom should the addon say hello?',\n\t\t\ttype: 'string' // boolean | number | select | multiselect\n\t\t})\n\t\t.build(),\n\n\tsetup: ({ dependsOn, isKit, unsupported }) => {\n\t\tif (!isKit) unsupported('Requires SvelteKit');\n\t\tdependsOn('vitest');\n\t},\n\n\trun: ({ isKit, cancel, sv, options, file, language, directory }) => {\n\t\t// Add \"Hello [who]!\" to the root page\n\t\tsv.file(\n\t\t\tdirectory.kitRoutes + '/+page.svelte',\n\t\t\ttransforms.svelte(({ ast, svelte }) => {\n\t\t\t\tsvelte.addFragment(ast, `<p>Hello ${options.who}!</p>`);\n\t\t\t})\n\t\t);\n\t},\n\n\tnextSteps: ({ options }) => ['enjoy the add-on!']\n});The Svelte CLI is split into two packages with a clear boundary:[**`sv`**](sv) = **where and when** to do it. It owns paths, workspace detection, dependency tracking, and file I/O. The engine orchestrates add-on execution.\n[**`@sveltejs/sv-utils`**](sv-utils) = **what** to do to content. It provides parsers, language tooling, and typed transforms. Everything here is pure - no file system, no workspace awareness.This separation means transforms are testable without a workspace and composable across add-ons.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Development"],"href":"/docs/cli/community#Development","content":"You can run your add-on locally using the file: protocol:cd /path/to/test-project\nnpx sv add file:../path/to/my-addonThis allows you to iterate quickly without publishing to npm.The file: protocol also works for custom or private add-ons that you don't intend to publish - for example, to standardize project setup across your team or organization.[!NOTE]\nThe `demo-add` script automatically builds your add-on before running it.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Testing"],"href":"/docs/cli/community#Testing","content":"The sv/testing module provides utilities for testing your add-on. createSetupTest is a factory that takes your vitest imports and returns a setupTest function. It creates real SvelteKit projects from templates, runs your add-on, and gives you access to the resulting files.import { expect } from '@playwright/test';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createSetupTest } from 'sv/testing';\nimport * as vitest from 'vitest';\nimport addon from './index.js';\n\nconst { test, testCases } = createSetupTest(vitest)(\n\t{ addon },\n\t{\n\t\tkinds: [\n\t\t\t{\n\t\t\t\ttype: 'default',\n\t\t\t\toptions: {\n\t\t\t\t\t'your-addon-name': { who: 'World' }\n\t\t\t\t}\n\t\t\t}\n\t\t],\n\t\tfilter: (testCase) => testCase.variant.includes('kit'),\n\t\tbrowser: false\n\t}\n);\n\ntest.concurrent.for(testCases)('my-addon $kind.type $variant', async (testCase, ctx) => {\n\tconst cwd = ctx.cwd(testCase);\n\n\tconst page = fs.readFileSync(path.resolve(cwd, 'src/routes/+page.svelte'), 'utf8');\n\texpect(page).toContain('Hello World!');\n});Your vitest.config.js must include the global setup from sv/testing:import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n\ttest: {\n\t\tinclude: ['tests/**/*.test.{js,ts}'],\n\t\tglobalSetup: ['tests/setup/global.js']\n\t}\n});And the global test setup script tests/setup/global.js:import { fileURLToPath } from 'node:url';\nimport { setupGlobal } from 'sv/testing';\n\nconst TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url));\n\nexport default setupGlobal({ TEST_DIR });","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing"],"href":"/docs/cli/community#Publishing","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","Bundling"],"href":"/docs/cli/community#Publishing-Bundling","content":"Community add-ons are bundled with tsdown into a single file. Everything is bundled except sv. (It is a peer dependency provided at runtime.)","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","package.json"],"href":"/docs/cli/community#Publishing-package.json","content":"Your add-on must have sv as a peer dependency and no dependencies in package.json:{\n\t\"name\": \"@my-org/sv\",\n\t\"version\": \"1.0.0\",\n\t\"type\": \"module\",\n\t// bundled entrypoint (tsdown outputs .mjs for ESM)\n\t\"exports\": {\n\t\t\".\": { \"default\": \"./dist/index.mjs\" }\n\t},\n\t\"publishConfig\": {\n\t\t\"access\": \"public\"\n\t},\n\t// cannot have dependencies\n\t\"dependencies\": {},\n\t\"peerDependencies\": {\n\t\t// minimum version required to run by this add-on\n\t\t\"sv\": \"^0.13.0\"\n\t},\n\t// Add the \"sv-add\" keyword so users can discover your add-on\n\t\"keywords\": [\"sv-add\", \"svelte\", \"sveltekit\"]\n}","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","Naming convention"],"href":"/docs/cli/community#Publishing-Naming-convention","content":"","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","packages names"],"href":"/docs/cli/community#Publishing-packages-names","content":"If you name your package @my-org/sv, users can install it by typing just the org handle:npx sv add @my-orgIt's also possible to publish like @my-org/core, just users will need to type the full package name.npx sv add @my-org/coreUsers can also ask for a specific version:npx sv add @my-org/sv@1.2.3When no version is specified, latest is used.[!NOTE]\nUnscoped packages are not supported yet","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","export options"],"href":"/docs/cli/community#Publishing-export-options","content":"sv first tries to import your-package/sv, then falls back to the default export. This means you have two options:**Default export** (for dedicated add-on packages):\n\n```json\n{\n    \"exports\": {\n        \".\": \"./src/index.js\"\n    }\n}\n```\n\n**`./sv` export** (for packages that also export other functionality):\n```json\n{\n    \"exports\": {\n        \".\": \"./src/main.js\",\n        \"./sv\": \"./src/addon.js\"\n    }\n}\n```","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Publishing","Publish to npm"],"href":"/docs/cli/community#Publishing-Publish-to-npm","content":"npm login\nnpm publish`prepublishOnly` automatically runs the build before publishing.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Next steps"],"href":"/docs/cli/community#Next-steps","content":"You can optionally display guidance in the console after your add-on runs:import { color } from '@sveltejs/sv-utils';\n\nexport default defineAddon({\n\t// ...\n\n\tnextSteps: ({ options }) => [\n\t\t`Run ${color.command('npm run dev')} to start developing`,\n\t\t`Check out the docs at https://...`\n\t]\n});","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Version compatibility"],"href":"/docs/cli/community#Version-compatibility","content":"Your add-on should specify a minimum sv version in peerDependencies. Your users will get a compatibility warning if their sv version has a different major version than what was specified.","rank":null},{"breadcrumbs":["Docs","CLI","Add-ons","[create your own]","Examples"],"href":"/docs/cli/community#Examples","content":"See the official add-on source code for some real world examples.","rank":null},{"breadcrumbs":["Docs","CLI","API","sv"],"href":"/docs/cli/sv","content":"sv exposes a programmatic API for creating projects and running add-ons.","rank":null},{"breadcrumbs":["Docs","CLI","API","sv","defineAddon"],"href":"/docs/cli/sv#defineAddon","content":"Creates an add-on definition. See create your own for a full guide.import { transforms } from '@sveltejs/sv-utils';\nimport { defineAddon, defineAddonOptions } from 'sv';\n\nexport default defineAddon({\n\tid: 'my-addon',\n\toptions: defineAddonOptions().build(),\n\n\t// called before run — declare dependencies and environment requirements\n\tsetup: ({ dependsOn, unsupported, isKit }) => {\n\t\tif (!isKit) unsupported('Requires SvelteKit');\n\t\tdependsOn('eslint');\n\t},\n\n\t// the actual work — add files, edit files, declare dependencies\n\trun: ({ sv, options, cancel }) => {\n\t\t// add a dependency\n\t\tsv.devDependency('my-lib', '^1.0.0');\n\n\t\t// create or edit files using transforms from @sveltejs/sv-utils\n\t\tsv.file('src/lib/foo.ts', (content) => {\n\t\t\treturn 'export const foo = true;';\n\t\t});\n\n\t\tsv.file(\n\t\t\t'src/routes/+page.svelte',\n\t\t\ttransforms.svelte(({ ast, svelte }) => {\n\t\t\t\tsvelte.addFragment(ast, '<p>Hello!</p>');\n\t\t\t})\n\t\t);\n\n\t\t// cancel at any point if something is wrong\n\t\t// cancel('reason');\n\t},\n\n\t// displayed after the add-on runs\n\tnextSteps: ({ options }) => ['Run `npm run dev` to get started']\n});The sv object in run provides file, dependency, devDependency, and execute. For file transforms (AST-based editing of scripts, Svelte components, CSS, JSON, etc.) and package manager helpers, see `@sveltejs/sv-utils`.","rank":null},{"breadcrumbs":["Docs","CLI","API","sv","defineAddonOptions"],"href":"/docs/cli/sv#defineAddonOptions","content":"Builder for add-on options. Chained with .add() and finalized with .build().import { defineAddonOptions } from 'sv';\n\nconst options = defineAddonOptions()\n\t.add('database', {\n\t\tquestion: 'Which database?',\n\t\ttype: 'select',\n\t\tdefault: 'postgresql',\n\t\toptions: [\n\t\t\t{ value: 'postgresql' },\n\t\t\t{ value: 'mysql' },\n\t\t\t{ value: 'sqlite' }\n\t\t]\n\t})\n\t.add('docker', {\n\t\tquestion: 'Add a docker-compose file?',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\t// only ask when database is not sqlite\n\t\tcondition: (opts) => opts.database !== 'sqlite'\n\t})\n\t.build();Options are asked in order. The condition callback receives the answers collected so far — return false to skip the question (its value will be undefined).","rank":null},{"breadcrumbs":["Docs","CLI","API","sv","create"],"href":"/docs/cli/sv#create","content":"Programmatically create a new Svelte project.import { create } from 'sv';\n\ncreate('./my-app', {\n\tname: 'my-app',\n\ttemplate: 'minimal',\n\ttypes: 'typescript'\n});","rank":null},{"breadcrumbs":["Docs","CLI","API","sv","add"],"href":"/docs/cli/sv#add","content":"Programmatically run add-ons against an existing project.import { add, officialAddons } from 'sv';\n\nawait add({\n\tcwd: './my-app',\n\taddons: { prettier: officialAddons.prettier },\n\toptions: { prettier: {} },\n\tpackageManager: 'npm'\n});","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils"],"href":"/docs/cli/sv-utils","content":"[!NOTE]\n`@sveltejs/sv-utils` is currently **experimental**. The API may change.@sveltejs/sv-utils is an add-on utilty for parsing, transforming, and generating code..npm install -D @sveltejs/sv-utils","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms"],"href":"/docs/cli/sv-utils#transforms","content":"transforms is a collection of parser-aware functions that lets you modify the files via abstract syntax tree (AST). It accepts a callback function. The return value is designed to be be passed directly into sv.file(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as Svelte because you never call a parser yourself.Each transform injects relevant utilities into the callback, so you only need one import:import { transforms } from '@sveltejs/sv-utils';\n\ntransforms.script(/* ... */);\ntransforms.svelte(/* ... */);\n// ...","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.script"],"href":"/docs/cli/sv-utils#transforms-transforms.script","content":"Transform a JavaScript/TypeScript file. The callback receives { ast, comments, content, js }. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\tfile.viteConfig,\n\ttransforms.script(({ ast, js }) => {\n\t\tjs.imports.addDefault(ast, { as: 'foo', from: 'foo' });\n\t\tjs.vite.addPlugin(ast, { code: 'foo()' });\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.svelte"],"href":"/docs/cli/sv-utils#transforms-transforms.svelte","content":"Transform a Svelte component. The callback receives { ast, content, svelte, js }. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\tlayoutPath,\n\ttransforms.svelte(({ ast, svelte }) => {\n\t\tsvelte.addFragment(ast, '<Foo />');\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.svelteScript"],"href":"/docs/cli/sv-utils#transforms-transforms.svelteScript","content":"Transform a Svelte component with a <script> block guaranteed. Pass { language } as the first argument. The callback receives { ast, content, svelte, js } where ast.instance is always non-null. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\tlayoutPath,\n\ttransforms.svelteScript({ language: 'ts' }, ({ ast, svelte, js }) => {\n\t\tjs.imports.addDefault(ast.instance.content, { as: 'Foo', from: './Foo.svelte' });\n\t\tsvelte.addFragment(ast, '<Foo />');\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.css"],"href":"/docs/cli/sv-utils#transforms-transforms.css","content":"Transform a CSS file. The callback receives { ast, content, css }. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\tfile.stylesheet,\n\ttransforms.css(({ ast, css }) => {\n\t\tcss.addAtRule(ast, { name: 'import', params: \"'tailwindcss'\" });\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.json"],"href":"/docs/cli/sv-utils#transforms-transforms.json","content":"Transform a JSON file. Mutate the data object directly. The callback receives { data, content, json }. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\tfile.typeConfig,\n\ttransforms.json(({ data }) => {\n\t\tdata.compilerOptions ??= {};\n\t\tdata.compilerOptions.strict = true;\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.yaml` / transforms.toml`"],"href":"/docs/cli/sv-utils#transforms-transforms.yaml-transforms.toml","content":"Same pattern as transforms.json, for YAML and TOML files respectively. The callback receives { data, content }.","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","transforms.text"],"href":"/docs/cli/sv-utils#transforms-transforms.text","content":"Transform a plain text file (.env, .gitignore, etc.). No parser - string in, string out. The callback receives { content, text }. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\t'.env',\n\ttransforms.text(({ content }) => {\n\t\treturn content + '\\nDATABASE_URL=\"file:local.db\"';\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","Aborting a transform"],"href":"/docs/cli/sv-utils#transforms-Aborting-a-transform","content":"Return false from any transform callback to abort - the original content is returned unchanged. \nimport { transforms } from '@sveltejs/sv-utils';\n\nsv.file(\n\t'eslint.config.js',\n\ttransforms.script(({ ast, js }) => {\n\t\tconst { value: existing } = js.exports.createDefault(ast, { fallback: myConfig });\n\t\tif (existing !== myConfig) {\n\t\t\t// config already exists, don't touch it\n\t\t\treturn false;\n\t\t}\n\t\t// ... continue modifying ast\n\t})\n);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","Standalone usage & testing"],"href":"/docs/cli/sv-utils#transforms-Standalone-usage-testing","content":"Transforms are curried functions - call them with the callback, then apply to content:import { transforms } from '@sveltejs/sv-utils';\n\nconst transform = transforms.script(({ ast, js }) => {\n\tjs.imports.addDefault(ast, { as: 'foo', from: 'foo' });\n});\nconst result = transform('export default {}');","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","transforms","Composability"],"href":"/docs/cli/sv-utils#transforms-Composability","content":"For cases where you need to mix and match transforms and raw edits, use sv.file with a content callback and invoke the curried transform manually: \nsv.file(path, (content) => {\n\t// curried\n\tconst transform = transforms.script(({ ast, js }) => {\n\t\tjs.imports.addDefault(ast, { as: 'foo', from: 'bar' });\n\t});\n\n\t// parser manipulation\n\tcontent = transform(content);\n\n\t// raw string manipulation\n\tcontent = content.replace('foo', 'baz');\n\n\treturn content;\n});Add-ons can also export reusable transform functions: \nimport { transforms } from '@sveltejs/sv-utils';\n\n// reusable - export from your package\nexport const addFooImport = transforms.svelte(({ ast, svelte, js }) => {\n\tsvelte.ensureScript(ast, { language });\n\tjs.imports.addDefault(ast.instance.content, { as: 'Foo', from: './Foo.svelte' });\n});sv.file('+page.svelte', addFooImport);\nsv.file('index.svelte', addFooImport);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","Parsers (low-level)"],"href":"/docs/cli/sv-utils#Parsers-(low-level)","content":"transforms will fit most users needs (e.g., conditional parsing, error handling around the parser). If not, parse is a low-level API available to you: \nimport { parse } from '@sveltejs/sv-utils';\n\nconst { ast, generateCode } = parse.script(content);\nconst { ast, generateCode } = parse.svelte(content);\nconst { ast, generateCode } = parse.css(content);\nconst { data, generateCode } = parse.json(content);\nconst { data, generateCode } = parse.yaml(content);\nconst { data, generateCode } = parse.toml(content);\nconst { ast, generateCode } = parse.html(content);","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","Language tooling"],"href":"/docs/cli/sv-utils#Language-tooling","content":"Namespaced helpers for AST manipulation:**`js.*`** - imports, exports, objects, arrays, variables, functions, vite config helpers, SvelteKit helpers\n**`css.*`** - rules, declarations, at-rules, imports\n**`svelte.*`** - ensureScript, addSlot, addFragment\n**`json.*`** - arrayUpsert, packageScriptsUpsert\n**`html.*`** - attribute manipulation\n**`text.*`** - upsert lines in flat files (.env, .gitignore)","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","Package manager helpers"],"href":"/docs/cli/sv-utils#Package-manager-helpers","content":"","rank":null},{"breadcrumbs":["Docs","CLI","API","sv-utils","Package manager helpers","pnpm.allowBuilds"],"href":"/docs/cli/sv-utils#Package-manager-helpers-pnpm.allowBuilds","content":"Returns a transform for pnpm-workspace.yaml that adds packages to the pnpm \"allow builds\" config. Use with sv.file when the project uses pnpm.The helper detects the installed pnpm version via pnpm --version:pnpm `>= 11`: writes to the unified `allowBuilds` map (`{ pkg: true }`), migrating any legacy `onlyBuiltDependencies` list into the map.\npnpm `< 11`: writes to the legacy `onlyBuiltDependencies` list. \nimport { pnpm } from '@sveltejs/sv-utils';\n\nif (packageManager === 'pnpm') {\n\tsv.file(file.findUp('pnpm-workspace.yaml'), pnpm.allowBuilds('my-native-dep'));\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Introduction"],"href":"/docs/kit/introduction","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Introduction","Before we begin"],"href":"/docs/kit/introduction#Before-we-begin","content":"[!NOTE] If you're new to Svelte or SvelteKit we recommend checking out the [interactive tutorial](/tutorial/kit).\n\nIf you get stuck, reach out for help in the [Discord chatroom](/chat).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Introduction","What is SvelteKit?"],"href":"/docs/kit/introduction#What-is-SvelteKit","content":"SvelteKit is a framework for rapidly developing robust, performant web applications using Svelte. If you're coming from React, SvelteKit is similar to Next. If you're coming from Vue, SvelteKit is similar to Nuxt.To learn more about the kinds of applications you can build with SvelteKit, see the documentation regarding project types.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Introduction","What is Svelte?"],"href":"/docs/kit/introduction#What-is-Svelte","content":"In short, Svelte is a way of writing user interface components — like a navigation bar, comment section, or contact form — that users see and interact with in their browsers. The Svelte compiler converts your components to JavaScript that can be run to render the HTML for the page and to CSS that styles the page. You don't need to know Svelte to understand the rest of this guide, but it will help. If you'd like to learn more, check out the Svelte tutorial.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Introduction","SvelteKit vs Svelte"],"href":"/docs/kit/introduction#SvelteKit-vs-Svelte","content":"Svelte renders UI components. You can compose these components and render an entire page with just Svelte, but you need more than just Svelte to write an entire app.SvelteKit helps you build web apps while following modern best practices and providing solutions to common development challenges. It offers everything from basic functionalities — like a router that updates your UI when a link is clicked — to more advanced capabilities. Its extensive list of features includes build optimizations to load only the minimal required code; offline support; preloading pages before user navigation; configurable rendering to handle different parts of your app on the server via SSR, in the browser through client-side rendering, or at build-time with prerendering; image optimization; and much more. Building an app with all the modern best practices is fiendishly complicated, but SvelteKit does all the boring stuff for you so that you can get on with the creative part.It reflects changes to your code in the browser instantly to provide a lightning-fast and feature-rich development experience by leveraging Vite with a Svelte plugin to do Hot Module Replacement (HMR).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Creating a project"],"href":"/docs/kit/creating-a-project","content":"The easiest way to start building a SvelteKit app is to run npx sv create:npx sv create my-app\ncd my-app\nnpm run devThe first command will scaffold a new project in the my-app directory asking if you'd like to set up some basic tooling such as TypeScript. See the CLI docs for information about these options and the integrations page for pointers on setting up additional tooling. npm run dev will then start the development server on localhost:5173 - make sure you install dependencies before running this if you didn't do so during project creation.There are two basic concepts:Each page of your app is a [Svelte](../svelte) component\nYou create pages by adding files to the `src/routes` directory of your project. These will be server-rendered so that a user's first visit to your app is as fast as possible, then a client-side app takes overTry editing the files to get a feel for how everything works.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Creating a project","Editor setup"],"href":"/docs/kit/creating-a-project#Editor-setup","content":"We recommend using Visual Studio Code (aka VS Code) with the Svelte extension, but support also exists for numerous other editors.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types"],"href":"/docs/kit/project-types","content":"SvelteKit offers configurable rendering, which allows you to build and deploy your project in several different ways. You can build all of the below types of applications and more with SvelteKit. Rendering settings are not mutually exclusive and you may choose the optimal manner with which to render different parts of your application.If you don't have a particular way you'd like to build your application in mind, don't worry! The way your application is built, deployed, and rendered is controlled by which adapter you've chosen and a small amount of configuration and these can always be changed later. The project structure and routing will be the same regardless of the project type that you choose.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Default rendering"],"href":"/docs/kit/project-types#Default-rendering","content":"By default, when a user visits a site, SvelteKit will render the first page with server-side rendering (SSR) and subsequent pages with client-side rendering (CSR). Using SSR for the initial render improves SEO and perceived performance of the initial page load. Client-side rendering then takes over and updates the page without having to rerender common components, which is typically faster and eliminates a flash when navigating between pages. Apps built with this hybrid rendering approach have also been called transitional apps.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Static site generation"],"href":"/docs/kit/project-types#Static-site-generation","content":"You can use SvelteKit as a static site generator (SSG) that fully prerenders your site with static rendering using `adapter-static`. You may also use the prerender option to prerender only some pages and then choose a different adapter with which to dynamically server-render other pages.Tools built solely to do static site generation may scale the prerendering process more efficiently during build when rendering a very large number of pages. When working with very large statically generated sites, you can avoid long build times with Incremental Static Regeneration (ISR) if using `adapter-vercel`. And in contrast to purpose-built SSGs, SvelteKit allows for nicely mixing and matching different rendering types on different pages.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Single-page app"],"href":"/docs/kit/project-types#Single-page-app","content":"Single-page apps (SPAs) exclusively use client-side rendering (CSR). You can build single-page apps (SPAs) with SvelteKit. As with all types of SvelteKit applications, you can write your backend in SvelteKit or another language or framework. If you are building an application with no backend or a separate backend, you can simply skip over and ignore the parts of the docs talking about server files.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Multi-page app"],"href":"/docs/kit/project-types#Multi-page-app","content":"SvelteKit isn't typically used to build traditional multi-page apps. However, in SvelteKit you can remove all JavaScript on a page with `csr = false`, which will render subsequent links on the server, or you can use `data-sveltekit-reload` to render specific links on the server.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Separate backend"],"href":"/docs/kit/project-types#Separate-backend","content":"If your backend is written in another language such as Go, Java, PHP, Ruby, Rust, or C#, there are a couple of ways that you can deploy your application. The most recommended way would be to deploy your SvelteKit frontend separately from your backend utilizing adapter-node or a serverless adapter. Some users prefer not to have a separate process to manage and decide to deploy their application as a single-page app (SPA) served by their backend server, but note that single-page apps have worse SEO and performance characteristics.If you are using an external backend, you can simply skip over and ignore the parts of the docs talking about server files. You may also want to reference the FAQ about how to make calls to a separate backend.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Serverless app"],"href":"/docs/kit/project-types#Serverless-app","content":"SvelteKit apps are simple to run on serverless platforms. The default zero config adapter will automatically run your app on a number of supported platforms or you can use `adapter-vercel`, `adapter-netlify`, or `adapter-cloudflare` to provide platform-specific configuration. And community adapters allow you to deploy your application to almost any serverless environment. Some of these adapters such as `adapter-vercel` and `adapter-netlify` offer an edge option, to support edge rendering for improved latency.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Your own server"],"href":"/docs/kit/project-types#Your-own-server","content":"You can deploy to your own server or VPS using `adapter-node`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Container"],"href":"/docs/kit/project-types#Container","content":"You can use `adapter-node` to run a SvelteKit app within a container such as Docker or LXC.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Library"],"href":"/docs/kit/project-types#Library","content":"You can create a library to be used by other Svelte apps with the `@sveltejs/package` add-on to SvelteKit by choosing the library option when running `sv create`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Offline app"],"href":"/docs/kit/project-types#Offline-app","content":"SvelteKit has full support for service workers allowing you to build many types of applications such as offline apps and progressive web apps.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Mobile app"],"href":"/docs/kit/project-types#Mobile-app","content":"You can turn a SvelteKit SPA into a mobile app with Tauri or Capacitor. Mobile features like the camera, geolocation, and push notifications are available via plugins for both platforms.These mobile development platforms work by starting a local web server and then serving your application like a static host on your phone. You may find `bundleStrategy: 'single'` to be a helpful option to limit the number of requests made. E.g. at the time of writing, the Capacitor local server uses HTTP/1, which limits the number of concurrent connections.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Desktop app"],"href":"/docs/kit/project-types#Desktop-app","content":"You can turn a SvelteKit SPA into a desktop app with Tauri, Wails, or Electron.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Browser extension"],"href":"/docs/kit/project-types#Browser-extension","content":"You can build browser extensions using either `adapter-static` or community adapters specifically tailored towards browser extensions.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project types","Embedded device"],"href":"/docs/kit/project-types#Embedded-device","content":"Because of its efficient rendering, Svelte can be run on low power devices. Embedded devices like microcontrollers and TVs may limit the number of concurrent connections. In order to reduce the number of concurrent requests, you may find `bundleStrategy: 'single'` to be a helpful option in this deployment configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure"],"href":"/docs/kit/project-structure","content":"A typical SvelteKit project looks like this:my-project/\n├ src/\n│ ├ lib/\n│ │ ├ server/\n│ │ │ └ [your server-only lib files]\n│ │ └ [your lib files]\n│ ├ params/\n│ │ └ [your param matchers]\n│ ├ routes/\n│ │ └ [your routes]\n│ ├ app.html\n│ ├ error.html\n│ ├ hooks.client.js\n│ ├ hooks.server.js\n│ ├ service-worker.js\n│ └ instrumentation.server.js\n├ static/\n│ └ [your static assets]\n├ tests/\n│ └ [your tests]\n├ package.json\n├ svelte.config.js\n├ tsconfig.json\n└ vite.config.jsYou'll also find common files like .gitignore and .npmrc (and .prettierrc and eslint.config.js and so on, if you chose those options when running npx sv create).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files"],"href":"/docs/kit/project-structure#Project-files","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","src"],"href":"/docs/kit/project-structure#Project-files-src","content":"The src directory contains the meat of your project. Everything except src/routes and src/app.html is optional.`lib` contains your library code (utilities and components), which can be imported via the [`$lib`]($lib) alias, or packaged up for distribution using [`svelte-package`](packaging)\n- `server` contains your server-only library code. It can be imported by using the [`$lib/server`](server-only-modules) alias. SvelteKit will prevent you from importing these in client code.\n`params` contains any [param matchers](advanced-routing#Matching) your app needs\n`routes` contains the [routes](routing) of your application. You can also colocate other components that are only used within a single route here\n`app.html` is your page template — an HTML document containing the following placeholders:\n- `%sveltekit.head%` — `<link>` and `<script>` elements needed by the app, plus any `<svelte:head>` content\n- `%sveltekit.body%` — the markup for a rendered page. This should live inside a `<div>` or other element, rather than directly inside `<body>`, to prevent bugs caused by browser extensions injecting elements that are then destroyed by the hydration process. SvelteKit will warn you in development if this is not the case\n- `%sveltekit.assets%` — either [`paths.assets`](configuration#paths), if specified, or a relative path to [`paths.base`](configuration#paths)\n- `%sveltekit.nonce%` — a [CSP](configuration#csp) nonce for manually included links and scripts, if used\n- `%sveltekit.env.[NAME]%` - this will be replaced at render time with the `[NAME]` environment variable, which must begin with the [`publicPrefix`](configuration#env) (usually `PUBLIC_`), or be defined as a public variable in `src/env` if using [`experimental.explicitEnvironmentVariables`](environment-variables). It will fallback to `''` if not matched.\n- `%sveltekit.version%` — the app version, which can be specified with the [`version`](configuration#version) configuration\n`error.html` is the page that is rendered when everything else fails. It can contain the following placeholders:\n- `%sveltekit.status%` — the HTTP status\n- `%sveltekit.error.message%` — the error message\n`hooks.client.js` contains your client [hooks](hooks)\n`hooks.server.js` contains your server [hooks](hooks)\n`service-worker.js` contains your [service worker](service-workers)\n`instrumentation.server.js` contains your [observability](observability) setup and instrumentation code\n- Requires adapter support. If your adapter supports it, it is guaranteed to run prior to loading and running your application code.(Whether the project contains .js or .ts files depends on whether you opt to use TypeScript when you create your project.)If you added Vitest when you set up your project, your unit tests will live in the src directory with a .test.js extension.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","static"],"href":"/docs/kit/project-structure#Project-files-static","content":"Any static assets that should be served without any alteration to the name — such as robots.txt — go in here. It's generally preferable to minimize the number of assets in static/ and instead import them. Using an import allows Vite's built-in handling to give a unique name to an asset based on a hash of its contents so that it can be cached.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","tests"],"href":"/docs/kit/project-structure#Project-files-tests","content":"If you added Playwright for browser testing when you set up your project, the tests will live in this directory.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","package.json"],"href":"/docs/kit/project-structure#Project-files-package.json","content":"Your package.json file must include @sveltejs/kit, svelte and vite as devDependencies.When you create a project with npx sv create, you'll also notice that package.json includes \"type\": \"module\". This means that .js files are interpreted as native JavaScript modules with import and export keywords. Legacy CommonJS files need a .cjs file extension.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","svelte.config.js"],"href":"/docs/kit/project-structure#Project-files-svelte.config.js","content":"This file contains your Svelte and SvelteKit configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","tsconfig.json"],"href":"/docs/kit/project-structure#Project-files-tsconfig.json","content":"This file (or jsconfig.json, if you prefer type-checked .js files over .ts files) configures TypeScript, if you added typechecking during npx sv create. Since SvelteKit relies on certain configuration being set a specific way, it generates its own .svelte-kit/tsconfig.json file which your own config extends. To make changes to top-level options such as include and exclude, we recommend extending the generated config; see the `typescript.config` setting for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Project files","vite.config.js"],"href":"/docs/kit/project-structure#Project-files-vite.config.js","content":"A SvelteKit project is really just a Vite project that uses the `@sveltejs/kit/vite` plugin, along with any other Vite configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Other files"],"href":"/docs/kit/project-structure#Other-files","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Project structure","Other files",".svelte-kit"],"href":"/docs/kit/project-structure#Other-files-.svelte-kit","content":"As you develop and build your project, SvelteKit will generate files in a .svelte-kit directory (configurable as `outDir`). You can ignore its contents, and delete them at any time (they will be regenerated when you next dev or build).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards"],"href":"/docs/kit/web-standards","content":"Throughout this documentation, you'll see references to the standard Web APIs that SvelteKit builds on top of. Rather than reinventing the wheel, we use the platform, which means your existing web development skills are applicable to SvelteKit. Conversely, time spent learning SvelteKit will help you be a better web developer elsewhere.These APIs are available in all modern browsers and in many non-browser environments like Cloudflare Workers, Deno, and Vercel Functions. During development, and in adapters for Node-based environments (including AWS Lambda), they're made available via polyfills where necessary (for now, that is — Node is rapidly adding support for more web standards).In particular, you'll get comfortable with the following:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Fetch APIs"],"href":"/docs/kit/web-standards#Fetch-APIs","content":"SvelteKit uses `fetch` for getting data from the network. It's available in hooks and server routes as well as in the browser.[!NOTE] A special version of `fetch` is available in [`load`](load) functions, [server hooks](hooks#Server-hooks), [API routes](routing#server) and [remote functions](remote-functions) for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. (To make credentialled fetches in server-side code outside `load`, you must explicitly pass `cookie` and/or `authorization` headers.) It also allows you to make relative requests, whereas server-side `fetch` normally requires a fully qualified URL.Besides fetch itself, the Fetch API includes the following interfaces:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Fetch APIs","Request"],"href":"/docs/kit/web-standards#Fetch-APIs-Request","content":"An instance of `Request` is accessible in hooks and server routes as event.request. It contains useful methods like request.json() and request.formData() for getting data that was posted to an endpoint.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Fetch APIs","Response"],"href":"/docs/kit/web-standards#Fetch-APIs-Response","content":"An instance of `Response` is returned from await fetch(...) and handlers in +server.js files. Fundamentally, a SvelteKit app is a machine for turning a Request into a Response.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Fetch APIs","Headers"],"href":"/docs/kit/web-standards#Fetch-APIs-Headers","content":"The `Headers` interface allows you to read incoming request.headers and set outgoing response.headers. For example, you can get the request.headers as shown below, and use the `json` convenience function to send modified response.headers: \n \nimport { json } from '@sveltejs/kit';\n\n/** @type {import('./$types').RequestHandler} */\nexport function GET({ request }) {\n\t// log all headers\n\tconsole.log(...request.headers);\n\n\t// create a JSON Response using a header we received\n\treturn json({\n\t\t// retrieve a specific header\n\t\tuserAgent: request.headers.get('user-agent')\n\t}, {\n\t\t// set a header on the response\n\t\theaders: { 'x-custom-header': 'potato' }\n\t});\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","FormData"],"href":"/docs/kit/web-standards#FormData","content":"When dealing with HTML native form submissions you'll be working with `FormData` objects. \n \nimport { json } from '@sveltejs/kit';\n\n/** @type {import('./$types').RequestHandler} */\nexport async function POST(event) {\n\tconst body = await event.request.formData();\n\n\t// log all fields\n\tconsole.log([...body]);\n\n\treturn json({\n\t\t// get a specific field's value\n\t\tname: body.get('name') ?? 'world'\n\t});\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Stream APIs"],"href":"/docs/kit/web-standards#Stream-APIs","content":"Most of the time, your endpoints will return complete data, as in the userAgent example above. Sometimes, you may need to return a response that's too large to fit in memory in one go, or is delivered in chunks, and for this the platform provides streams — ReadableStream, WritableStream and TransformStream.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","URL APIs"],"href":"/docs/kit/web-standards#URL-APIs","content":"URLs are represented by the `URL` interface, which includes useful properties like origin and pathname (and, in the browser, hash). This interface shows up in various places — event.url in hooks and server routes, `page.url` in pages, from and to in `beforeNavigate` and `afterNavigate` and so on.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","URL APIs","URLSearchParams"],"href":"/docs/kit/web-standards#URL-APIs-URLSearchParams","content":"Wherever you encounter a URL, you can access query parameters via url.searchParams, which is an instance of `URLSearchParams`:const foo = url.searchParams.get('foo');","rank":null},{"breadcrumbs":["Docs","SvelteKit","Getting started","Web standards","Web Crypto"],"href":"/docs/kit/web-standards#Web-Crypto","content":"The Web Crypto API is made available via the crypto global. It's used internally for Content Security Policy headers, but you can also use it for things like generating UUIDs:const uuid = crypto.randomUUID();","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing"],"href":"/docs/kit/routing","content":"At the heart of SvelteKit is a filesystem-based router. The routes of your app — i.e. the URL paths that users can access — are defined by the directories in your codebase:`src/routes` is the root route\n`src/routes/about` creates an `/about` route\n`src/routes/blog/[slug]` creates a route with a _parameter_, `slug`, that can be used to load data dynamically when a user requests a page like `/blog/hello-world`[!NOTE] You can change `src/routes` to a different directory by editing the [project config](configuration).Each route directory contains one or more route files, which can be identified by their + prefix.We'll introduce these files in a moment in more detail, but here are a few simple rules to help you remember how SvelteKit's routing works:All files can run on the server\nAll files run on the client except `+server` files\n`+layout` and `+error` files apply to subdirectories as well as the directory they live in","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+page"],"href":"/docs/kit/routing#page","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+page","+page.svelte"],"href":"/docs/kit/routing#page-page.svelte","content":"A +page.svelte component defines a page of your app. By default, pages are rendered both on the server (SSR) for the initial request and in the browser (CSR) for subsequent navigation.<!--- file: src/routes/+page.svelte --->\n<h1>Hello and welcome to my site!</h1>\n<a href=\"/about\">About my site</a><!--- file: src/routes/about/+page.svelte --->\n<h1>About this site</h1>\n<p>TODO...</p>\n<a href=\"/\">Home</a>[!NOTE] SvelteKit uses `<a>` elements to navigate between routes, rather than a framework-specific `<Link>` component.Pages can receive data from load functions via the data prop.<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n</script>\n\n<h1>{data.title}</h1>\n<div>{@html data.content}</div>As of 2.24, pages also receive a params prop which is typed based on the route parameters. This is particularly useful alongside remote functions:<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\timport { getPost } from '../blog.remote';\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { params } = $props();\n\n\tconst post = $derived(await getPost(params.slug));\n</script>\n\n<h1>{post.title}</h1>\n<div>{@html post.content}</div>[!LEGACY]\n`PageProps` was added in 2.16.0. In earlier versions, you had to type the `data` property manually with `PageData` instead, see [$types](#\\$types).\n\nIn Svelte 4, you'd use `export let data` instead.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+page","+page.js"],"href":"/docs/kit/routing#page-page.js","content":"Often, a page will need to load some data before it can be rendered. For this, we add a +page.js module that exports a load function: \nimport { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').PageLoad} */\nexport function load({ params }) {\n\tif (params.slug === 'hello-world') {\n\t\treturn {\n\t\t\ttitle: 'Hello world!',\n\t\t\tcontent: 'Welcome to our blog. Lorem ipsum dolor sit amet...'\n\t\t};\n\t}\n\n\terror(404, 'Not found');\n}This function runs alongside +page.svelte, which means it runs on the server during server-side rendering and in the browser during client-side navigation. See `load` for full details of the API.As well as load, +page.js can export values that configure the page's behaviour:`export const prerender = true` or `false` or `'auto'`\n`export const ssr = true` or `false`\n`export const csr = true` or `false`You can find more information about these in page options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+page","+page.server.js"],"href":"/docs/kit/routing#page-page.server.js","content":"If your load function can only run on the server — for example, if it needs to fetch data from a database or you need to access private environment variables like API keys — then you can rename +page.js to +page.server.js and change the PageLoad type to PageServerLoad.import { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n\tconst post = await getPostFromDatabase(params.slug);\n\n\tif (post) {\n\t\treturn post;\n\t}\n\n\terror(404, 'Not found');\n}During client-side navigation, SvelteKit will load this data from the server, which means that the returned value must be serializable using devalue. See `load` for full details of the API.Like +page.js, +page.server.js can export page options — prerender, ssr and csr.A +page.server.js file can also export actions. If load lets you read data from the server, actions let you write data to the server using the <form> element. To learn how to use them, see the form actions section.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+error"],"href":"/docs/kit/routing#error","content":"If an error occurs during load, SvelteKit will render a default error page. You can customise this error page on a per-route basis by adding an +error.svelte file:<!--- file: src/routes/blog/[slug]/+error.svelte --->\n<script>\n\timport { page } from '$app/state';\n</script>\n\n<h1>{page.status}: {page.error.message}</h1>[!LEGACY]\n`$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.SvelteKit will 'walk up the tree' looking for the closest error boundary — if the file above didn't exist it would try src/routes/blog/+error.svelte and then src/routes/+error.svelte before rendering the default error page. If that fails (or if the error was thrown from the load function of the root +layout, which sits 'above' the root +error), SvelteKit will bail out and render a static fallback error page, which you can customise by creating a src/error.html file.If the error occurs inside a load function in +layout(.server).js, the closest error boundary in the tree is an +error.svelte file above that layout (not next to it).If no route can be found (404), src/routes/+error.svelte (or the default error page, if that file does not exist) will be used.[!NOTE] `+error.svelte` is _not_ used when an error occurs inside [`handle`](hooks#Server-hooks-handle) or a [+server.js](#server) request handler.You can read more about error handling here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+layout"],"href":"/docs/kit/routing#layout","content":"So far, we've treated pages as entirely standalone components — upon navigation, the existing +page.svelte component will be destroyed, and a new one will take its place.But in many apps, there are elements that should be visible on every page, such as top-level navigation or a footer. Instead of repeating them in every +page.svelte, we can put them in layouts.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+layout","+layout.svelte"],"href":"/docs/kit/routing#layout-layout.svelte","content":"To create a layout that applies to every page, make a file called src/routes/+layout.svelte. The default layout (the one that SvelteKit uses if you don't bring your own) looks like this...<script>\n\tlet { children } = $props();\n</script>\n\n{@render children()}...but we can add whatever markup, styles and behaviour we want. The only requirement is that the component includes a @render tag for the page content. For example, let's add a nav bar:<!--- file: src/routes/+layout.svelte --->\n<script>\n\tlet { children } = $props();\n</script>\n\n<nav>\n\t<a href=\"/\">Home</a>\n\t<a href=\"/about\">About</a>\n\t<a href=\"/settings\">Settings</a>\n</nav>\n\n{@render children()}If we create pages for /, /about and /settings... \n<h1>Home</h1> \n<h1>About</h1> \n<h1>Settings</h1>...the nav will always be visible, and clicking between the three pages will only result in the <h1> being replaced.Layouts can be nested. Suppose we don't just have a single /settings page, but instead have nested pages like /settings/profile and /settings/notifications with a shared submenu (for a real-life example, see github.com/settings).We can create a layout that only applies to pages below /settings (while inheriting the root layout with the top-level nav):<!--- file: src/routes/settings/+layout.svelte --->\n<script>\n\t/** @type {import('./$types').LayoutProps} */\n\tlet { data, children } = $props();\n</script>\n\n<h1>Settings</h1>\n\n<div class=\"submenu\">\n\t{#each data.sections as section}\n\t\t<a href=\"/settings/{section.slug}\">{section.title}</a>\n\t{/each}\n</div>\n\n{@render children()}[!LEGACY]\n`LayoutProps` was added in 2.16.0. In earlier versions, you had to [type the properties manually instead](#\\$types).You can see how data is populated by looking at the +layout.js example in the next section just below.By default, each layout inherits the layout above it. Sometimes that isn't what you want - in this case, advanced layouts can help you.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+layout","+layout.js"],"href":"/docs/kit/routing#layout-layout.js","content":"Just like +page.svelte loading data from +page.js, your +layout.svelte component can get data from a `load` function in +layout.js. \n/** @type {import('./$types').LayoutLoad} */\nexport function load() {\n\treturn {\n\t\tsections: [\n\t\t\t{ slug: 'profile', title: 'Profile' },\n\t\t\t{ slug: 'notifications', title: 'Notifications' }\n\t\t]\n\t};\n}If a +layout.js exports page options — prerender, ssr and csr — they will be used as defaults for child pages.Data returned from a layout's load function is also available to all its child pages:<!--- file: src/routes/settings/profile/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n\n\tconsole.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]\n</script>[!NOTE] Often, layout data is unchanged when navigating between pages. SvelteKit will intelligently rerun [`load`](load) functions when necessary.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+layout","+layout.server.js"],"href":"/docs/kit/routing#layout-layout.server.js","content":"To run your layout's load function on the server, move it to +layout.server.js, and change the LayoutLoad type to LayoutServerLoad.Like +layout.js, +layout.server.js can export page options — prerender, ssr and csr.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+server"],"href":"/docs/kit/routing#server","content":"As well as pages, you can define routes with a +server.js file (sometimes referred to as an 'API route' or an 'endpoint'), which gives you full control over the response. Your +server.js file exports functions corresponding to HTTP verbs like GET, POST, PATCH, PUT, DELETE, OPTIONS, and HEAD that take a `RequestEvent` argument and return a `Response` object.For example we could create an /api/random-number route with a GET handler: \nimport { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').RequestHandler} */\nexport function GET({ url }) {\n\tconst min = Number(url.searchParams.get('min') ?? '0');\n\tconst max = Number(url.searchParams.get('max') ?? '1');\n\n\tconst d = max - min;\n\n\tif (isNaN(d) || d < 0) {\n\t\terror(400, 'min and max must be numbers, and min must be less than max');\n\t}\n\n\tconst random = min + Math.random() * d;\n\n\treturn new Response(String(random));\n}The first argument to Response can be a `ReadableStream`, making it possible to stream large amounts of data or create server-sent events (unless deploying to platforms that buffer responses, like AWS Lambda).You can use the `error`, `redirect` and `json` methods from @sveltejs/kit for convenience (but you don't have to).If an error is thrown (either error(...) or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via src/error.html — depending on the Accept header. The `+error.svelte` component will not be rendered in this case. You can read more about error handling here.[!NOTE] When creating an `OPTIONS` handler, note that Vite will inject `Access-Control-Allow-Origin` and `Access-Control-Allow-Methods` headers — these will not be present in production unless you add them.[!NOTE] `+layout` files have no effect on `+server.js` files. If you want to run some logic before each request, add it to the server [`handle`](hooks#Server-hooks-handle) hook.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+server","Receiving data"],"href":"/docs/kit/routing#server-Receiving-data","content":"By exporting POST/PUT/PATCH/DELETE/OPTIONS/HEAD handlers, +server.js files can be used to create a complete API:<!--- file: src/routes/add/+page.svelte --->\n<script>\n\tlet a = $state(0);\n\tlet b = $state(0);\n\tlet total = $state(0);\n\n\tasync function add() {\n\t\tconst response = await fetch('/api/add', {\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify({ a, b }),\n\t\t\theaders: {\n\t\t\t\t'content-type': 'application/json'\n\t\t\t}\n\t\t});\n\n\t\ttotal = await response.json();\n\t}\n</script>\n\n<input type=\"number\" bind:value={a}> +\n<input type=\"number\" bind:value={b}> =\n{total}\n\n<button onclick={add}>Calculate</button> \nimport { json } from '@sveltejs/kit';\n\n/** @type {import('./$types').RequestHandler} */\nexport async function POST({ request }) {\n\tconst { a, b } = await request.json();\n\treturn json(a + b);\n}[!NOTE] In general, [form actions](form-actions) are a better way to submit data from the browser to the server.[!NOTE] If a `GET` handler is exported, a `HEAD` request will return the `content-length` of the `GET` handler's response body.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+server","Fallback method handler"],"href":"/docs/kit/routing#server-Fallback-method-handler","content":"Exporting the fallback handler will match any unhandled request methods, including methods like MOVE which have no dedicated export from +server.js. \nimport { json, text } from '@sveltejs/kit';\n\n/** @type {import('./$types').RequestHandler} */\nexport async function POST({ request }) {\n\tconst { a, b } = await request.json();\n\treturn json(a + b);\n}\n\n// This handler will respond to PUT, PATCH, DELETE, etc.\n/** @type {import('./$types').RequestHandler} */\nexport async function fallback({ request }) {\n\treturn text(`I caught your ${request.method} request!`);\n}[!NOTE] For `HEAD` requests, the `GET` handler takes precedence over the `fallback` handler.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","+server","Content negotiation"],"href":"/docs/kit/routing#server-Content-negotiation","content":"+server.js files can be placed in the same directory as +page files, allowing the same route to be either a page or an API endpoint. To determine which, SvelteKit applies the following rules:`PUT`/`PATCH`/`DELETE`/`OPTIONS` requests are always handled by `+server.js` since they do not apply to pages\n`GET`/`POST`/`HEAD` requests are treated as page requests if the `accept` header prioritises `text/html` (in other words, it's a browser page request), else they are handled by `+server.js`.\nResponses to `GET` requests will include a `Vary: Accept` header, so that proxies and browsers cache HTML and JSON responses separately.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","$types"],"href":"/docs/kit/routing#$types","content":"Throughout the examples above, we've been importing types from a $types.d.ts file. This is a file SvelteKit creates for you in a hidden directory if you're using TypeScript (or JavaScript with JSDoc type annotations) to give you type safety when working with your root files.For example, annotating let { data } = $props() with PageProps (or LayoutProps, for a +layout.svelte file) tells TypeScript that the type of data is whatever was returned from load:<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n</script>[!NOTE]\nThe `PageProps` and `LayoutProps` types, added in 2.16.0, are a shortcut for typing the `data` prop as `PageData` or `LayoutData`, as well as other props, such as `form` for pages, or `children` for layouts. In earlier versions, you had to type these properties manually. For example, for a page:\n\n```js\n/// file: +page.svelte\n/** @type {{ data: import('./$types').PageData, form: import('./$types').ActionData }} */\nlet { data, form } = $props();\n```\n\nOr, for a layout:\n\n```js\n/// file: +layout.svelte\n/** @type {{ data: import('./$types').LayoutData, children: Snippet }} */\nlet { data, children } = $props();\n```In turn, annotating the load function with PageLoad, PageServerLoad, LayoutLoad or LayoutServerLoad (for +page.js, +page.server.js, +layout.js and +layout.server.js respectively) ensures that params and the return value are correctly typed.If you're using VS Code or any IDE that supports the language server protocol and TypeScript plugins then you can omit these types entirely! Svelte's IDE tooling will insert the correct types for you, so you'll get type checking without writing them yourself. It also works with our command line tool svelte-check.You can read more about omitting $types in our blog post about it.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","Other files"],"href":"/docs/kit/routing#Other-files","content":"Any other files inside a route directory are ignored by SvelteKit. This means you can colocate components and utility modules with the routes that need them.If components and modules are needed by multiple routes, it's a good idea to put them in `$lib`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Routing","Further reading"],"href":"/docs/kit/routing#Further-reading","content":"[Tutorial: Routing](/tutorial/kit/pages)\n[Tutorial: API routes](/tutorial/kit/get-handlers)\n[Docs: Advanced routing](advanced-routing)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data"],"href":"/docs/kit/load","content":"Before a `+page.svelte` component (and its containing `+layout.svelte` components) can be rendered, we often need to get some data. This is done by defining load functions.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Page data"],"href":"/docs/kit/load#Page-data","content":"A +page.svelte file can have a sibling +page.js that exports a load function, the return value of which is available to the page via the data prop: \n/** @type {import('./$types').PageLoad} */\nexport function load({ params }) {\n\treturn {\n\t\tpost: {\n\t\t\ttitle: `Title for ${params.slug} goes here`,\n\t\t\tcontent: `Content for ${params.slug} goes here`\n\t\t}\n\t};\n}<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n</script>\n\n<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>[!LEGACY]\nBefore version 2.16.0, the props of a page and layout had to be typed individually:\n```js\n/// file: +page.svelte\n/** @type {{ data: import('./$types').PageData }} */\nlet { data } = $props();\n```\n\nIn Svelte 4, you'd use `export let data` instead.Thanks to the generated $types module, we get full type safety.A load function in a +page.js file runs both on the server and in the browser (unless combined with export const ssr = false, in which case it will only run in the browser). If your load function should always run on the server (because it uses private environment variables, for example, or accesses a database) then it would go in a +page.server.js instead.A more realistic version of your blog post's load function, that only runs on the server and pulls data from a database, might look like this:import * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n\treturn {\n\t\tpost: await db.getPost(params.slug)\n\t};\n}Notice that the type changed from PageLoad to PageServerLoad, because server load functions can access additional arguments. To understand when to use +page.js and when to use +page.server.js, see Universal vs server.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Layout data"],"href":"/docs/kit/load#Layout-data","content":"Your +layout.svelte files can also load data, via +layout.js or +layout.server.js.import * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load() {\n\treturn {\n\t\tposts: await db.getPostSummaries()\n\t};\n}<!--- file: src/routes/blog/[slug]/+layout.svelte --->\n<script>\n\t/** @type {import('./$types').LayoutProps} */\n\tlet { data, children } = $props();\n</script>\n\n<main>\n\t<!-- +page.svelte is `@render`ed here -->\n\t{@render children()}\n</main>\n\n<aside>\n\t<h2>More posts</h2>\n\t<ul>\n\t\t{#each data.posts as post}\n\t\t\t<li>\n\t\t\t\t<a href=\"/blog/{post.slug}\">\n\t\t\t\t\t{post.title}\n\t\t\t\t</a>\n\t\t\t</li>\n\t\t{/each}\n\t</ul>\n</aside>[!LEGACY]\n`LayoutProps` was added in 2.16.0. In earlier versions, properties had to be typed individually:\n```js\n/// file: +layout.svelte\n/** @type {{ data: import('./$types').LayoutData, children: Snippet }} */\nlet { data, children } = $props();\n```Data returned from layout load functions is available to child +layout.svelte components and the +page.svelte component as well as the layout that it 'belongs' to. \n<script>\n\t+++import { page } from '$app/state';+++\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n\n+++\t// we can access `data.posts` because it's returned from\n\t// the parent layout `load` function\n\tlet index = $derived(data.posts.findIndex(post => post.slug === page.params.slug));\n\tlet next = $derived(data.posts[index + 1]);+++\n</script>\n\n<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>\n\n+++{#if next}\n\t<p>Next post: <a href=\"/blog/{next.slug}\">{next.title}</a></p>\n{/if}+++[!NOTE] If multiple `load` functions return data with the same key, the last one 'wins' — the result of a layout `load` returning `{ a: 1, b: 2 }` and a page `load` returning `{ b: 3, c: 4 }` would be `{ a: 1, b: 3, c: 4 }`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","page.data"],"href":"/docs/kit/load#page.data","content":"The +page.svelte component, and each +layout.svelte component above it, has access to its own data plus all the data from its parents.In some cases, we might need the opposite — a parent layout might need to access page data or data from a child layout. For example, the root layout might want to access a title property returned from a load function in +page.js or +page.server.js. This can be done with page.data:<!--- file: src/routes/+layout.svelte --->\n<script>\n\timport { page } from '$app/state';\n</script>\n\n<svelte:head>\n\t<title>{page.data.title}</title>\n</svelte:head>Type information for page.data is provided by App.PageData.[!LEGACY]\n`$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.\nIt provides a `page` store with the same interface that you can subscribe to, e.g. `$page.data.title`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Universal vs server"],"href":"/docs/kit/load#Universal-vs-server","content":"As we've seen, there are two types of load function:`+page.js` and `+layout.js` files export _universal_ `load` functions that run both on the server and in the browser\n`+page.server.js` and `+layout.server.js` files export _server_ `load` functions that only run server-sideConceptually, they're the same thing, but there are some important differences to be aware of.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Universal vs server","When does which load function run?"],"href":"/docs/kit/load#Universal-vs-server-When-does-which-load-function-run","content":"Server load functions always run on the server.By default, universal load functions run on the server during SSR when the user first visits your page. They will then run again during hydration, reusing any responses from fetch requests. All subsequent invocations of universal load functions happen in the browser. You can customize the behavior through page options. If you disable server-side rendering, you'll get an SPA and universal load functions always run on the client.If a route contains both universal and server load functions, the server load runs first.A load function is invoked at runtime, unless you prerender the page — in that case, it's invoked at build time.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Universal vs server","Input"],"href":"/docs/kit/load#Universal-vs-server-Input","content":"Both universal and server load functions have access to properties describing the request (params, route and url) and various functions (fetch, setHeaders, parent, depends and untrack). These are described in the following sections.Server load functions are called with a ServerLoadEvent, which inherits clientAddress, cookies, locals, platform and request from RequestEvent.Universal load functions are called with a LoadEvent, which has a data property. If you have load functions in both +page.js and +page.server.js (or +layout.js and +layout.server.js), the return value of the server load function is the data property of the universal load function's argument.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Universal vs server","Output"],"href":"/docs/kit/load#Universal-vs-server-Output","content":"A universal load function can return an object containing any values, including things like custom classes and component constructors.A server load function must return data that can be serialized with devalue — anything that can be represented as JSON plus things like BigInt, Date, Map, Set and RegExp, or repeated/cyclical references — so that it can be transported over the network. Your data can include promises, in which case it will be streamed to browsers. If you need to serialize/deserialize custom types, use transport hooks.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Universal vs server","When to use which"],"href":"/docs/kit/load#Universal-vs-server-When-to-use-which","content":"Server load functions are convenient when you need to access data directly from a database or filesystem, or need to use private environment variables.Universal load functions are useful when you need to fetch data from an external API and don't need private credentials, since SvelteKit can get the data directly from the API rather than going via your server. They are also useful when you need to return something that can't be serialized, such as a Svelte component constructor.In rare cases, you might need to use both together — for example, you might need to return an instance of a custom class that was initialised with data from your server. When using both, the server load return value is not passed directly to the page, but to the universal load function (as the data property): \n/** @type {import('./$types').PageServerLoad} */\nexport async function load() {\n\treturn {\n\t\tserverMessage: 'hello from server load function'\n\t};\n} \n \n/** @type {import('./$types').PageLoad} */\nexport async function load({ data }) {\n\treturn {\n\t\tserverMessage: data.serverMessage,\n\t\tuniversalMessage: 'hello from universal load function'\n\t};\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using URL data"],"href":"/docs/kit/load#Using-URL-data","content":"Often the load function depends on the URL in one way or another. For this, the load function provides you with url, route and params.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using URL data","url"],"href":"/docs/kit/load#Using-URL-data-url","content":"An instance of `URL`, containing properties like the origin, hostname, pathname and searchParams (which contains the parsed query string as a `URLSearchParams` object). url.hash cannot be accessed during load, since it is unavailable on the server.[!NOTE] In some environments this is derived from request headers during server-side rendering. If you're using [adapter-node](adapter-node), for example, you may need to configure the adapter in order for the URL to be correct.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using URL data","route"],"href":"/docs/kit/load#Using-URL-data-route","content":"Contains the name of the current route directory, relative to src/routes: \n/** @type {import('./$types').PageLoad} */\nexport function load({ route }) {\n\tconsole.log(route.id); // '/a/[b]/[...c]'\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using URL data","params"],"href":"/docs/kit/load#Using-URL-data-params","content":"params is derived from url.pathname and route.id.Given a route.id of /a/[b]/[...c] and a url.pathname of /a/x/y/z, the params object would look like this:{\n\t\"b\": \"x\",\n\t\"c\": \"y/z\"\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Making fetch requests"],"href":"/docs/kit/load#Making-fetch-requests","content":"To get data from an external API or a +server.js handler, you can use the provided fetch function, which behaves identically to the native `fetch` web API with a few additional features:It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.\nIt can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).\nInternal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.\nDuring server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text`, `json` and `arrayBuffer` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](hooks#Server-hooks-handle).\nDuring hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request - if you received a warning in your browser console when using the browser `fetch` instead of the `load` `fetch`, this is why. \n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch, params }) {\n\tconst res = await fetch(`/api/items/${params.id}`);\n\tconst item = await res.json();\n\n\treturn { item };\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Cookies"],"href":"/docs/kit/load#Cookies","content":"A server load function can get and set `cookies`.import * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load({ cookies }) {\n\tconst sessionid = cookies.get('sessionid');\n\n\treturn {\n\t\tuser: await db.getUser(sessionid)\n\t};\n}Cookies will only be passed through the provided fetch function if the target host is the same as the SvelteKit application or a more specific subdomain of it.For example, if SvelteKit is serving my.domain.com:domain.com WILL NOT receive cookies\nmy.domain.com WILL receive cookies\napi.domain.com WILL NOT receive cookies\nsub.my.domain.com WILL receive cookiesOther cookies will not be passed when credentials: 'include' is set, because SvelteKit does not know which domain which cookie belongs to (the browser does not pass this information along), so it's not safe to forward any of them. Use the handleFetch hook to work around it.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Headers"],"href":"/docs/kit/load#Headers","content":"Both server and universal load functions have access to a setHeaders function that, when running on the server, can set headers for the response. (When running in the browser, setHeaders has no effect.) This is useful if you want the page to be cached, for example: \n \n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch, setHeaders }) {\n\tconst url = `https://cms.example.com/products.json`;\n\tconst response = await fetch(url);\n\n\t// Headers are only set during SSR, caching the page's HTML\n\t// for the same length of time as the underlying data.\n\tsetHeaders({\n\t\tage: response.headers.get('age'),\n\t\t'cache-control': response.headers.get('cache-control')\n\t});\n\n\treturn response.json();\n}Setting the same header multiple times (even in separate load functions) is an error. You can only set a given header once using the setHeaders function. You cannot add a set-cookie header with setHeaders — use cookies.set(name, value, options) instead.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using parent data"],"href":"/docs/kit/load#Using-parent-data","content":"Occasionally it's useful for a load function to access data from a parent load function, which can be done with await parent(): \n/** @type {import('./$types').LayoutLoad} */\nexport function load() {\n\treturn { a: 1 };\n} \n/** @type {import('./$types').LayoutLoad} */\nexport async function load({ parent }) {\n\tconst { a } = await parent();\n\treturn { b: a + 1 };\n} \n/** @type {import('./$types').PageLoad} */\nexport async function load({ parent }) {\n\tconst { a, b } = await parent();\n\treturn { c: a + b };\n}<!--- file: src/routes/abc/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n</script>\n\n<!-- renders `1 + 2 = 3` -->\n<p>{data.a} + {data.b} = {data.c}</p>[!NOTE] Notice that the `load` function in `+page.js` receives the merged data from both layout `load` functions, not just the immediate parent.Inside +page.server.js and +layout.server.js, parent returns data from parent +layout.server.js files.In +page.js or +layout.js it will return data from parent +layout.js files. However, a missing +layout.js is treated as a ({ data }) => data function, meaning that it will also return data from parent +layout.server.js files that are not 'shadowed' by a +layout.js fileTake care not to introduce waterfalls when using await parent(). Here, for example, getData(params) does not depend on the result of calling parent(), so we should call it first to avoid a delayed render./** @type {import('./$types').PageLoad} */\nexport async function load({ params, parent }) {\n\t---const parentData = await parent();---\n\tconst data = await getData(params);\n\t+++const parentData = await parent();+++\n\n\treturn {\n\t\t...data,\n\t\tmeta: { ...parentData.meta, ...data.meta }\n\t};\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Errors"],"href":"/docs/kit/load#Errors","content":"If an error is thrown during load, the nearest `+error.svelte` will be rendered. For _expected_ errors, use the error helper from @sveltejs/kit to specify the HTTP status code and an optional message:import { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport function load({ locals }) {\n\tif (!locals.user) {\n\t\terror(401, 'not logged in');\n\t}\n\n\tif (!locals.user.isAdmin) {\n\t\terror(403, 'not an admin');\n\t}\n}Calling error(...) will throw an exception, making it easy to stop execution from inside helper functions.If an _unexpected_ error is thrown, SvelteKit will invoke `handleError` and treat it as a 500 Internal Error.[!NOTE] [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the error yourself","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Redirects"],"href":"/docs/kit/load#Redirects","content":"To redirect users, use the redirect helper from @sveltejs/kit to specify the location to which they should be redirected alongside a 3xx status code. Like error(...), calling redirect(...) will throw an exception, making it easy to stop execution from inside helper functions.import { redirect } from '@sveltejs/kit';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport function load({ locals }) {\n\tif (!locals.user) {\n\t\tredirect(307, '/login');\n\t}\n}[!NOTE] Don't use `redirect()` inside a `try {...}` block, as the redirect will immediately trigger the catch statement.In the browser, you can also navigate programmatically outside of a load function using `goto` from `$app.navigation`.[!NOTE] [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the `redirect` yourself","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Streaming with promises"],"href":"/docs/kit/load#Streaming-with-promises","content":"When using a server load, promises will be streamed to the browser as they resolve. This is useful if you have slow, non-essential data, since you can start rendering the page before all the data is available:/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n\treturn {\n\t\t// make sure the `await` happens at the end, otherwise we\n\t\t// can't start loading comments until we've loaded the post\n\t\tcomments: loadComments(params.slug),\n\t\tpost: await loadPost(params.slug)\n\t};\n}This is useful for creating skeleton loading states, for example:<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n</script>\n\n<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>\n\n{#await data.comments}\n\tLoading comments...\n{:then comments}\n\t{#each comments as comment}\n\t\t<p>{comment.content}</p>\n\t{/each}\n{:catch error}\n\t<p>error loading comments: {error.message}</p>\n{/await}When streaming data, be careful to handle promise rejections correctly. More specifically, the server could crash with an \"unhandled promise rejection\" error if a lazy-loaded promise fails before rendering starts (at which point it's caught) and isn't handling the error in some way. When using SvelteKit's fetch directly in the load function, SvelteKit will handle this case for you. For other promises, it is enough to attach a noop-catch to the promise to mark it as handled. \n/** @type {import('./$types').PageServerLoad} */\nexport function load({ fetch }) {\n\tconst ok_manual = Promise.reject();\n\tok_manual.catch(() => {});\n\n\treturn {\n\t\tok_manual,\n\t\tok_fetch: fetch('/fetch/that/could/fail'),\n\t\tdangerous_unhandled: Promise.reject()\n\t};\n}[!NOTE] On platforms that do not support streaming, such as AWS Lambda or Firebase, responses will be buffered. This means the page will only render once all promises resolve. If you are using a proxy (e.g. NGINX), make sure it does not buffer responses from the proxied server.[!NOTE] Streaming data will only work when JavaScript is enabled. You should avoid returning promises from a universal `load` function if the page is server rendered, as these are _not_ streamed — instead, the promise is recreated when the function reruns in the browser.[!NOTE] The headers and status code of a response cannot be changed once the response has started streaming, therefore you cannot `setHeaders` or throw redirects inside a streamed promise.[!NOTE] [In SvelteKit 1.x](migrating-to-sveltekit-2#Top-level-promises-are-no-longer-awaited) top-level promises were automatically awaited, only nested promises were streamed.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Parallel loading"],"href":"/docs/kit/load#Parallel-loading","content":"When rendering (or navigating to) a page, SvelteKit runs all load functions concurrently, avoiding a waterfall of requests. During client-side navigation, the result of calling multiple server load functions are grouped into a single response. Once all load functions have returned, the page is rendered.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Rerunning load functions"],"href":"/docs/kit/load#Rerunning-load-functions","content":"SvelteKit tracks the dependencies of each load function to avoid rerunning it unnecessarily during navigation.For example, given a pair of load functions like these...import * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n\treturn {\n\t\tpost: await db.getPost(params.slug)\n\t};\n}import * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load() {\n\treturn {\n\t\tposts: await db.getPostSummaries()\n\t};\n}...the one in +page.server.js will rerun if we navigate from /blog/trying-the-raw-meat-diet to /blog/i-regret-my-choices because params.slug has changed. The one in +layout.server.js will not, because the data is still valid. In other words, we won't call db.getPostSummaries() a second time.A load function that calls await parent() will also rerun if a parent load function is rerun.Dependency tracking does not apply after the load function has returned — for example, accessing params.x inside a nested promise will not cause the function to rerun when params.x changes. (Don't worry, you'll get a warning in development if you accidentally do this.) Instead, access the parameter in the main body of your load function.Search parameters are tracked independently from the rest of the url. For example, accessing event.url.searchParams.get(\"x\") inside a load function will make that load function re-run when navigating from ?x=1 to ?x=2, but not when navigating from ?x=1&y=1 to ?x=1&y=2.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Rerunning load functions","Untracking dependencies"],"href":"/docs/kit/load#Rerunning-load-functions-Untracking-dependencies","content":"In rare cases, you may wish to exclude something from the dependency tracking mechanism. You can do this with the provided untrack function: \n/** @type {import('./$types').PageLoad} */\nexport async function load({ untrack, url }) {\n\t// Untrack url.pathname so that path changes don't trigger a rerun\n\tif (untrack(() => url.pathname === '/')) {\n\t\treturn { message: 'Welcome!' };\n\t}\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Rerunning load functions","Manual invalidation"],"href":"/docs/kit/load#Rerunning-load-functions-Manual-invalidation","content":"You can also rerun load functions that apply to the current page using `invalidate(url)`, which reruns all load functions that depend on url, and `invalidateAll()`, which reruns every load function. Server load functions will never automatically depend on a fetched url to avoid leaking secrets to the client.A load function depends on url if it calls fetch(url) or depends(url). Note that url can be a custom identifier that starts with [a-z]:: \n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch, depends }) {\n\t// load reruns when `invalidate('https://api.example.com/random-number')` is called...\n\tconst response = await fetch('https://api.example.com/random-number');\n\n\t// ...or when `invalidate('app:random')` is called\n\tdepends('app:random');\n\n\treturn {\n\t\tnumber: await response.json()\n\t};\n}<!--- file: src/routes/random-number/+page.svelte --->\n<script>\n\timport { invalidate, invalidateAll } from '$app/navigation';\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n\n\tfunction rerunLoadFunction() {\n\t\t// any of these will cause the `load` function to rerun\n\t\tinvalidate('app:random');\n\t\tinvalidate('https://api.example.com/random-number');\n\t\tinvalidate(url => url.href.includes('random-number'));\n\t\tinvalidateAll();\n\t}\n</script>\n\n<p>random number: {data.number}</p>\n<button onclick={rerunLoadFunction}>Update random number</button>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Rerunning load functions","When do load functions rerun?"],"href":"/docs/kit/load#Rerunning-load-functions-When-do-load-functions-rerun","content":"To summarize, a load function will rerun in the following situations:It references a property of `params` whose value has changed\nIt references a property of `url` (such as `url.pathname` or `url.search`) whose value has changed. Properties in `request.url` are _not_ tracked\nIt calls `url.searchParams.get(...)`, `url.searchParams.getAll(...)` or `url.searchParams.has(...)` and the parameter in question changes. Accessing other properties of `url.searchParams` will have the same effect as accessing `url.search`.\nIt calls `await parent()` and a parent `load` function reran\nA child `load` function calls `await parent()` and is rerunning, and the parent is a server load function\nIt declared a dependency on a specific URL via [`fetch`](#Making-fetch-requests) (universal load only) or [`depends`](@sveltejs-kit#LoadEvent), and that URL was marked invalid with [`invalidate(url)`]($app-navigation#invalidate)\nAll active `load` functions were forcibly rerun with [`invalidateAll()`]($app-navigation#invalidateAll)params and url can change in response to a <a href=\"..\"> link click, a `<form>` interaction, a `goto` invocation, or a `redirect`.Note that rerunning a load function will update the data prop inside the corresponding +layout.svelte or +page.svelte; it does not cause the component to be recreated. As a result, internal state is preserved. If this isn't what you want, you can reset whatever you need to reset inside an `afterNavigate` callback, and/or wrap your component in a `{#key ...}` block.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Implications for authentication"],"href":"/docs/kit/load#Implications-for-authentication","content":"A couple features of loading data have important implications for auth checks:Layout `load` functions do not run on every request, such as during client side navigation between child routes. [(When do load functions rerun?)](load#Rerunning-load-functions-When-do-load-functions-rerun)\nLayout and page `load` functions run concurrently unless `await parent()` is called. If a layout `load` throws, the page `load` function runs, but the client will not receive the returned data.There are a few possible strategies to ensure an auth check occurs before protected code.To prevent data waterfalls and preserve layout load caches:Use [hooks](hooks) to protect multiple routes before any `load` functions run\nUse auth guards directly in `+page.server.js` `load` functions for route specific protectionPutting an auth guard in +layout.server.js requires all child pages to call await parent() before protected code. Unless every child page depends on returned data from await parent(), the other options will be more performant.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Using `getRequestEvent`"],"href":"/docs/kit/load#Using-getRequestEvent","content":"When running server load functions, the event object passed to the function as an argument can also be retrieved with `getRequestEvent`. This allows shared logic (such as authentication guards) to access information about the current request without it needing to be passed around.For example, you might have a function that requires users to be logged in, and redirects them to /login if not:import { redirect } from '@sveltejs/kit';\nimport { getRequestEvent } from '$app/server';\n\nexport function requireLogin() {\n\tconst { locals, url } = getRequestEvent();\n\n\t// assume `locals.user` is populated in `handle`\n\tif (!locals.user) {\n\t\tconst redirectTo = url.pathname + url.search;\n\t\tconst params = new URLSearchParams({ redirectTo });\n\n\t\tredirect(303, `/login?${params}`);\n\t}\n\n\treturn locals.user;\n}Now, you can call requireLogin in any load function (or form action, for example) to guarantee that the user is logged in:import { requireLogin } from '$lib/server/auth';\n\nexport function load() {\n\tconst user = requireLogin();\n\n\t// `user` is guaranteed to be a user object here, because otherwise\n\t// `requireLogin` would throw a redirect and we wouldn't get here\n\treturn {\n\t\tmessage: `hello ${user.name}!`\n\t};\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Loading data","Further reading"],"href":"/docs/kit/load#Further-reading","content":"[Tutorial: Loading data](/tutorial/kit/page-data)\n[Tutorial: Errors and redirects](/tutorial/kit/error-basics)\n[Tutorial: Advanced loading](/tutorial/kit/await-parent)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions"],"href":"/docs/kit/form-actions","content":"A +page.server.js file can export actions, which allow you to POST data to the server using the <form> element.When using <form>, client-side JavaScript is optional, but you can easily progressively enhance your form interactions with JavaScript to provide the best user experience.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Default actions"],"href":"/docs/kit/form-actions#Default-actions","content":"In the simplest case, a page declares a default action: \n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tdefault: async (event) => {\n\t\t// TODO log the user in\n\t}\n};To invoke this action from the /login page, just add a <form> — no JavaScript needed:<!--- file: src/routes/login/+page.svelte --->\n<form method=\"POST\">\n\t<label>\n\t\tEmail\n\t\t<input name=\"email\" type=\"email\">\n\t</label>\n\t<label>\n\t\tPassword\n\t\t<input name=\"password\" type=\"password\">\n\t</label>\n\t<button>Log in</button>\n</form>If someone were to click the button, the browser would send the form data via POST request to the server, running the default action.[!NOTE] Actions always use `POST` requests, since `GET` requests should never have side-effects.We can also invoke the action from other pages (for example if there's a login widget in the nav in the root layout) by adding the action attribute, pointing to the page: \n<form method=\"POST\" action=\"/login\">\n\t<!-- content -->\n</form>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Named actions"],"href":"/docs/kit/form-actions#Named-actions","content":"Instead of one default action, a page can have as many named actions as it needs: \n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n---\tdefault: async (event) => {---\n+++\tlogin: async (event) => {+++\n\t\t// TODO log the user in\n\t},\n+++\tregister: async (event) => {\n\t\t// TODO register the user\n\t}+++\n};To invoke a named action, add a query parameter with the name prefixed by a / character:<!--- file: src/routes/login/+page.svelte --->\n<form method=\"POST\" action=\"?/register\"><!--- file: src/routes/+layout.svelte --->\n<form method=\"POST\" action=\"/login?/register\">As well as the action attribute, we can use the formaction attribute on a button to POST the same form data to a different action than the parent <form>: \n<form method=\"POST\" +++action=\"?/login\"+++>\n\t<label>\n\t\tEmail\n\t\t<input name=\"email\" type=\"email\">\n\t</label>\n\t<label>\n\t\tPassword\n\t\t<input name=\"password\" type=\"password\">\n\t</label>\n\t<button>Log in</button>\n\t+++<button formaction=\"?/register\">Register</button>+++\n</form>[!NOTE] We can't have default actions next to named actions, because if you POST to a named action without a redirect, the query parameter is persisted in the URL, which means the next default POST would go through the named action from before.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Anatomy of an action"],"href":"/docs/kit/form-actions#Anatomy-of-an-action","content":"Each action receives a RequestEvent object, allowing you to read the data with request.formData(). After processing the request (for example, logging the user in by setting a cookie), the action can respond with data that will be available through the form property on the corresponding page and through page.form app-wide until the next update.import * as db from '$lib/server/db';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ cookies }) {\n\tconst user = await db.getUserFromSession(cookies.get('sessionid'));\n\treturn { user };\n}\n\n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tlogin: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\t\tconst email = data.get('email');\n\t\tconst password = data.get('password');\n\n\t\tconst user = await db.getUser(email);\n\t\tcookies.set('sessionid', await db.createSession(user), { path: '/' });\n\n\t\treturn { success: true };\n\t},\n\tregister: async (event) => {\n\t\t// TODO register the user\n\t}\n};<!--- file: src/routes/login/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data, form } = $props();\n</script>\n\n{#if form?.success}\n\t<!-- this message is ephemeral; it exists because the page was rendered in\n\t       response to a form submission. it will vanish if the user reloads -->\n\t<p>Successfully logged in! Welcome back, {data.user.name}</p>\n{/if}[!LEGACY]\n`PageProps` was added in 2.16.0. In earlier versions, you had to type the `data` and `form` properties individually:\n```js\n/// file: +page.svelte\n/** @type {{ data: import('./$types').PageData, form: import('./$types').ActionData }} */\nlet { data, form } = $props();\n```\n\nIn Svelte 4, you'd use `export let data` and `export let form` instead to declare properties.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Anatomy of an action","Validation errors"],"href":"/docs/kit/form-actions#Anatomy-of-an-action-Validation-errors","content":"If the request couldn't be processed because of invalid data, you can return validation errors — along with the previously submitted form values — back to the user so that they can try again. The fail function lets you return an HTTP status code (typically 400 or 422, in the case of validation errors) along with the data. The status code is available through page.status and the data through form:+++import { fail } from '@sveltejs/kit';+++\nimport * as db from '$lib/server/db';\n\n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tlogin: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\t\tconst email = data.get('email');\n\t\tconst password = data.get('password');\n\n+++\t\tif (!email) {\n\t\t\treturn fail(400, { email, missing: true });\n\t\t}+++\n\n\t\tconst user = await db.getUser(email);\n\n+++\t\tif (!user || user.password !== db.hash(password)) {\n\t\t\treturn fail(400, { email, incorrect: true });\n\t\t}+++\n\n\t\tcookies.set('sessionid', await db.createSession(user), { path: '/' });\n\n\t\treturn { success: true };\n\t},\n\tregister: async (event) => {\n\t\t// TODO register the user\n\t}\n};[!NOTE] Note that as a precaution, we only return the email back to the page — not the password. \n<form method=\"POST\" action=\"?/login\">\n+++\t{#if form?.missing}<p class=\"error\">The email field is required</p>{/if}\n\t{#if form?.incorrect}<p class=\"error\">Invalid credentials!</p>{/if}+++\n\t<label>\n\t\tEmail\n\t\t<input name=\"email\" type=\"email\" +++value={form?.email ?? ''}+++>\n\t</label>\n\t<label>\n\t\tPassword\n\t\t<input name=\"password\" type=\"password\">\n\t</label>\n\t<button>Log in</button>\n\t<button formaction=\"?/register\">Register</button>\n</form>The returned data must be serializable as JSON. Beyond that, the structure is entirely up to you. For example, if you had multiple forms on the page, you could distinguish which <form> the returned form data referred to with an id property or similar.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Anatomy of an action","Redirects"],"href":"/docs/kit/form-actions#Anatomy-of-an-action-Redirects","content":"Redirects (and errors) work exactly the same as in `load`:import { fail, +++redirect+++ } from '@sveltejs/kit';\nimport * as db from '$lib/server/db';\n\n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tlogin: async ({ cookies, request, +++url+++ }) => {\n\t\tconst data = await request.formData();\n\t\tconst email = data.get('email');\n\t\tconst password = data.get('password');\n\n\t\tconst user = await db.getUser(email);\n\t\tif (!user) {\n\t\t\treturn fail(400, { email, missing: true });\n\t\t}\n\n\t\tif (user.password !== db.hash(password)) {\n\t\t\treturn fail(400, { email, incorrect: true });\n\t\t}\n\n\t\tcookies.set('sessionid', await db.createSession(user), { path: '/' });\n\n+++\t\tif (url.searchParams.has('redirectTo')) {\n\t\t\tredirect(303, url.searchParams.get('redirectTo'));\n\t\t}+++\n\n\t\treturn { success: true };\n\t},\n\tregister: async (event) => {\n\t\t// TODO register the user\n\t}\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Loading data"],"href":"/docs/kit/form-actions#Loading-data","content":"After an action runs, the page will be re-rendered (unless a redirect or an unexpected error occurs), with the action's return value available to the page as the form prop. This means that your page's load functions will run after the action completes.Note that handle runs before the action is invoked, and does not rerun before the load functions. This means that if, for example, you use handle to populate event.locals based on a cookie, you must update event.locals when you set or delete the cookie in an action:/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tevent.locals.user = await getUser(event.cookies.get('sessionid'));\n\treturn resolve(event);\n}/** @type {import('./$types').PageServerLoad} */\nexport function load(event) {\n\treturn {\n\t\tuser: event.locals.user\n\t};\n}\n\n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tlogout: async (event) => {\n\t\tevent.cookies.delete('sessionid', { path: '/' });\n\t\tevent.locals.user = null;\n\t}\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Progressive enhancement"],"href":"/docs/kit/form-actions#Progressive-enhancement","content":"In the preceding sections we built a /login action that works without client-side JavaScript — not a fetch in sight. That's great, but when JavaScript is available we can progressively enhance our form interactions to provide a better user experience.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Progressive enhancement","use:enhance"],"href":"/docs/kit/form-actions#Progressive-enhancement-use:enhance","content":"The easiest way to progressively enhance a form is to add the use:enhance action: \n<script>\n\t+++import { enhance } from '$app/forms';+++\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { form } = $props();\n</script>\n\n<form method=\"POST\" +++use:enhance+++>[!NOTE] `use:enhance` can only be used with forms that have `method=\"POST\"` and point to actions defined in a `+page.server.js` file. It will not work with `method=\"GET\"`, which is the default for forms without a specified method. Attempting to use `use:enhance` on forms without `method=\"POST\"` or posting to a `+server.js` endpoint will result in an error.[!NOTE] Yes, it's a little confusing that the `enhance` action and `<form action>` are both called 'action'. These docs are action-packed. Sorry.Without an argument, use:enhance will emulate the browser-native behaviour, just without the full-page reloads. It will:update the `form` property, `page.form` and `page.status` on a successful or invalid response, but only if the action is on the same page you're submitting from. For example, if your form looks like `<form action=\"/somewhere/else\" ..>`, the `form` prop and the `page.form` state will _not_ be updated. This is because in the native form submission case you would be redirected to the page the action is on. If you want to have them updated either way, use [`applyAction`](#Progressive-enhancement-Customising-use:enhance)\nreset the `<form>` element\ninvalidate all data using `invalidateAll` on a successful response\ncall `goto` on a redirect response\nrender the nearest `+error` boundary if an error occurs\n[reset focus](accessibility#Focus-management) to the appropriate element","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Progressive enhancement","Customising use:enhance"],"href":"/docs/kit/form-actions#Progressive-enhancement-Customising-use:enhance","content":"To customise the behaviour, you can provide a SubmitFunction that runs immediately before the form is submitted, and (optionally) returns a callback that runs with the ActionResult.<form\n\tmethod=\"POST\"\n\tuse:enhance={({ formElement, formData, action, cancel, submitter }) => {\n\t\t// `formElement` is this `<form>` element\n\t\t// `formData` is its `FormData` object that's about to be submitted\n\t\t// `action` is the URL to which the form is posted\n\t\t// calling `cancel()` will prevent the submission\n\t\t// `submitter` is the `HTMLElement` that caused the form to be submitted\n\n\t\treturn async ({ result, update }) => {\n\t\t\t// `result` is an `ActionResult` object\n\t\t\t// `update` is a function which triggers the default logic that would be triggered if this callback wasn't set\n\t\t};\n\t}}\n>You can use these functions to show and hide loading UI, and so on.If you return a callback, you override the default post-submission behavior. To get it back, call update, which accepts invalidateAll and reset parameters, or use applyAction on the result: \n<script>\n\timport { enhance, +++applyAction+++ } from '$app/forms';\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { form } = $props();\n</script>\n\n<form\n\tmethod=\"POST\"\n\tuse:enhance={({ formElement, formData, action, cancel }) => {\n\t\treturn async ({ result }) => {\n\t\t\t// `result` is an `ActionResult` object\n+++\t\t\tif (result.type === 'redirect') {\n\t\t\t\tgoto(result.location);\n\t\t\t} else {\n\t\t\t\tawait applyAction(result);\n\t\t\t}+++\n\t\t};\n\t}}\n>The behaviour of applyAction(result) depends on result.type:`success`, `failure` — sets `page.status` to `result.status` and updates `form` and `page.form` to `result.data` (regardless of where you are submitting from, in contrast to `update` from `enhance`)\n`redirect` — calls `goto(result.location, { invalidateAll: true })`\n`error` — renders the nearest `+error` boundary with `result.error`In all cases, focus will be reset.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Progressive enhancement","Custom event listener"],"href":"/docs/kit/form-actions#Progressive-enhancement-Custom-event-listener","content":"We can also implement progressive enhancement ourselves, without use:enhance, with a normal event listener on the <form>:<!--- file: src/routes/login/+page.svelte --->\n<script>\n\timport { invalidateAll, goto } from '$app/navigation';\n\timport { applyAction, deserialize } from '$app/forms';\n\n\t/** @type {import('./$types').PageProps} */\n\tlet { form } = $props();\n\n\t/** @param {SubmitEvent & { currentTarget: EventTarget & HTMLFormElement}} event */\n\tasync function handleSubmit(event) {\n\t\tevent.preventDefault();\n\t\tconst data = new FormData(event.currentTarget, event.submitter);\n\n\t\tconst response = await fetch(event.currentTarget.action, {\n\t\t\tmethod: 'POST',\n\t\t\tbody: data\n\t\t});\n\n\t\t/** @type {import('@sveltejs/kit').ActionResult} */\n\t\tconst result = deserialize(await response.text());\n\n\t\tif (result.type === 'success') {\n\t\t\t// rerun all `load` functions, following the successful update\n\t\t\tawait invalidateAll();\n\t\t}\n\n\t\tapplyAction(result);\n\t}\n</script>\n\n<form method=\"POST\" onsubmit={handleSubmit}>\n\t<!-- content -->\n</form>Note that you need to deserialize the response before processing it further using the corresponding method from $app/forms. JSON.parse() isn't enough because form actions - like load functions - also support returning Date or BigInt objects.If you have a +server.js alongside your +page.server.js, fetch requests will be routed there by default. To POST to an action in +page.server.js instead, use the custom x-sveltekit-action header: \nconst response = await fetch(this.action, {\n\tmethod: 'POST',\n\tbody: data,\n+++\theaders: {\n\t\t'x-sveltekit-action': 'true'\n\t}+++\n});","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Alternatives"],"href":"/docs/kit/form-actions#Alternatives","content":"Form actions are the preferred way to send data to the server, since they can be progressively enhanced, but you can also use `+server.js` files to expose (for example) a JSON API. Here's how such an interaction could look like:<!--- file: src/routes/send-message/+page.svelte --->\n<script>\n\tfunction rerun() {\n\t\tfetch('/api/ci', {\n\t\t\tmethod: 'POST'\n\t\t});\n\t}\n</script>\n\n<button onclick={rerun}>Rerun CI</button> \n \n/** @type {import('./$types').RequestHandler} */\nexport function POST() {\n\t// do something\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","GET vs POST"],"href":"/docs/kit/form-actions#GET-vs-POST","content":"As we've seen, to invoke a form action you must use method=\"POST\".Some forms don't need to POST data to the server — search inputs, for example. For these you can use method=\"GET\" (or, equivalently, no method at all), and SvelteKit will treat them like <a> elements, using the client-side router instead of a full page navigation:<form action=\"/search\">\n\t<label>\n\t\tSearch\n\t\t<input name=\"q\">\n\t</label>\n</form>Submitting this form will navigate to /search?q=... and invoke your load function but will not invoke an action. As with <a> elements, you can set the `data-sveltekit-reload`, `data-sveltekit-replacestate`, `data-sveltekit-keepfocus` and `data-sveltekit-noscroll` attributes on the <form> to control the router's behaviour.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Form actions","Further reading"],"href":"/docs/kit/form-actions#Further-reading","content":"[Tutorial: Forms](/tutorial/kit/the-form-element)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options"],"href":"/docs/kit/page-options","content":"By default, SvelteKit will render (or prerender) any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called _hydration_. For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a _router_ that takes over subsequent navigations.You can control each of these on a page-by-page basis by exporting options from `+page.js` or `+page.server.js`, or for groups of pages using a shared `+layout.js` or `+layout.server.js`. To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered.You can mix and match these options in different areas of your app. For example, you could prerender your marketing page for maximum speed, server-render your dynamic pages for SEO and accessibility and turn your admin section into an SPA by rendering it on the client only. This makes SvelteKit very versatile.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","prerender"],"href":"/docs/kit/page-options#prerender","content":"It's likely that at least some routes of your app can be represented as a simple HTML file generated at build time. These routes can be _prerendered_. \nexport const prerender = true;Alternatively, you can set export const prerender = true in your root +layout.js or +layout.server.js and prerender everything except pages that are explicitly marked as not prerenderable: \nexport const prerender = false;Routes with prerender = true will be excluded from manifests used for dynamic SSR, making your server (or serverless/edge functions) smaller. In some cases you might want to prerender a route but also include it in the manifest (for example, with a route like /blog/[slug] where you want to prerender your most recent/popular content but server-render the long tail) — for these cases, there's a third option, 'auto': \nexport const prerender = 'auto';[!NOTE] If your entire app is suitable for prerendering, you can use [`adapter-static`](adapter-static), which will output files suitable for use with any static webserver.The prerenderer will start at the root of your app and generate files for any prerenderable pages or +server.js routes it finds. Each page is scanned for <a> elements that point to other pages that are candidates for prerendering — because of this, you generally don't need to specify which pages should be accessed. If you do need to specify which pages should be accessed by the prerenderer, you can do so with `config.kit.prerender.entries`, or by exporting an `entries` function from your dynamic route.While prerendering, the value of building imported from `$app/environment` will be true.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","prerender","Prerendering server routes"],"href":"/docs/kit/page-options#prerender-Prerendering-server-routes","content":"Unlike the other page options, prerender also applies to +server.js files. These files are not affected by layouts, but will inherit default values from the pages that fetch data from them, if any. For example if a +page.js contains this load function... \nexport const prerender = true;\n\n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch }) {\n\tconst res = await fetch('/my-server-route.json');\n\treturn await res.json();\n}...then src/routes/my-server-route.json/+server.js will be treated as prerenderable if it doesn't contain its own export const prerender = false.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","prerender","When not to prerender"],"href":"/docs/kit/page-options#prerender-When-not-to-prerender","content":"The basic rule is this: for a page to be prerenderable, any two users hitting it directly must get the same content from the server.[!NOTE] Not all pages are suitable for prerendering. Any content that is prerendered will be seen by all users. You can of course fetch personalized data in `onMount` in a prerendered page, but this may result in a poorer user experience since it will involve blank initial content or loading indicators.Note that you can still prerender pages that load data based on the page's parameters, such as a src/routes/blog/[slug]/+page.svelte route.Accessing `url.searchParams` during prerendering is forbidden. If you need to use it, ensure you are only doing so in the browser (for example in onMount).Pages with actions cannot be prerendered, because a server must be able to handle the action POST requests.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","prerender","Route conflicts"],"href":"/docs/kit/page-options#prerender-Route-conflicts","content":"Because prerendering writes to the filesystem, it isn't possible to have two endpoints that would cause a directory and a file to have the same name. For example, src/routes/foo/+server.js and src/routes/foo/bar/+server.js would try to create foo and foo/bar, which is impossible.For that reason among others, it's recommended that you always include a file extension — src/routes/foo.json/+server.js and src/routes/foo/bar.json/+server.js would result in foo.json and foo/bar.json files living harmoniously side-by-side.For pages, we skirt around this problem by writing foo/index.html instead of foo.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","prerender","Troubleshooting"],"href":"/docs/kit/page-options#prerender-Troubleshooting","content":"If you encounter an error like 'The following routes were marked as prerenderable, but were not prerendered' it's because the route in question (or a parent layout, if it's a page) has export const prerender = true but the page wasn't reached by the prerendering crawler and thus wasn't prerendered.Since these routes cannot be dynamically server-rendered, this will cause errors when people try to access the route in question. There are a few ways to fix it:Ensure that SvelteKit can find the route by following links from [`config.kit.prerender.entries`](configuration#prerender) or the [`entries`](#entries) page option. Add links to dynamic routes (i.e. pages with `[parameters]` ) to this option if they are not found through crawling the other entry points, else they are not prerendered because SvelteKit doesn't know what value the parameters should have. Pages not marked as prerenderable will be ignored and their links to other pages will not be crawled, even if some of them would be prerenderable.\nEnsure that SvelteKit can find the route by discovering a link to it from one of your other prerendered pages that have server-side rendering enabled.\nChange `export const prerender = true` to `export const prerender = 'auto'`. Routes with `'auto'` can be dynamically server rendered","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","entries"],"href":"/docs/kit/page-options#entries","content":"SvelteKit will discover pages to prerender automatically, by starting at entry points and crawling them. By default, all your non-dynamic routes are considered entry points — for example, if you have these routes.../             # non-dynamic\n/blog         # non-dynamic\n/blog/[slug]  # dynamic, because of `[slug]`...SvelteKit will prerender / and /blog, and in the process discover links like <a href=\"/blog/hello-world\"> which give it new pages to prerender.Most of the time, that's enough. In some situations, links to pages like /blog/hello-world might not exist (or might not exist on prerendered pages), in which case we need to tell SvelteKit about their existence.This can be done with `config.kit.prerender.entries`, or by exporting an entries function from a +page.js, a +page.server.js or a +server.js belonging to a dynamic route: \n/** @type {import('./$types').EntryGenerator} */\nexport function entries() {\n\treturn [\n\t\t{ slug: 'hello-world' },\n\t\t{ slug: 'another-blog-post' }\n\t];\n}\n\nexport const prerender = true;entries can be an async function, allowing you to (for example) retrieve a list of posts from a CMS or database, in the example above.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","ssr"],"href":"/docs/kit/page-options#ssr","content":"Normally, SvelteKit renders your page on the server before sending that HTML to the client where it's hydrated. This is also required for prerendering to save the full contents of a page.If you set ssr to false, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server (because you use browser-only globals like document for example), but in most situations it's not recommended (see appendix). \nexport const ssr = false;\n// If both `ssr` and `csr` are `false`, nothing will be rendered!If you add export const ssr = false to your root +layout.js, your entire app will only be rendered on the client — which essentially means you turn your app into an SPA. You should not do this if your goal is to build a statically generated site.[!NOTE] If all your page options are boolean or string literal values, SvelteKit will evaluate them statically. If not, it will import your `+page.js` or `+layout.js` file on the server (both at build time, and at runtime if your app isn't fully static) so it can evaluate the options. In the second case, browser-only code must not run when the module is loaded. In practice, this means you should import browser-only code in your `+page.svelte` or `+layout.svelte` file instead.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","csr"],"href":"/docs/kit/page-options#csr","content":"Ordinarily, SvelteKit hydrates your server-rendered HTML into an interactive client-side-rendered (CSR) page. Some pages don't require JavaScript at all — many blog posts and 'about' pages fall into this category. In these cases you can disable CSR: \nexport const csr = false;\n// If both `csr` and `ssr` are `false`, nothing will be rendered!Disabling CSR does not ship any JavaScript to the client. This means:The webpage should work with HTML and CSS only.\n`<script>` tags inside all Svelte components are removed.\n`<form>` elements cannot be [progressively enhanced](form-actions#Progressive-enhancement).\nLinks are handled by the browser with a full-page navigation.\nHot Module Replacement (HMR) will be disabled.You can enable csr during development (for example to take advantage of HMR) like so: \nimport { dev } from '$app/environment';\n\nexport const csr = dev;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","trailingSlash"],"href":"/docs/kit/page-options#trailingSlash","content":"By default, SvelteKit will remove trailing slashes from URLs — if you visit /about/, it will respond with a redirect to /about. You can change this behaviour with the trailingSlash option, which can be one of 'never' (the default), 'always', or 'ignore'.As with other page options, you can export this value from a +layout.js or a +layout.server.js and it will apply to all child pages. You can also export the configuration from +server.js files. \nexport const trailingSlash = 'always';This option also affects prerendering. If trailingSlash is always, a route like /about will result in an about/index.html file, otherwise it will create about.html, mirroring static webserver conventions.[!NOTE] Ignoring trailing slashes is not recommended — the semantics of relative paths differ between the two cases (`./y` from `/x` is `/y`, but from `/x/` is `/x/y`), and `/x` and `/x/` are treated as separate URLs which is harmful to SEO.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","config"],"href":"/docs/kit/page-options#config","content":"With the concept of adapters, SvelteKit is able to run on a variety of platforms. Each of these might have specific configuration to further tweak the deployment — for example on Vercel you could choose to deploy some parts of your app on the edge and others on serverless environments.config is an object with key-value pairs at the top level. Beyond that, the concrete shape is dependent on the adapter you're using. Every adapter should provide a Config interface to import for type safety. Consult the documentation of your adapter for more information. \n/** @type {import('some-adapter').Config} */\nexport const config = {\n\truntime: 'edge'\n};config objects are merged at the top level (but not deeper levels). This means you don't need to repeat all the values in a +page.js if you want to only override some of the values in the upper +layout.js. For example this layout configuration... \nexport const config = {\n\truntime: 'edge',\n\tregions: 'all',\n\tfoo: {\n\t\tbar: true\n\t}\n}...is overridden by this page configuration... \nexport const config = {\n\tregions: ['us1', 'us2'],\n\tfoo: {\n\t\tbaz: true\n\t}\n}...which results in the config value { runtime: 'edge', regions: ['us1', 'us2'], foo: { baz: true } } for that page.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Page options","Further reading"],"href":"/docs/kit/page-options#Further-reading","content":"[Tutorial: Page options](/tutorial/kit/page-options)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management"],"href":"/docs/kit/state-management","content":"If you're used to building client-only apps, state management in an app that spans server and client might seem intimidating. This section provides tips for avoiding some common gotchas.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","Avoid shared state on the server"],"href":"/docs/kit/state-management#Avoid-shared-state-on-the-server","content":"Browsers are stateful — state is stored in memory as the user interacts with the application. Servers, on the other hand, are stateless — the content of the response is determined entirely by the content of the request.Conceptually, that is. In reality, servers are often long-lived and shared by multiple users. For that reason it's important not to store data in shared variables. For example, consider this code: \n \nlet user;\n\n/** @type {import('./$types').PageServerLoad} */\nexport function load() {\n\treturn { user };\n}\n\n/** @satisfies {import('./$types').Actions} */\nexport const actions = {\n\tdefault: async ({ request }) => {\n\t\tconst data = await request.formData();\n\n\t\t// NEVER DO THIS!\n\t\tuser = {\n\t\t\tname: data.get('name'),\n\t\t\tembarrassingSecret: data.get('secret')\n\t\t};\n\t}\n}The user variable is shared by everyone who connects to this server. If Alice submitted an embarrassing secret, and Bob visited the page after her, Bob would know Alice's secret. In addition, when Alice returns to the site later in the day, the server may have restarted, losing her data.Instead, you should authenticate the user using `cookies` and persist the data to a database.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","No side-effects in load"],"href":"/docs/kit/state-management#No-side-effects-in-load","content":"For the same reason, your load functions should be pure — no side-effects (except maybe the occasional console.log(...)). For example, you might be tempted to write to a store or global state inside a load function so that you can use the value in your components:import { user } from '$lib/user';\n\n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch }) {\n\tconst response = await fetch('/api/user');\n\n\t// NEVER DO THIS!\n\tuser.set(await response.json());\n}As with the previous example, this puts one user's information in a place that is shared by all users. Instead, just return the data... \n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch }) {\n\tconst response = await fetch('/api/user');\n\n+++\treturn {\n\t\tuser: await response.json()\n\t};+++\n}...and pass it around to the components that need it, or use `page.data`.If you're not using SSR, then there's no risk of accidentally exposing one user's data to another. But you should still avoid side-effects in your load functions — your application will be much easier to reason about without them.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","Using state and stores with context"],"href":"/docs/kit/state-management#Using-state-and-stores-with-context","content":"You might wonder how we're able to use page.data and other app state (or app stores) if we can't use global state. The answer is that app state and app stores on the server use Svelte's context API — the state (or store) is attached to the component tree with setContext, and when you subscribe you retrieve it with getContext. We can do the same thing with our own state:<!--- file: src/routes/+layout.svelte --->\n<script>\n\timport { setContext } from 'svelte';\n\n\t/** @type {import('./$types').LayoutProps} */\n\tlet { data } = $props();\n\n\t// Pass a function referencing our state\n\t// to the context for child components to access\n\tsetContext('user', () => data.user);\n</script><!--- file: src/routes/user/+page.svelte --->\n<script>\n\timport { getContext } from 'svelte';\n\n\t// Retrieve user store from context\n\tconst user = getContext('user');\n</script>\n\n<p>Welcome {user().name}</p>[!NOTE] We're passing a function into `setContext` to keep reactivity across boundaries. Read more about it [here](/docs/svelte/$state#Passing-state-into-functions)[!LEGACY]\nYou also use stores from `svelte/store` for this, but when using Svelte 5 it is recommended to make use of universal reactivity instead.Updating the value of context-based state in deeper-level pages or components while the page is being rendered via SSR will not affect the value in the parent component because it has already been rendered by the time the state value is updated. In contrast, on the client (when CSR is enabled, which is the default) the value will be propagated and components, pages, and layouts higher in the hierarchy will react to the new value. Therefore, to avoid values 'flashing' during state updates during hydration, it is generally recommended to pass state down into components rather than up.If you're not using SSR (and can guarantee that you won't need to use SSR in future) then you can safely keep state in a shared module, without using the context API.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","Component and page state is preserved"],"href":"/docs/kit/state-management#Component-and-page-state-is-preserved","content":"When you navigate around your application, SvelteKit reuses existing layout and page components. For example, if you have a route like this...<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n\n\t// THIS CODE IS BUGGY!\n\tconst wordCount = data.content.split(' ').length;\n\tconst estimatedReadingTime = wordCount / 250;\n</script>\n\n<header>\n\t<h1>{data.title}</h1>\n\t<p>Reading time: {Math.round(estimatedReadingTime)} minutes</p>\n</header>\n\n<div>{@html data.content}</div>...then navigating from /blog/my-short-post to /blog/my-long-post won't cause the layout, page and any other components within to be destroyed and recreated. Instead the data prop (and by extension data.title and data.content) will update (as it would with any other Svelte component) and, because the code isn't rerunning, lifecycle methods like onMount and onDestroy won't rerun and estimatedReadingTime won't be recalculated.Instead, we need to make the value _reactive_: \n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data } = $props();\n\n+++\tlet wordCount = $derived(data.content.split(' ').length);\n\tlet estimatedReadingTime = $derived(wordCount / 250);+++\n</script>[!NOTE] If your code in `onMount` and `onDestroy` has to run again after navigation you can use [afterNavigate]($app-navigation#afterNavigate) and [beforeNavigate]($app-navigation#beforeNavigate) respectively.Reusing components like this means that things like sidebar scroll state are preserved, and you can easily animate between changing values. In the case that you do need to completely destroy and remount a component on navigation, you can use this pattern:<script>\n\timport { page } from '$app/state';\n</script>\n\n{#key page.url.pathname}\n\t<BlogPost title={data.title} content={data.title} />\n{/key}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","Storing state in the URL"],"href":"/docs/kit/state-management#Storing-state-in-the-URL","content":"If you have state that should survive a reload and/or affect SSR, such as filters or sorting rules on a table, URL search parameters (like ?sort=price&order=ascending) are a good place to put them. You can put them in <a href=\"...\"> or <form action=\"...\"> attributes, or set them programmatically via goto('?key=value'). They can be accessed inside load functions via the url parameter, and inside components via page.url.searchParams.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","State management","Storing ephemeral state in snapshots"],"href":"/docs/kit/state-management#Storing-ephemeral-state-in-snapshots","content":"Some UI state, such as 'is the accordion open?', is disposable — if the user navigates away or refreshes the page, it doesn't matter if the state is lost. In some cases, you do want the data to persist if the user navigates to a different page and comes back, but storing the state in the URL or in a database would be overkill. For this, SvelteKit provides snapshots, which let you associate component state with a history entry.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions"],"href":"/docs/kit/remote-functions","content":"Remote functions are a tool for type-safe communication between client and server. They can be called anywhere in your app, but always run on the server, meaning they can safely access server-only modules containing things like environment variables and database clients.Combined with Svelte's experimental support for `await`, it allows you to load and manipulate data directly inside your components.This feature is currently experimental, meaning it is likely to contain bugs and is subject to change without notice. You must opt in by adding the compilerOptions.experimental.async and kit.experimental.remoteFunctions options in your svelte.config.js: \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\texperimental: {\n\t\t\t+++remoteFunctions: true+++\n\t\t}\n\t},\n\tcompilerOptions: {\n\t\texperimental: {\n\t\t\t+++async: true+++\n\t\t}\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Overview"],"href":"/docs/kit/remote-functions#Overview","content":"Remote functions are exported from a .remote.js or .remote.ts file, and come in four flavours: query, form, command and prerender. On the client, the exported functions are transformed to fetch wrappers that invoke their counterparts on the server via a generated HTTP endpoint. Remote files can be placed anywhere in your src directory (except inside the src/lib/server directory), and third party libraries can provide them, too.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query"],"href":"/docs/kit/remote-functions#query","content":"The query function allows you to read dynamic data from the server (for static data, consider using `prerender` instead):import { query } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getPosts = query(async () => {\n\tconst posts = await db.sql`\n\t\tSELECT title, slug\n\t\tFROM post\n\t\tORDER BY published_at\n\t\tDESC\n\t`;\n\n\treturn posts;\n});[!NOTE] Throughout this page, you'll see imports from fictional modules like `$lib/server/database` and `$lib/server/auth`. These are purely for illustrative purposes — you can use whatever database client and auth setup you like.\n\nThe `db.sql` function above is a [tagged template function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) that escapes any interpolated values.The query returned from getPosts works as a `Promise` that resolves to posts:<!--- file: src/routes/blog/+page.svelte --->\n<script>\n\timport { getPosts } from './data.remote';\n</script>\n\n<h1>Recent posts</h1>\n\n<ul>\n\t{#each await getPosts() as { title, slug }}\n\t\t<li><a href=\"/blog/{slug}\">{title}</a></li>\n\t{/each}\n</ul>Until the promise resolves — and if it errors — the nearest `<svelte:boundary>` will be invoked.While using await is recommended, as an alternative the query also has loading, error and current properties:<!--- file: src/routes/blog/+page.svelte --->\n<script>\n\timport { getPosts } from './data.remote';\n\n\tconst query = getPosts();\n</script>\n\n<h1>Recent posts</h1>\n\n{#if query.error}\n\t<p>oops!</p>\n{:else if query.loading}\n\t<p>loading...</p>\n{:else}\n\t<ul>\n\t\t{#each query.current as { title, slug }}\n\t\t\t<li><a href=\"/blog/{slug}\">{title}</a></li>\n\t\t{/each}\n\t</ul>\n{/if}[!NOTE] For the rest of this document, we'll use the `await` form.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query","Query arguments"],"href":"/docs/kit/remote-functions#query-Query-arguments","content":"Query functions can accept an argument, such as the slug of an individual post:<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n\timport { getPost } from '../data.remote';\n\n\tlet { params } = $props();\n\n\tconst post = $derived(await getPost(params.slug));\n</script>\n\n<h1>{post.title}</h1>\n<div>{@html post.content}</div>Since getPost exposes an HTTP endpoint, it's important to validate this argument to be sure that it's the correct type. For this, we can use any Standard Schema validation library such as Zod or Valibot:import * as v from 'valibot';\nimport { error } from '@sveltejs/kit';\nimport { query } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getPosts = query(async () => { /* ... */ });\n\nexport const getPost = query(v.string(), async (slug) => {\n\tconst [post] = await db.sql`\n\t\tSELECT * FROM post\n\t\tWHERE slug = ${slug}\n\t`;\n\n\tif (!post) error(404, 'Not found');\n\treturn post;\n});Both the argument and the return value are serialized with devalue, which handles types like Date and Map (and custom types defined in your transport hook) in addition to JSON.[!NOTE] For `query` and `prerender` arguments (but not return values), objects, maps, and sets are sorted so that instances with the same members result in the same cache key. For example, `getPosts({ limit: 10, offset: 10 })` and `getPosts({ offset: 10, limit: 10 })` will result in the same cache key. If order is important to you, you'll have to use an array.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query","Deduplication"],"href":"/docs/kit/remote-functions#query-Deduplication","content":"When you call a query function, SvelteKit serializes the argument you call it with and uses it as a cache key. On the server, this is used to create a request-scoped cache so that multiple invocations of the same query only result in the work happening once. On the client, SvelteKit does something similar: Multiple identical invocations of a query all point to the same instance.You can await a query in any context — components, event handlers, universal load functions, async callbacks — and SvelteKit will dedupe with whatever other consumers are using the same query. For example:<script>\n\timport { getData } from './data.remote.js';\n\n  // awaited inside the component template — populates the cache\n  const data = getData();\n</script>\n\n<p>{await data}</p>\n\n<!-- this dedupes with the component-level use above; no extra request -->\n<button onclick={async () => console.log(await getData())}>\n\tclick me!\n</button>The cache is shared as long as the query is in active use — rendered in a component, currently being awaited, or otherwise referenced. Once nothing is using it, the cached value is released.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query","Refreshing queries"],"href":"/docs/kit/remote-functions#query-Refreshing-queries","content":"Any query can be re-fetched via its refresh method, which retrieves the latest value from the server:<button onclick={() => getPosts().refresh()}>\n\tCheck for new posts\n</button>[!NOTE] Queries are cached while they're on the page, meaning `getPosts() === getPosts()`. This means you don't need a reference like `const posts = getPosts()` in order to update the query.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query.batch"],"href":"/docs/kit/remote-functions#query.batch","content":"query.batch works like query except that it batches requests that happen within the same macrotask. This solves the so-called n+1 problem: rather than each query resulting in a separate database call (for example), simultaneous queries are grouped together.On the server, the callback receives an array of the arguments the function was called with. It must return a function of the form (input: Input, index: number) => Output. SvelteKit will then call this with each of the input arguments to resolve the individual calls with their results.import * as v from 'valibot';\nimport { query } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getWeather = query.batch(v.string(), async (cityIds) => {\n\tconst weather = await db.sql`\n\t\tSELECT * FROM weather\n\t\tWHERE city_id = ANY(${cityIds})\n\t`;\n\tconst lookup = new Map(weather.map(w => [w.city_id, w]));\n\n\treturn (cityId) => lookup.get(cityId);\n});<!--- file: Weather.svelte --->\n<script>\n\timport CityWeather from './CityWeather.svelte';\n\timport { getWeather } from './weather.remote';\n\n\tlet { cities } = $props();\n\tlet limit = $state(5);\n</script>\n\n<h2>Weather</h2>\n\n{#each cities.slice(0, limit) as city}\n\t<h3>{city.name}</h3>\n\t<CityWeather weather={await getWeather(city.id)} />\n{/each}\n\n{#if cities.length > limit}\n\t<button onclick={() => limit += 5}>\n\t\tLoad more\n\t</button>\n{/if}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","query.live"],"href":"/docs/kit/remote-functions#query.live","content":"query.live is for accessing real-time data from the server. It behaves similarly to query, but the callback — typically an async generator function — returns an AsyncIterable:import { query } from '$app/server';\n\nexport const getTime = query.live(async function* () {\n\twhile (true) {\n\t\tyield new Date();\n\t\tawait new Promise((f) => setTimeout(f, 1000));\n\t}\n});During server-side rendering, await getTime() returns the first yielded value then closes the iterator. This initial value is serialized and reused during hydration.On the client, the query stays connected while it's actively used in a component. Multiple instances share a connection. When there are no active uses left, the stream disconnects and server-side iteration is stopped.Live queries expose a connected property and reconnect() method:<script>\n\timport { getTime } from './time.remote.js';\n\n\tconst time = getTime();\n</script>\n\n<p>{await time}</p>\n<p>connected: {time.connected}</p>\n<button onclick={() => time.reconnect()}>Reconnect</button>If the connection drops, connected becomes false. SvelteKit will attempt to reconnect passively, with exponential backoff, and actively if navigator.onLine goes from false to true.Unlike query, live queries do not have a refresh() method, as they are self-updating.If you need direct, imperative access to the underlying stream of values (rather than the reactive current property), live query instances are themselves async-iterable. You can for await over the instance directly:async function logTimes() {\n\tfor await (const value of getTime()) {\n\t\tconsole.log(value);\n\t\tif (someCondition) break;\n\t}\n}Multiple consumers of the same live query (whether reactive — via await or current — or imperative for await loops) share a single underlying connection. The first value yielded to a for await iterator is the most-recently-received value, if one is already available, mirroring the semantics of awaiting the resource directly. Subsequent yields fire whenever a new value arrives from the server. If values arrive faster than the consumer drains the iterator, only the latest pending value is kept — live streams are not event logs.On the server, for await likewise joins a per-request shared iteration of the underlying generator, so concurrent consumers within the same request don't run the user-defined generator multiple times.[!NOTE] It's essential that you don't cache live query responses in a service worker, since the cloned response will continue streaming long after the page is closed. Make sure that your caching logic excludes any responses with a `Cache-Control` header that includes `no-store`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form"],"href":"/docs/kit/remote-functions#form","content":"The form function makes it easy to write data to the server. It takes a callback that receives data constructed from the submitted `FormData`...import * as v from 'valibot';\nimport { error, redirect } from '@sveltejs/kit';\nimport { query, form } from '$app/server';\nimport * as db from '$lib/server/database';\nimport * as auth from '$lib/server/auth';\n\nexport const getPosts = query(async () => { /* ... */ });\n\nexport const getPost = query(v.string(), async (slug) => { /* ... */ });\n\nexport const createPost = form(\n\tv.object({\n\t\ttitle: v.pipe(v.string(), v.nonEmpty()),\n\t\tcontent:v.pipe(v.string(), v.nonEmpty())\n\t}),\n\tasync ({ title, content }) => {\n\t\t// Check the user is logged in\n\t\tconst user = await auth.getUser();\n\t\tif (!user) error(401, 'Unauthorized');\n\n\t\tconst slug = title.toLowerCase().replace(/ /g, '-');\n\n\t\t// Insert into the database\n\t\tawait db.sql`\n\t\t\tINSERT INTO post (slug, title, content)\n\t\t\tVALUES (${slug}, ${title}, ${content})\n\t\t`;\n\n\t\t// Redirect to the newly created page\n\t\tredirect(303, `/blog/${slug}`);\n\t}\n);...and returns an object that can be spread onto a <form> element. The callback is called whenever the form is submitted.<!--- file: src/routes/blog/new/+page.svelte --->\n<script>\n\timport { createPost } from '../data.remote';\n</script>\n\n<h1>Create a new post</h1>\n\n<form {...createPost}>\n\t<!-- form content goes here -->\n\n\t<button>Publish!</button>\n</form>The form object contains method and action properties that allow it to work without JavaScript (i.e. it submits data and reloads the page). It also has an attachment that progressively enhances the form when JavaScript is available, submitting data without reloading the entire page.As with query, if the callback uses the submitted data, it should be validated by passing a Standard Schema as the first argument to form.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Fields"],"href":"/docs/kit/remote-functions#form-Fields","content":"A form is composed of a set of fields, which are defined by the schema. In the case of createPost, we have two fields, title and content, which are both strings. To get the attributes for a field, call its .as(...) method, specifying which input type to use. For most input types, you can also pass a second argument — .as(type, value) — to control the rendered value:<form {...createPost}>\n\t<label>\n\t\t<h2>Title</h2>\n\t\t+++<input {...createPost.fields.title.as('text')} />+++\n\t</label>\n\n\t<label>\n\t\t<h2>Write your post</h2>\n\t\t+++<textarea {...createPost.fields.content.as('text')}></textarea>+++\n\t</label>\n\n\t<button>Publish!</button>\n</form>These attributes allow SvelteKit to set the correct input type, set a name that is used to construct the data passed to the handler, populate the value of the form (for example following a failed submission, to save the user having to re-enter everything), and set the `aria-invalid` state.Passing a second argument to .as(...) is useful when rendering a form from existing data, such as an edit form or multiple instances created with `for(...)`. radio, submit and hidden inputs always need this value, and checkbox inputs need it when they represent one option in an array field. file inputs cannot be populated this way.[!NOTE] The generated `name` attribute uses JS object notation (e.g. `nested.array[0].value`). String keys that require quotes such as `object['nested-array'][0].value` are not supported. Under the hood, boolean checkbox and number field names are prefixed with `b:` and `n:`, respectively, to signal SvelteKit to coerce the values from strings prior to validation.Fields can be nested in objects and arrays, and their values can be strings, numbers, booleans or File objects. For example, if your schema looked like this...const datingProfile = v.object({\n\tname: v.string(),\n\tphoto: v.file(),\n\tinfo: v.object({\n\t\theight: v.number(),\n\t\tlikesDogs: v.optional(v.boolean(), false)\n\t}),\n\tattributes: v.array(v.string())\n});\n\nexport const createProfile = form(datingProfile, (data) => { /* ... */ });...your form could look like this:<script>\n\timport { createProfile } from './data.remote';\n\n\tconst { name, photo, info, attributes } = createProfile.fields;\n</script>\n\n<form {...createProfile} enctype=\"multipart/form-data\">\n\t<label>\n\t\t<input {...name.as('text')} /> Name\n\t</label>\n\n\t<label>\n\t\t<input {...photo.as('file')} /> Photo\n\t</label>\n\n\t<label>\n\t\t<input {...info.height.as('number')} /> Height (cm)\n\t</label>\n\n\t<label>\n\t\t<input {...info.likesDogs.as('checkbox')} /> I like dogs\n\t</label>\n\n\t<h2>My best attributes</h2>\n\t<input {...attributes[0].as('text')} />\n\t<input {...attributes[1].as('text')} />\n\t<input {...attributes[2].as('text')} />\n\n\t<button>submit</button>\n</form>Because our form contains a file input, we've added an enctype=\"multipart/form-data\" attribute. The values for info.height and info.likesDogs are coerced to a number and a boolean respectively.[!NOTE] If a `checkbox` input is unchecked, the value is not included in the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object that SvelteKit constructs the data from. As such, we have to make the value optional in our schema. In Valibot that means using `v.optional(v.boolean(), false)` instead of just `v.boolean()`, whereas in Zod it would mean using `z.coerce.boolean<boolean>()`.In the case of radio and checkbox inputs that all belong to the same field, the value must be specified as a second argument to .as(...): \nexport const operatingSystems = /** @type {const} */ (['windows', 'mac', 'linux']);\nexport const languages = /** @type {const} */ (['html', 'css', 'js']);import { operatingSystems, languages } from './constants';\n\nexport const survey = form(\n\tv.object({\n\t\toperatingSystem: v.picklist(operatingSystems),\n\t\tlanguages: v.optional(v.array(v.picklist(languages)), []),\n\t}),\n\t(data) => { /* ... */ },\n);<form {...survey}>\n\t<h2>Which operating system do you use?</h2>\n\n\t{#each operatingSystems as os}\n\t\t<label>\n\t\t\t<input {...survey.fields.operatingSystem.as('radio', os)}>\n\t\t\t{os}\n\t\t</label>\n\t{/each}\n\n\t<h2>Which languages do you write code in?</h2>\n\n\t{#each languages as language}\n\t\t<label>\n\t\t\t<input {...survey.fields.languages.as('checkbox', language)}>\n\t\t\t{language}\n\t\t</label>\n\t{/each}\n\n\t<button>submit</button>\n</form>Alternatively, you could use select and select multiple:<form {...survey}>\n\t<h2>Which operating system do you use?</h2>\n\n\t<select {...survey.fields.operatingSystem.as('select')}>\n\t\t{#each operatingSystems as os}\n\t\t\t<option>{os}</option>\n\t\t{/each}\n\t</select>\n\n\t<h2>Which languages do you write code in?</h2>\n\n\t<select {...survey.fields.languages.as('select multiple')}>\n\t\t{#each languages as language}\n\t\t\t<option>{language}</option>\n\t\t{/each}\n\t</select>\n\n\t<button>submit</button>\n</form>[!NOTE] As with unchecked `checkbox` inputs, if no selections are made then the data will be `undefined`. For this reason, the `languages` field uses `v.optional(v.array(...), [])` rather than just `v.array(...)`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Programmatic validation"],"href":"/docs/kit/remote-functions#form-Programmatic-validation","content":"In addition to declarative schema validation, you can programmatically mark fields as invalid inside the form handler using the invalid helper from @sveltejs/kit. This is useful for cases where you can't know if something is valid until you try to perform some action.It throws just like `redirect` or `error`\nIt accepts multiple arguments that can be strings (for issues relating to the form as a whole — these will only show up in `fields.allIssues()`) or standard-schema-compliant issues (for those relating to a specific field). Use the `issue` parameter for type-safe creation of such issues:import * as v from 'valibot';\nimport { invalid } from '@sveltejs/kit';\nimport { form } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const buyHotcakes = form(\n\tv.object({\n\t\tqty: v.pipe(\n\t\t\tv.number(),\n\t\t\tv.minValue(1, 'you must buy at least one hotcake')\n\t\t)\n\t}),\n\tasync (data, issue) => {\n\t\ttry {\n\t\t\tawait db.buy(data.qty);\n\t\t} catch (e) {\n\t\t\tif (e.code === 'OUT_OF_STOCK') {\n\t\t\t\tinvalid(\n\t\t\t\t\tissue.qty(`we don't have enough hotcakes`)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n);","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Validation"],"href":"/docs/kit/remote-functions#form-Validation","content":"If the submitted data doesn't pass the schema, the callback will not run. Instead, each invalid field's issues() method will return an array of { message: string } objects, and the aria-invalid attribute (returned from as(...)) will be set to true:<form {...createPost}>\n\t<label>\n\t\t<h2>Title</h2>\n\n+++\t\t{#each createPost.fields.title.issues() as issue}\n\t\t\t<p class=\"issue\">{issue.message}</p>\n\t\t{/each}+++\n\n\t\t<input {...createPost.fields.title.as('text')} />\n\t</label>\n\n\t<label>\n\t\t<h2>Write your post</h2>\n\n+++\t\t{#each createPost.fields.content.issues() as issue}\n\t\t\t<p class=\"issue\">{issue.message}</p>\n\t\t{/each}+++\n\n\t\t<textarea {...createPost.fields.content.as('text')}></textarea>\n\t</label>\n\n\t<button>Publish!</button>\n</form>You don't need to wait until the form is submitted to validate the data — you can call validate() programmatically, for example in an oninput callback (which will validate the data on every keystroke) or an onchange callback:<form {...createPost} oninput={() => createPost.validate()}>\n\t<!-- -->\n</form>By default, issues will be ignored if they belong to form controls that haven't yet been interacted with. To validate all inputs, call validate({ includeUntouched: true }).For client-side validation, you can specify a preflight schema which will populate issues() and prevent data being sent to the server if the data doesn't validate:<script>\n\timport * as v from 'valibot';\n\timport { createPost } from '../data.remote';\n\n\tconst schema = v.object({\n\t\ttitle: v.pipe(v.string(), v.nonEmpty()),\n\t\tcontent: v.pipe(v.string(), v.nonEmpty())\n\t});\n</script>\n\n<h1>Create a new post</h1>\n\n<form {...+++createPost.preflight(schema)+++}>\n\t<!-- -->\n</form>[!NOTE] The preflight schema can be the same object as your server-side schema, if appropriate, though it won't be able to do server-side checks like 'this value already exists in the database'. Note that you cannot export a schema from a `.remote.ts` or `.remote.js` file, so the schema must either be exported from a shared module, or from a `<script module>` block in the component containing the `<form>`.To get a list of all issues, rather than just those belonging to a single field, you can use the fields.allIssues() method:{#each createPost.fields.allIssues() as issue}\n\t<p>{issue.message}</p>\n{/each}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Getting/setting inputs"],"href":"/docs/kit/remote-functions#form-Getting-setting-inputs","content":"Each field has a value() method that reflects its current value. As the user interacts with the form, it is automatically updated:<form {...createPost}>\n\t<!-- -->\n</form>\n\n<div class=\"preview\">\n\t<h2>{createPost.fields.title.value()}</h2>\n\t<div>{@html render(createPost.fields.content.value())}</div>\n</div>Alternatively, createPost.fields.value() would return a { title, content } object.You can update a field (or a collection of fields) via the set(...) method:<script>\n\timport { createPost } from '../data.remote';\n\n\t// this...\n\tcreatePost.fields.set({\n\t\ttitle: 'My new blog post',\n\t\tcontent: 'Lorem ipsum dolor sit amet...'\n\t});\n\n\t// ...is equivalent to this:\n\tcreatePost.fields.title.set('My new blog post');\n\tcreatePost.fields.content.set('Lorem ipsum dolor sit amet');\n</script>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Handling sensitive data"],"href":"/docs/kit/remote-functions#form-Handling-sensitive-data","content":"In the case of a non-progressively-enhanced form submission (i.e. where JavaScript is unavailable, for whatever reason) value() is also populated if the submitted data is invalid, so that the user does not need to fill the entire form out from scratch.You can prevent sensitive data (such as passwords and credit card numbers) from being sent back to the user by using a name with a leading underscore:<form {...register}>\n\t<label>\n\t\tUsername\n\t\t<input {...register.fields.username.as('text')} />\n\t</label>\n\n\t<label>\n\t\tPassword\n\t\t<input +++{...register.fields._password.as('password')}+++ />\n\t</label>\n\n\t<button>Sign up!</button>\n</form>In this example, if the data does not validate, only the first <input> will be populated when the page reloads.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Returns and redirects"],"href":"/docs/kit/remote-functions#form-Returns-and-redirects","content":"The example above uses `redirect(...)`, which sends the user to the newly created page. Alternatively, the callback could return data, in which case it would be available as createPost.result:export const createPost = form(\n\tv.object({/* ... */}),\n\tasync (data) => {\n\t\t// ...\n\n\t\treturn { success: true };\n\t}\n);<!--- file: src/routes/blog/new/+page.svelte --->\n<script>\n\timport { createPost } from '../data.remote';\n</script>\n\n<h1>Create a new post</h1>\n\n<form {...createPost}>\n\t<!-- -->\n</form>\n\n{#if createPost.result?.success}\n\t<p>Successfully published!</p>\n{/if}This value is ephemeral — it will vanish if you resubmit, navigate away, or reload the page.[!NOTE] The `result` value need not indicate success — it can also contain validation errors, along with any data that should repopulate the form on page reload.If an error occurs during submission, the nearest +error.svelte page will be rendered.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","enhance"],"href":"/docs/kit/remote-functions#form-enhance","content":"We can customize what happens when the form is submitted with the enhance method:<!--- file: src/routes/blog/new/+page.svelte --->\n<script>\n\timport { createPost } from '../data.remote';\n\timport { showToast } from '$lib/toast';\n</script>\n\n<h1>Create a new post</h1>\n\n<form {...createPost.enhance(async (form) => {\n\ttry {\n\t\tif (await form.submit()) {\n\t\t\tform.element.reset();\n\n\t\t\tshowToast('Successfully published!');\n\t\t} else {\n\t\t\tshowToast('Invalid data!');\n\t\t}\n\t} catch (error) {\n\t\tshowToast('Oh no! Something went wrong');\n\t}\n})}>\n\t<!-- -->\n</form>[!NOTE] When using `enhance`, the `<form>` is not automatically reset — you must call `form.element.reset()` if you want to clear the inputs.The callback receives a copy of the form instance. It has all the same properties and methods except enhance, and form.submit() performs the submission directly without re-running the enhance callback. Inside the callback, form.element is always defined.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Multiple instances of a form"],"href":"/docs/kit/remote-functions#form-Multiple-instances-of-a-form","content":"Some forms may be repeated as part of a list. In this case you can create separate instances of a form function via for(id) to achieve isolation.When each instance should render different values, pass them as the second argument to .as(...):<!--- file: src/routes/todos/+page.svelte --->\n<script>\n\timport { getTodos, modifyTodo } from '../data.remote';\n</script>\n\n<h1>Todos</h1>\n\n{#each await getTodos() as todo}\n\t{@const modify = modifyTodo.for(todo.id)}\n\t<form {...modify}>\n\t\t<input {...modify.fields.description.as('text', todo.description)} />\n\t\t<button disabled={!!modify.pending}>save changes</button>\n\t</form>\n{/each}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","form","Multiple submit buttons"],"href":"/docs/kit/remote-functions#form-Multiple-submit-buttons","content":"It's possible for a <form> to have multiple submit buttons. For example, you might have a single form that allows you to log in or register depending on which button was clicked.To accomplish this, add a field to your schema for the button value, and use as('submit', value) to bind it:<!--- file: src/routes/login/+page.svelte --->\n<script>\n\timport { loginOrRegister } from '$lib/auth';\n</script>\n\n<form {...loginOrRegister}>\n\t<label>\n\t\tYour username\n\t\t<input {...loginOrRegister.fields.username.as('text')} />\n\t</label>\n\n\t<label>\n\t\tYour password\n\t\t<input {...loginOrRegister.fields._password.as('password')} />\n\t</label>\n\n\t<button {...loginOrRegister.fields.action.as('submit', 'login')}>login</button>\n\t<button {...loginOrRegister.fields.action.as('submit', 'register')}>register</button>\n</form>In your form handler, you can check which button was clicked: \nimport * as v from 'valibot';\nimport { form } from '$app/server';\n\nexport const loginOrRegister = form(\n\tv.object({\n\t\tusername: v.string(),\n\t\t_password: v.string(),\n\t\taction: v.picklist(['login', 'register'])\n\t}),\n\tasync ({ username, _password, action }) => {\n\t\tif (action === 'login') {\n\t\t\t// handle login\n\t\t} else {\n\t\t\t// handle registration\n\t\t}\n\t}\n);","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","command"],"href":"/docs/kit/remote-functions#command","content":"The command function, like form, allows you to write data to the server. Unlike form, it's not specific to an element and can be called from anywhere.[!NOTE] Prefer `form` where possible, since it gracefully degrades if JavaScript is disabled or fails to load.As with query and form, if the function accepts an argument, it should be validated by passing a Standard Schema as the first argument to command.import * as v from 'valibot';\nimport { query, command } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getLikes = query(v.string(), async (id) => {\n\tconst [row] = await db.sql`\n\t\tSELECT likes\n\t\tFROM item\n\t\tWHERE id = ${id}\n\t`;\n\n\treturn row.likes;\n});\n\nexport const addLike = command(v.string(), async (id) => {\n\tawait db.sql`\n\t\tUPDATE item\n\t\tSET likes = likes + 1\n\t\tWHERE id = ${id}\n\t`;\n});Now simply call addLike, from (for example) an event handler:<!--- file: +page.svelte --->\n<script>\n\timport { getLikes, addLike } from './likes.remote';\n\timport { showToast } from '$lib/toast';\n\n\tlet { item } = $props();\n</script>\n\n<button\n\tonclick={async () => {\n\t\ttry {\n\t\t\tawait addLike(item.id);\n\t\t} catch (error) {\n\t\t\tshowToast('Something went wrong!');\n\t\t}\n\t}}\n>\n\tadd like\n</button>\n\n<p>likes: {await getLikes(item.id)}</p>[!NOTE] Commands cannot be called during render.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Single-flight mutations"],"href":"/docs/kit/remote-functions#Single-flight-mutations","content":"The purpose of both `form` and `command` is mutating data. In many cases, mutating data invalidates other data. By default, form deals with this by automatically invalidating all queries and load functions following a successful submission, to emulate what would happen with a traditional full-page reload. command, on the other hand, does nothing. Typically, neither of these options is going to be the ideal solution — invalidating everything is likely wasteful, as it's unlikely a form submission changed everything being displayed on your webpage. In the case of command, doing nothing likely under-invalidates your app, leaving stale data displayed. In both cases, it's common to have to perform two round-trips to the server: One to run the mutation, and another after that completes to re-request the data from any queries you need to refresh.SvelteKit solves both of these problems with single-flight mutations: Your form submission or command invocation can refresh queries and pass their results back to the client in a single request.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Single-flight mutations","Server-driven refreshes"],"href":"/docs/kit/remote-functions#Single-flight-mutations-Server-driven-refreshes","content":"In most circumstances, the server handler knows what client data needs to be updated based on its arguments:export const getPosts = query(async () => { /* ... */ });\n\nexport const getPost = query(v.string(), async (slug) => { /* ... */ });\n\nexport const createPost = form(\n\tv.object({/* ... */}),\n\tasync (data) => {\n\t\t// form logic goes here...\n\n\t\t// Refresh `getPosts()` on the server, and send\n\t\t// the data back with the result of `createPost`\n\t\t// it's safe to throw away the promise from `refresh`,\n\t\t// as the framework awaits it for us before serving the response\n\t\t+++void getPosts().refresh();+++\n\n\t\t// Redirect to the newly created page\n\t\tredirect(303, `/blog/${slug}`);\n\t}\n);\n\nexport const updatePost = form(\n\tv.object({ id: v.string() }),\n\tasync (post) => {\n\t\t// form logic goes here...\n\t\tconst result = externalApi.update(post);\n\n\t\t// The API already gives us the updated post,\n\t\t// no need to refresh it, we can set it directly\n\t\t+++getPost(post.id).set(result);+++\n\t}\n);Because queries are keyed based on their arguments, getPost(post.id).set(result) on the server knows to look up the matching getPost(id) on the client to update it. The same goes for getPosts().refresh() -- it knows to look up getPosts() with no argument on the client.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Single-flight mutations","Reconnecting live queries in mutations"],"href":"/docs/kit/remote-functions#Single-flight-mutations-Reconnecting-live-queries-in-mutations","content":"Single-flight mutations can also reconnect query.live instances. In a form/command handler, call .reconnect() on the live query resource you want to reconnect:import * as v from 'valibot';\nimport { form, query } from '$app/server';\n\nexport const getNotifications = query.live(v.string(), async function* (userId) {\n\twhile (true) {\n\t\tyield await db.notifications(userId);\n\t\tawait wait(1000);\n\t}\n});\n\nexport const markAllRead = form(v.object({ userId: v.string() }), async ({ userId }) => {\n\t// mutation logic...\n\t+++getNotifications(userId).reconnect();+++\n});This schedules a reconnect for the matching active client instances and applies it as part of the mutation response (i.e. in the same flight as the form/command result). You might need this if, for example, the command modifies a cookie that the live query needs to restart in order to capture.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Single-flight mutations","Client-requested refreshes"],"href":"/docs/kit/remote-functions#Single-flight-mutations-Client-requested-refreshes","content":"Unfortunately, life isn't always as simple as the preceding example. The server always knows which query functions to update, but it may not know which specific query instances to update. For example, if getPosts({ filter: 'author:santa' }) is rendered on the client, calling getPosts().refresh() in the server handler won't update it. You'd need to call getPosts({ filter: 'author:santa' }).refresh() instead — but how could you know which specific combinations of filters are currently rendered on the client, especially if your query argument is more complicated than an object with just one key?SvelteKit makes this easy by allowing the client to request that the server updates specific data using submit().updates (for form) or myCommand().updates (for command):await submit().updates(\n\t// to request all active instances of getPosts\n\tgetPosts,\n\t// to request a specific instance\n\tgetPosts({ filter: 'author:santa' }),\n\t// to request a specific instance with an optimistic override\n\tgetPosts({ filter: 'author:santa' }).withOverride((posts) => [newPost, ...posts])\n);It's not enough to just request the updates from the client -- you need to accept them from the server as well:import { query, form, requested } from '$app/server';\n\nexport const getPosts = query(v.object({ filter: v.string() }), async ({ filter }) => { /* ... */ });\n\nexport const createPost = form(\n\tv.object({/* ... */}),\n\tasync (data) => {\n\t\t// form logic goes here...\n\n\t\t+++for (const { query } of requested(getPosts, 1)) {+++\n\t\t+++\tvoid query.refresh();+++\n\t\t+++}+++\n\n\t\t// Redirect to the newly created page\n\t\tredirect(303, `/blog/${slug}`);\n\t}\n);requested gives you access to the queries the client requested to refresh. Each entry is an { arg, query } object: arg is the value the query's implementation function received — i.e. the argument after the schema has validated and (where applicable) transformed it — and query is a RemoteQuery already bound to the client's original cache key, so calling query.refresh() / query.set(...) updates the correct client instance. If parsing an argument fails, that query will error, but the entire command will not fail. requested's second parameter, limit, is the maximum number of items it will return. Any refresh requests beyond this limit will fail.[!NOTE] `limit` is required because the list of refresh requests is controlled by the client — each entry causes the server to validate an argument and usually re-fetch data, so an unbounded list is a denial-of-service risk. Choose a limit that reflects the worst case you're willing to handle per request. You _can_ pass `Infinity` if you have explicitly decided to accept any number of refreshes, but it is not recommended.Additionally, requested allows a simple shorthand when all you want to do is refresh the requested query instances:// this is the same as looping over the result and calling `void query.refresh()`.\nawait requested(getPosts, 1).refreshAll();[!NOTE] Why does the command have to name every query it's willing to refresh? Two reasons:\n\n- **Bundle size.** If a command could implicitly refresh *any* query in your app, SvelteKit would have to include every query's code in the command's server bundle, because it can't know ahead of time which ones will be called.\n- **Denial-of-service.** Any malicious user can inspect their network tab to discover which queries your app uses, then POST a command with a client-supplied list of thousands of refreshes. The only defence is for the server handler to declare which queries it is willing to refresh — and in what quantity (hence the required `limit`).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","prerender"],"href":"/docs/kit/remote-functions#prerender","content":"The prerender function is similar to query, except that it will be invoked at build time to prerender the result. Use this for data that changes at most once per redeployment.import { prerender } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getPosts = prerender(async () => {\n\tconst posts = await db.sql`\n\t\tSELECT title, slug\n\t\tFROM post\n\t\tORDER BY published_at\n\t\tDESC\n\t`;\n\n\treturn posts;\n});You can use prerender functions on pages that are otherwise dynamic, allowing for partial prerendering of your data. This results in very fast navigation, since prerendered data can live on a CDN along with your other static assets.In the browser, prerendered data is saved using the `Cache` API. This cache survives page reloads, and will be cleared when the user first visits a new deployment of your app.[!NOTE] When the entire page has `export const prerender = true`, you cannot use queries, as they are dynamic.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","prerender","Prerender arguments"],"href":"/docs/kit/remote-functions#prerender-Prerender-arguments","content":"As with queries, prerender functions can accept an argument, which should be validated with a Standard Schema:import * as v from 'valibot';\nimport { error } from '@sveltejs/kit';\nimport { prerender } from '$app/server';\nimport * as db from '$lib/server/database';\n\nexport const getPosts = prerender(async () => { /* ... */ });\n\nexport const getPost = prerender(v.string(), async (slug) => {\n\tconst [post] = await db.sql`\n\t\tSELECT * FROM post\n\t\tWHERE slug = ${slug}\n\t`;\n\n\tif (!post) error(404, 'Not found');\n\treturn post;\n});Any calls to getPost(...) found by SvelteKit's crawler while prerendering pages will be saved automatically, but you can also specify which values it should be called with using the inputs option:\nexport const getPost = prerender(\n\tv.string(),\n\tasync (slug) => { /* ... */ },\n\t{\n\t\tinputs: () => [\n\t\t\t'first-post',\n\t\t\t'second-post',\n\t\t\t'third-post'\n\t\t]\n\t}\n);By default, prerender functions are excluded from your server bundle, which means that you cannot call them with any arguments that were not prerendered. You can set dynamic: true to change this behaviour:\nexport const getPost = prerender(\n\tv.string(),\n\tasync (slug) => { /* ... */ },\n\t{\n\t\t+++dynamic: true+++,\n\t\tinputs: () => [\n\t\t\t'first-post',\n\t\t\t'second-post',\n\t\t\t'third-post'\n\t\t]\n\t}\n);","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Handling validation errors"],"href":"/docs/kit/remote-functions#Handling-validation-errors","content":"As long as you're not passing invalid data to your remote functions, there are only two reasons why the argument passed to a command, query or prerender function would fail validation:the function signature changed between deployments, and some users are currently on an older version of your app\nsomeone is trying to attack your site by poking your exposed endpoints with bad dataIn the second case, we don't want to give the attacker any help, so SvelteKit will generate a generic 400 Bad Request response. You can control the message by implementing the `handleValidationError` server hook, which, like `handleError`, must return an `App.Error` (which defaults to { message: string }): \n/** @type {import('@sveltejs/kit').HandleValidationError} */\nexport function handleValidationError({ event, issues }) {\n\treturn {\n\t\tmessage: 'Nice try, hacker!'\n\t};\n}If you know what you're doing and want to opt out of validation, you can pass the string 'unchecked' in place of a schema: \nimport { query } from '$app/server';\n\nexport const getStuff = query('unchecked', async ({ id }: { id: string }) => {\n\t// the shape might not actually be what TypeScript thinks\n\t// since bad actors might call this function with other arguments\n});","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Using `getRequestEvent`"],"href":"/docs/kit/remote-functions#Using-getRequestEvent","content":"Inside query, form and command you can use `getRequestEvent` to get the current `RequestEvent` object. This makes it easy to build abstractions for interacting with cookies, for example:import { getRequestEvent, query } from '$app/server';\nimport { findUser } from '$lib/server/database';\n\nexport const getProfile = query(async () => {\n\tconst user = await getUser();\n\n\treturn user && {\n\t\tname: user.name,\n\t\tavatar: user.avatar\n\t};\n});\n\n// this query could be called from multiple places, but\n// the function will only run once per request\nconst getUser = query(async () => {\n\tconst { cookies } = getRequestEvent();\n\n\treturn await findUser(cookies.get('session_id'));\n});Note that some properties of RequestEvent are different inside remote functions:you cannot set headers (other than writing cookies, and then only inside `form` and `command` functions)\n`route`, `params` and `url` relate to the page the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Queries are not re-run when the user navigates (unless the argument to the query changes as a result of navigation), and so you should be mindful of how you use these values. In particular, never use them to determine whether or not a user is authorized to access certain data.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Remote functions","Redirects"],"href":"/docs/kit/remote-functions#Redirects","content":"Inside query, form and prerender functions it is possible to use the `redirect(...)` function. It is not possible inside command functions, as you should avoid redirecting here. (If you absolutely have to, you can return a { redirect: location } object and deal with it in the client.)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables"],"href":"/docs/kit/environment-variables","content":"Environment variables are values your app needs that exist separately from the app's source code. They allow you to use sensitive information like API keys and database credentials without storing them in version control.During development, and at build time, variables defined in a .env or .env.local file will be added to the environment: \nAPI_KEY=19f401ba-e8b0-48c4-8c77-b0ebb26d97feBy default, every environment variable is implicitly available inside your app via the following modules:[`$env/static/private`]($env-static-private)\n[`$env/static/public`]($env-static-public)\n[`$env/dynamic/private`]($env-dynamic-private)\n[`$env/dynamic/public`]($env-dynamic-public)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables"],"href":"/docs/kit/environment-variables#Explicit-environment-variables","content":"As of SvelteKit 2.63, you can opt into explicit environment variables, in which case you instead import environment variables from these modules:[`$app/env/private`]($app-env-private)\n[`$app/env/public`]($app-env-public)Additionally, the `$app/environment` module is renamed to `$app/env`.[!NOTE] Explicit environment variables will become the default in SvelteKit 3. The `$env/*` modules, along with `$app/environment`, will be removed.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Setup"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Setup","content":"To opt in, update your configuration... \nexport default {\n\tkit: {\n\t\texperimental: {\n\t\t\t+++explicitEnvironmentVariables: true+++\n\t\t}\n\t}\n};...and add a src/env.ts (or src/env.js) file that exports a variables object: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\n\nexport const variables = defineEnvVars({\n\t// ...\n});Each value in the object passed to `defineEnvVars` is an `EnvVarConfig` object that configures the environment variable.[!NOTE] `defineEnvVars` returns its argument unaltered — it exists purely to help with type safety.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Private variables"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Private-variables","content":"By default, all variables are considered private. For example, you don't want to reveal your API_KEY: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\n\nexport const variables = defineEnvVars({\n\t+++API_KEY: {}+++\n});[!NOTE] Since no configuration is needed for this variable, we can use an empty object (`{}`).Now that API_KEY is defined, it can be imported into app code via $app/env/private:import { API_KEY } from '$app/env/private';The $app/env/private module cannot be imported into code that runs in the browser, so that you can't accidentally reveal your secrets in a JavaScript bundle.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Public variables"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Public-variables","content":"Some variables are perfectly safe — necessary, even — to expose to the browser. For these, we can specify public: true: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\n\nexport const variables = defineEnvVars({\n\tGOOGLE_ANALYTICS_ID: {\n\t\t+++public: true+++\n\t}\n});GOOGLE_ANALYTICS_ID can now be imported from $app/env/public, or used in your app.html template as %sveltekit.env.GOOGLE_ANALYTICS_ID%:<!--- file: src/app.html --->\n<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"%sveltekit.assets%/favicon.png\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t%sveltekit.head%\n\n\t\t<script\n\t\t\tasync\n\t\t\tsrc=\"https://www.googletagmanager.com/gtag/js?id=+++%sveltekit.env.GOOGLE_ANALYTICS_ID%+++\"\n\t\t></script>\n\n\t\t<script>\n\t\t\twindow.dataLayer ??= [];\n\t\t\tfunction gtag(){dataLayer.push(arguments)}\n\t\t\tgtag('js', new Date());\n\t\t\tgtag('config', +++'%sveltekit.env.GOOGLE_ANALYTICS_ID%'+++);\n\t\t</script>\n\t</head>\n\t<body data-sveltekit-preload-data=\"hover\">\n\t\t<div style=\"display: contents\">%sveltekit.body%</div>\n\t</body>\n</html>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Validation"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Validation","content":"You can specify a Standard Schema validator such as Zod or Valibot to check that an environment variable value is correct: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\n+++import * as v from 'valibot';+++\n\nexport const variables = defineEnvVars({\n\tGOOGLE_ANALYTICS_ID: {\n\t\tpublic: true,\n\t\t+++validate: v.pipe(v.string(), v.regex(/G-[A-Z0-9]+/))+++\n\t}\n});If a value is invalid, the app will fail to start (or build).You can use validators to make values optional, or transform them (such as turning a string into a boolean, or parsing JSON) — see your validation library's documentation to learn how.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Static variables"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Static-variables","content":"If a variable is configured with static: true, it will be inlined into your application code, enabling optimisations like dead-code elimination: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\nimport * as v from 'valibot';\n\nexport const variables = defineEnvVars({\n\tSHOW_DEBUG_OVERLAY: {\n\t\tpublic: true,\n\t\t+++static: true,+++\n\n\t\t// coerce to true/false\n\t\tvalidate: v.pipe(\n\t\t\tv.optional(v.string(), ''),\n\t\t\tv.transform((str) => str !== '')\n\t\t)\n\t}\n});Because this variable is static, the <DebugOverlay> component shown here will be excluded from the JavaScript bundle unless SHOW_DEBUG_OVERLAY is truthy:<script>\n\timport { SHOW_DEBUG_OVERLAY } from '$app/env/public';\n\timport DebugOverlay from '$lib/components/DebugOverlay.svelte';\n</script>\n\n{#if SHOW_DEBUG_OVERLAY}\n\t<DebugOverlay />\n{/if}But if the variable is set before building the app...SHOW_DEBUG_OVERLAY=true npm run build...then the component will be included and shown.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Core concepts","Environment variables","Explicit environment variables","Documenting variables"],"href":"/docs/kit/environment-variables#Explicit-environment-variables-Documenting-variables","content":"You can document the purpose of an environment variable by adding a description: \nimport { defineEnvVars } from '@sveltejs/kit/hooks';\n\nexport const variables = defineEnvVars({\n\tCACHE_TTL_SECONDS: {\n\t\tdescription: 'How long to cache responses, in seconds'\n\t}\n});Hovering over CACHE_TTL_SECONDS in your app code will show the description.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Building your app"],"href":"/docs/kit/building-your-app","content":"Building a SvelteKit app happens in two stages, which both happen when you run vite build (usually via npm run build).Firstly, Vite creates an optimized production build of your server code, your browser code, and your service worker (if you have one). Prerendering is executed at this stage, if appropriate.Secondly, an adapter takes this production build and tunes it for your target environment — more on this on the following pages.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Building your app","During the build"],"href":"/docs/kit/building-your-app#During-the-build","content":"SvelteKit will load your +page/layout(.server).js files (and all files they import) for analysis during the build. Any code that should not be executed at this stage must check that building from `$app/environment` is false:+++import { building } from '$app/environment';+++\nimport { initialiseDatabase } from '$lib/server/database';\n\n+++if (!building) {+++\n\tinitialiseDatabase();\n+++}+++\n\nexport function load() {\n\t// ...\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Building your app","Preview your app"],"href":"/docs/kit/building-your-app#Preview-your-app","content":"After building, you can view your production build locally with vite preview (via npm run preview). Note that this will run the app in Node, and so is not a perfect reproduction of your deployed app — adapter-specific adjustments like the `platform` object do not apply to previews.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Adapters"],"href":"/docs/kit/adapters","content":"Before you can deploy your SvelteKit app, you need to adapt it for your deployment target. Adapters are small plugins that take the built app as input and generate output for deployment.Official adapters exist for a variety of platforms — these are documented on the following pages:[`@sveltejs/adapter-cloudflare`](adapter-cloudflare) for Cloudflare Workers and Cloudflare Pages\n[`@sveltejs/adapter-netlify`](adapter-netlify) for Netlify\n[`@sveltejs/adapter-node`](adapter-node) for Node servers\n[`@sveltejs/adapter-static`](adapter-static) for static site generation (SSG)\n[`@sveltejs/adapter-vercel`](adapter-vercel) for VercelAdditional community-provided adapters exist for other platforms.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Adapters","Using adapters"],"href":"/docs/kit/adapters#Using-adapters","content":"Your adapter is specified in svelte.config.js:import adapter from 'svelte-adapter-foo';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// adapter options go here\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Adapters","Platform-specific context"],"href":"/docs/kit/adapters#Platform-specific-context","content":"Some adapters may have access to additional information about the request. For example, Cloudflare Workers can access an env object containing KV namespaces etc. This can be passed to the RequestEvent used in hooks and server routes as the platform property — consult each adapter's documentation to learn more.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Zero-config deployments"],"href":"/docs/kit/adapter-auto","content":"When you create a new SvelteKit project with npx sv create, it installs `adapter-auto` by default. This adapter automatically installs and uses the correct adapter for supported environments when you deploy:[`@sveltejs/adapter-cloudflare`](adapter-cloudflare) for [Cloudflare Pages](https://developers.cloudflare.com/pages/)\n[`@sveltejs/adapter-netlify`](adapter-netlify) for [Netlify](https://netlify.com/)\n[`@sveltejs/adapter-vercel`](adapter-vercel) for [Vercel](https://vercel.com/)\n[`svelte-adapter-azure-swa`](https://github.com/geoffrich/svelte-adapter-azure-swa) for [Azure Static Web Apps](https://docs.microsoft.com/en-us/azure/static-web-apps/)\n[`svelte-kit-sst`](https://github.com/sst/v2/tree/master/packages/svelte-kit-sst) for [AWS via SST](https://sst.dev/docs/start/aws/svelte)\n[`@sveltejs/adapter-node`](adapter-node) for [Google Cloud Run](https://cloud.google.com/run)It's recommended to install the appropriate adapter to your devDependencies once you've settled on a target environment, since this will add the adapter to your lockfile and slightly improve install times on CI.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Zero-config deployments","Environment-specific configuration"],"href":"/docs/kit/adapter-auto#Environment-specific-configuration","content":"To add configuration options, such as { edge: true } in `adapter-vercel` and `adapter-netlify`, you must install the underlying adapter — adapter-auto does not take any options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Zero-config deployments","Adding community adapters"],"href":"/docs/kit/adapter-auto#Adding-community-adapters","content":"You can add zero-config support for additional adapters by editing adapters.js and opening a pull request.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers"],"href":"/docs/kit/adapter-node","content":"To generate a standalone Node server, use `adapter-node`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Usage"],"href":"/docs/kit/adapter-node#Usage","content":"Install with npm i -D @sveltejs/adapter-node, then add the adapter to your svelte.config.js: \n \nimport adapter from '@sveltejs/adapter-node';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Deploying"],"href":"/docs/kit/adapter-node#Deploying","content":"First, build your app with npm run build. This will create the production server in the output directory specified in the adapter options, defaulting to build.You will need the output directory, the project's package.json, and the production dependencies in node_modules to run the application. Production dependencies can be generated by copying the package.json and package-lock.json and then running npm ci --omit dev (you can skip this step if your app doesn't have any dependencies). You can then start your app with this command:node buildDevelopment dependencies will be bundled into your app using Rollup. To control whether a given package is bundled or externalised, place it in devDependencies or dependencies respectively in your package.json.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Deploying","Compressing responses"],"href":"/docs/kit/adapter-node#Deploying-Compressing-responses","content":"You will typically want to compress responses coming from the server. If you're already deploying your server behind a reverse proxy for SSL or load balancing, it typically results in better performance to also handle compression at that layer since Node.js is single-threaded.However, if you're building a custom server and do want to add a compression middleware there, note that we would recommend using `@polka/compression` since SvelteKit streams responses and the more popular compression package does not support streaming and may cause errors when used.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables"],"href":"/docs/kit/adapter-node#Environment-variables","content":"In dev and preview, SvelteKit will read environment variables from your .env file (or .env.local, or .env.[mode], as determined by Vite.)In production, .env files are not automatically loaded. To do so, install dotenv in your project...npm install dotenv...and invoke it before running the built app:node +++-r dotenv/config+++ buildIf you use Node.js v20.6+, you can use the `--env-file` flag instead:node +++--env-file=.env+++ build","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","PORT`, HOST` and `SOCKET_PATH`"],"href":"/docs/kit/adapter-node#Environment-variables-PORT-HOST-and-SOCKET_PATH","content":"By default, the server will accept connections on 0.0.0.0 using port 3000. These can be customised with the PORT and HOST environment variables:HOST=127.0.0.1 PORT=4000 node buildAlternatively, the server can be configured to accept connections on a specified socket path. When this is done using the SOCKET_PATH environment variable, the HOST and PORT environment variables will be disregarded.SOCKET_PATH=/tmp/socket node build","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","ORIGIN`, PROTOCOL_HEADER`, `HOST_HEADER`, and `PORT_HEADER`"],"href":"/docs/kit/adapter-node#Environment-variables-ORIGIN-PROTOCOL_HEADER-HOST_HEADER-and-PORT_HEADER","content":"HTTP doesn't give SvelteKit a reliable way to know the URL that is currently being requested. The simplest way to tell SvelteKit where the app is being served is to set the ORIGIN environment variable:ORIGIN=https://my.site node build\n\n# or e.g. for local previewing and testing\nORIGIN=http://localhost:3000 node buildWith this, a request for the /stuff pathname will correctly resolve to https://my.site/stuff. Alternatively, you can specify headers that tell SvelteKit about the request protocol and host, from which it can construct the origin URL:PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build[!NOTE] [`x-forwarded-proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) and [`x-forwarded-host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) are de facto standard headers that forward the original protocol and host if you're using a reverse proxy (think load balancers and CDNs). You should only set these variables if your server is behind a trusted reverse proxy; otherwise, it'd be possible for clients to spoof these headers.\n\nIf you're hosting your proxy on a non-standard port and your reverse proxy supports `x-forwarded-port`, you can also set `PORT_HEADER=x-forwarded-port`.If adapter-node can't correctly determine the URL of your deployment, you may experience this error when using form actions:[!NOTE] Cross-site POST form submissions are forbidden","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","ADDRESS_HEADER` and XFF_DEPTH`"],"href":"/docs/kit/adapter-node#Environment-variables-ADDRESS_HEADER-and-XFF_DEPTH","content":"The `RequestEvent` object passed to hooks and endpoints includes an event.getClientAddress() function that returns the client's IP address. By default this is the connecting remoteAddress. If your server is behind one or more proxies (such as a load balancer), this value will contain the innermost proxy's IP address rather than the client's, so we need to specify an ADDRESS_HEADER to read the address from:ADDRESS_HEADER=True-Client-IP node build[!NOTE] Headers can easily be spoofed. As with `PROTOCOL_HEADER` and `HOST_HEADER`, you should [know what you're doing](https://adam-p.ca/blog/2022/03/x-forwarded-for/) before setting these.If the ADDRESS_HEADER is X-Forwarded-For, the header value will contain a comma-separated list of IP addresses. The XFF_DEPTH environment variable should specify how many trusted proxies sit in front of your server. E.g. if there are three trusted proxies, proxy 3 will forward the addresses of the original connection and the first two proxies:<client address>, <proxy 1 address>, <proxy 2 address>Some guides will tell you to read the left-most address, but this leaves you vulnerable to spoofing:<spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>We instead read from the right, accounting for the number of trusted proxies. In this case, we would use XFF_DEPTH=3.[!NOTE] If you need to read the left-most address instead (and don't care about spoofing) — for example, to offer a geolocation service, where it's more important for the IP address to be _real_ than _trusted_, you can do so by inspecting the `x-forwarded-for` header within your app.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","BODY_SIZE_LIMIT"],"href":"/docs/kit/adapter-node#Environment-variables-BODY_SIZE_LIMIT","content":"The maximum request body size to accept in bytes including while streaming. The body size can also be specified with a unit suffix for kilobytes (K), megabytes (M), or gigabytes (G). For example, 512K or 1M. Defaults to 512kb. You can disable this option with a value of Infinity (0 in older versions of the adapter) and implement a custom check in `handle` if you need something more advanced.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","SHUTDOWN_TIMEOUT"],"href":"/docs/kit/adapter-node#Environment-variables-SHUTDOWN_TIMEOUT","content":"The number of seconds to wait before forcefully closing any remaining connections after receiving a SIGTERM or SIGINT signal. Defaults to 30. Internally the adapter calls `closeAllConnections`. See Graceful shutdown for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","IDLE_TIMEOUT"],"href":"/docs/kit/adapter-node#Environment-variables-IDLE_TIMEOUT","content":"When using systemd socket activation, IDLE_TIMEOUT specifies the number of seconds after which the app is automatically put to sleep when receiving no requests. If not set, the app runs continuously. See Socket activation for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Environment variables","KEEP_ALIVE_TIMEOUT` and HEADERS_TIMEOUT`"],"href":"/docs/kit/adapter-node#Environment-variables-KEEP_ALIVE_TIMEOUT-and-HEADERS_TIMEOUT","content":"The number of seconds for `keepAliveTimeout` and `headersTimeout`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Options"],"href":"/docs/kit/adapter-node#Options","content":"The adapter can be configured with various options: \n \nimport adapter from '@sveltejs/adapter-node';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// default options are shown\n\t\t\tout: 'build',\n\t\t\tprecompress: true,\n\t\t\tenvPrefix: ''\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Options","out"],"href":"/docs/kit/adapter-node#Options-out","content":"The directory to build the server to. It defaults to build — i.e. node build would start the server locally after it has been created.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Options","precompress"],"href":"/docs/kit/adapter-node#Options-precompress","content":"Enables precompressing using gzip and brotli for assets and prerendered pages. It defaults to true.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Options","envPrefix"],"href":"/docs/kit/adapter-node#Options-envPrefix","content":"If you need to change the name of the environment variables used to configure the deployment (for example, to deconflict with environment variables you don't control), you can specify a prefix:envPrefix: 'MY_CUSTOM_';MY_CUSTOM_HOST=127.0.0.1 \\\nMY_CUSTOM_PORT=4000 \\\nMY_CUSTOM_ORIGIN=https://my.site \\\nnode build","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Graceful shutdown"],"href":"/docs/kit/adapter-node#Graceful-shutdown","content":"By default adapter-node gracefully shuts down the HTTP server when a SIGTERM or SIGINT signal is received. It will:reject new requests ([`server.close`](https://nodejs.org/api/http.html#serverclosecallback))\nwait for requests that have already been made but not received a response yet to finish and close connections once they become idle ([`server.closeIdleConnections`](https://nodejs.org/api/http.html#servercloseidleconnections))\nand finally, close any remaining connections that are still active after [`SHUTDOWN_TIMEOUT`](#Environment-variables-SHUTDOWN_TIMEOUT) seconds. ([`server.closeAllConnections`](https://nodejs.org/api/http.html#servercloseallconnections))[!NOTE] If you want to customize this behaviour you can use a [custom server](#Custom-server).You can listen to the sveltekit:shutdown event which is emitted after the HTTP server has closed all connections. Unlike Node's exit event, the sveltekit:shutdown event supports asynchronous operations and is always emitted when all connections are closed even if the server has dangling work such as open database connections. \nprocess.on('sveltekit:shutdown', async (reason) => {\n  await jobs.stop();\n  await db.close();\n});The parameter reason has one of the following values:`SIGINT` - shutdown was triggered by a `SIGINT` signal\n`SIGTERM` - shutdown was triggered by a `SIGTERM` signal\n`IDLE` - shutdown was triggered by [`IDLE_TIMEOUT`](#Environment-variables-IDLE_TIMEOUT)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Socket activation"],"href":"/docs/kit/adapter-node#Socket-activation","content":"Most Linux operating systems today use a modern process manager called systemd to start the server and run and manage services. You can configure your server to allocate a socket and start and scale your app on demand. This is called socket activation. In this case, the OS will pass two environment variables to your app — LISTEN_PID and LISTEN_FDS. The adapter will then listen on file descriptor 3 which refers to a systemd socket unit that you will have to create.[!NOTE] You can still use [`envPrefix`](#Options-envPrefix) with systemd socket activation. `LISTEN_PID` and `LISTEN_FDS` are always read without a prefix.To take advantage of socket activation follow these steps.Run your app as a [systemd service](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html). It can either run directly on the host system or inside a container (using Docker or a systemd portable service for example). If you additionally pass an [`IDLE_TIMEOUT`](#Environment-variables-IDLE_TIMEOUT) environment variable to your app it will gracefully shutdown if there are no requests for `IDLE_TIMEOUT` seconds. systemd will automatically start your app again when new requests are coming in. \n[Service]\nEnvironment=NODE_ENV=production IDLE_TIMEOUT=60\nExecStart=/usr/bin/node /usr/bin/myapp/buildCreate an accompanying [socket unit](https://www.freedesktop.org/software/systemd/man/latest/systemd.socket.html). The adapter only accepts a single socket. \n[Socket]\nListenStream=3000\n\n[Install]\nWantedBy=sockets.targetMake sure systemd has recognised both units by running `sudo systemctl daemon-reload`. Then enable the socket on boot and start it immediately using `sudo systemctl enable --now myapp.socket`. The app will then automatically start once the first request is made to `localhost:3000`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Node servers","Custom server"],"href":"/docs/kit/adapter-node#Custom-server","content":"The adapter creates two files in your build directory — index.js and handler.js. Running index.js — e.g. node build, if you use the default build directory — will start a server on the configured port.Alternatively, you can import the handler.js file, which exports a handler suitable for use with Express, Connect or Polka (or even just the built-in `http.createServer`) and set up your own server: \n \nimport { handler } from './build/handler.js';\nimport express from 'express';\n\nconst app = express();\n\n// add a route that lives separately from the SvelteKit app\napp.get('/healthcheck', (req, res) => {\n\tres.end('ok');\n});\n\n// let SvelteKit handle everything else, including serving prerendered pages and static assets\napp.use(handler);\n\napp.listen(3000, () => {\n\tconsole.log('listening on port 3000');\n});","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation"],"href":"/docs/kit/adapter-static","content":"To use SvelteKit as a static site generator (SSG), use `adapter-static`.This will prerender your entire site as a collection of static files. If you'd like to prerender only some pages and dynamically server-render others, you will need to use a different adapter together with the `prerender` option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Usage"],"href":"/docs/kit/adapter-static#Usage","content":"Install with npm i -D @sveltejs/adapter-static, then add the adapter to your svelte.config.js: \n \nimport adapter from '@sveltejs/adapter-static';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// default options are shown. On some platforms\n\t\t\t// these options are set automatically — see below\n\t\t\tpages: 'build',\n\t\t\tassets: 'build',\n\t\t\tfallback: undefined,\n\t\t\tprecompress: false,\n\t\t\tstrict: true\n\t\t})\n\t}\n};\n\nexport default config;...and add the `prerender` option to your root layout: \n// If you're using a fallback (i.e. SPA mode) you don't need to prerender all\n// pages by setting this here, but should prerender as many as possible to\n// avoid large performance and SEO impacts\nexport const prerender = true;[!NOTE] You must ensure SvelteKit's [`trailingSlash`](page-options#trailingSlash) option is set appropriately for your environment. If your host does not render `/a.html` upon receiving a request for `/a` then you will need to set `trailingSlash: 'always'` in your root layout to create `/a/index.html` instead.[!NOTE] You must ensure SvelteKit's [`ssr`](page-options#ssr) option isn't set to `false`. Otherwise, prerendering will save an empty 'shell' page instead of the fully rendered content.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Zero-config support"],"href":"/docs/kit/adapter-static#Zero-config-support","content":"Some platforms have zero-config support (more to come in future):[Vercel](https://vercel.com)On these platforms, you should omit the adapter options so that adapter-static can provide the optimal configuration: \n \nimport adapter from '@sveltejs/adapter-static';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter(---{...}---)\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options"],"href":"/docs/kit/adapter-static#Options","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options","pages"],"href":"/docs/kit/adapter-static#Options-pages","content":"The directory to write prerendered pages to. It defaults to build.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options","assets"],"href":"/docs/kit/adapter-static#Options-assets","content":"The directory to write static assets (the contents of static, plus client-side JS and CSS generated by SvelteKit) to. Ordinarily this should be the same as pages, and it will default to whatever the value of pages is, but in rare circumstances you might need to output pages and assets to separate locations.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options","fallback"],"href":"/docs/kit/adapter-static#Options-fallback","content":"To create a single page app (SPA) you must specify the name of the fallback page to be generated by SvelteKit, which is used as the entry point for URLs that have not been prerendered. This is commonly 200.html, but can vary depending on your deployment platform. You should avoid index.html where possible to avoid conflicting with a prerendered homepage.[!NOTE] This option has large negative performance and SEO impacts. It is only recommended in certain circumstances such as wrapping the site in a mobile app. See the [single page apps](single-page-apps) documentation for more details and alternatives.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options","precompress"],"href":"/docs/kit/adapter-static#Options-precompress","content":"If true, precompresses files with brotli and gzip. This will generate .br and .gz files.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","Options","strict"],"href":"/docs/kit/adapter-static#Options-strict","content":"By default, adapter-static checks that either all pages and endpoints (if any) of your app were prerendered, or you have the fallback option set. This check exists to prevent you from accidentally publishing an app where some parts of it are not accessible, because they are not contained in the final output. If you know this is ok (for example when a certain page only exists conditionally), you can set strict to false to turn off this check.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","GitHub Pages"],"href":"/docs/kit/adapter-static#GitHub-Pages","content":"When building for GitHub Pages, if your repo name is not equivalent to your-username.github.io, make sure to update `config.kit.paths.base` to match your repo name. This is because the site will be served from https://your-username.github.io/your-repo-name rather than from the root.You'll also want to generate a fallback 404.html page to replace the default 404 page shown by GitHub Pages.A config for GitHub Pages might look like the following: \n \nimport adapter from '@sveltejs/adapter-static';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\tfallback: '404.html'\n\t\t}),\n\t\tpaths: {\n\t\t\tbase: process.argv.includes('dev') ? '' : process.env.BASE_PATH\n\t\t}\n\t}\n};\n\nexport default config;You can use GitHub actions to automatically deploy your site to GitHub Pages when you make a change. Here's an example workflow:#","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Static site generation","GitHub Pages","file: .github/workflows/deploy.yml"],"href":"/docs/kit/adapter-static#GitHub-Pages-file:-.github-workflows-deploy.yml","content":"name: Deploy to GitHub Pageson:\n  push:\n    branches: 'main'jobs:\n  build_site:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4  # If you're using pnpm, add this step then change the commands and cache key below to use `pnpm`\n  # - name: Install pnpm\n  #   uses: pnpm/action-setup@v3\n  #   with:\n  #     version: 8\n\n  - name: Install Node.js\n    uses: actions/setup-node@v4\n    with:\n      node-version: 20\n      cache: npm\n\n  - name: Install dependencies\n    run: npm i\n\n  - name: build\n    env:\n      BASE_PATH: '/${{ github.event.repository.name }}'\n    run: |\n      npm run build\n\n  - name: Upload Artifacts\n    uses: actions/upload-pages-artifact@v3\n    with:\n      # this should match the `pages` option in your adapter-static options\n      path: 'build/'  deploy:\n    needs: build_site\n    runs-on: ubuntu-latestpermissions:\n  pages: write\n  id-token: write\n\nenvironment:\n  name: github-pages\n  url: ${{ steps.deployment.outputs.page_url }}\n\nsteps:\n  - name: Deploy\n    id: deployment\n    uses: actions/deploy-pages@v4\nIf you're not using GitHub actions to deploy your site (for example, you're pushing the built site to its own repo), add an empty `.nojekyll` file in your `static` directory to prevent Jekyll from interfering.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Single-page apps"],"href":"/docs/kit/single-page-apps","content":"You can turn a SvelteKit app into a fully client-rendered single-page app (SPA) by specifying a fallback page. This page will be served for any URLs that can't be served by other means such as returning a prerendered page.[!NOTE] SPA mode has a large negative performance impact by forcing multiple network round trips (for the blank HTML document, then for the JavaScript, and then for any data needed for the page) before content can be shown. Unless you are serving the app from a local network (e.g. a mobile app that wraps a locally-served SPA) this will delay startup, especially when considering the latency of mobile devices. It also harms SEO by often causing sites to be downranked for performance (SPAs are much more likely to fail [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals)), excluding search engines that don't render JS, and causing your site to receive less frequent updates from those that do. And finally, it makes your app inaccessible to users if JavaScript fails or is disabled (which happens [more often than you probably think](https://kryogenix.org/code/browser/everyonehasjs.html)).\n\nYou can avoid these drawbacks by [prerendering](#Prerendering-individual-pages) as many pages as possible when using SPA mode (especially your homepage). If you can prerender all pages, you can simply use [static site generation](adapter-static) rather than a SPA. Otherwise, you should strongly consider using an adapter which supports server side rendering. SvelteKit has officially supported adapters for various providers with generous free tiers.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Single-page apps","Usage"],"href":"/docs/kit/single-page-apps#Usage","content":"First, disable SSR for the pages you don't want to prerender. These pages will be served via the fallback page; for example, to serve all pages via the fallback by default, you can update the root layout as shown below. You should opt back into prerendering individual pages and directories where possible. \nexport const ssr = false;If you don't have any server-side logic (i.e. +page.server.js, +layout.server.js or +server.js files) you can use `adapter-static` to create your SPA. Install adapter-static with npm i -D @sveltejs/adapter-static and add it to your svelte.config.js with the fallback option: \n \nimport adapter from '@sveltejs/adapter-static';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\tfallback: '200.html' // may differ from host to host\n\t\t})\n\t}\n};\n\nexport default config;The fallback page is an HTML page created by SvelteKit from your page template (e.g. app.html) that loads your app and navigates to the correct route. For example Surge, a static web host, lets you add a 200.html file that will handle any requests that don't correspond to static assets or prerendered pages.On some hosts it may be something else entirely — consult your platform's documentation. We recommend avoiding index.html if possible as it may conflict with prerendering.[!NOTE] Note that the fallback page will always contain absolute asset paths (i.e. beginning with `/` rather than `.`) regardless of the value of [`paths.relative`](configuration#paths), since it is used to respond to requests for arbitrary paths.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Single-page apps","Prerendering individual pages"],"href":"/docs/kit/single-page-apps#Prerendering-individual-pages","content":"If you want certain pages to be prerendered, you can re-enable ssr alongside prerender for just those parts of your app: \nexport const prerender = true;\nexport const ssr = true;You won't need a Node server or server capable of running JavaScript to deploy this page. It will only server render your page while building your project for the purposes of outputting an .html page that can be served from any static web host.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Single-page apps","Apache"],"href":"/docs/kit/single-page-apps#Apache","content":"To run an SPA on Apache, you should add a static/.htaccess file to route requests to the fallback page:<IfModule mod_rewrite.c>\n\tRewriteEngine On\n\tRewriteBase /\n\tRewriteRule ^200\\.html$ - [L]\n\tRewriteCond %{REQUEST_FILENAME} !-f\n\tRewriteCond %{REQUEST_FILENAME} !-d\n\tRewriteRule . /200.html [L]\n</IfModule>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare"],"href":"/docs/kit/adapter-cloudflare","content":"To deploy to Cloudflare Workers or Cloudflare Pages, use `adapter-cloudflare`.This adapter will be installed by default when you use `adapter-auto`. If you plan on staying with Cloudflare, you can switch from `adapter-auto` to using this adapter directly so that event.platform is emulated during local development, type declarations are automatically applied, and the ability to set Cloudflare-specific options is provided.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Comparisons"],"href":"/docs/kit/adapter-cloudflare#Comparisons","content":"`adapter-cloudflare` – supports all SvelteKit features; builds for Cloudflare Workers Static Assets and Cloudflare Pages\n`adapter-cloudflare-workers` – deprecated. Supports all SvelteKit features; builds for Cloudflare Workers Sites\n`adapter-static` – only produces client-side static assets; compatible with Cloudflare Workers Static Assets and Cloudflare Pages","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Usage"],"href":"/docs/kit/adapter-cloudflare#Usage","content":"Install with npm i -D @sveltejs/adapter-cloudflare, then add the adapter to your svelte.config.js: \n \nimport adapter from '@sveltejs/adapter-cloudflare';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// See below for an explanation of these options\n\t\t\tconfig: undefined,\n\t\t\tplatformProxy: {\n\t\t\t\tconfigPath: undefined,\n\t\t\t\tenvironment: undefined,\n\t\t\t\tpersist: undefined\n\t\t\t},\n\t\t\tfallback: 'plaintext',\n\t\t\troutes: {\n\t\t\t\tinclude: ['/*'],\n\t\t\t\texclude: ['<all>']\n\t\t\t}\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Options"],"href":"/docs/kit/adapter-cloudflare#Options","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Options","config"],"href":"/docs/kit/adapter-cloudflare#Options-config","content":"Path to your Wrangler configuration file. If you would like to use a Wrangler configuration filename other than wrangler.jsonc, wrangler.json, or wrangler.toml you can specify it using this option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Options","platformProxy"],"href":"/docs/kit/adapter-cloudflare#Options-platformProxy","content":"Preferences for the emulated platform.env local bindings. See the getPlatformProxy Wrangler API documentation for a full list of options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Options","fallback"],"href":"/docs/kit/adapter-cloudflare#Options-fallback","content":"Whether to render a plaintext 404.html page or a rendered SPA fallback page for non-matching asset requests.For Cloudflare Workers, the default behaviour is to return a null-body 404-status response for non-matching assets requests. However, if the `assets.not_found_handling` Wrangler configuration setting is set to \"404-page\", this page will be served if a request fails to match an asset. If assets.not_found_handling is set to \"single-page-application\", the adapter will render a SPA fallback index.html page regardless of the fallback option specified.For Cloudflare Pages, this page will only be served when a request that matches an entry in routes.exclude fails to match an asset.Most of the time plaintext is sufficient, but if you are using routes.exclude to manually exclude a set of prerendered pages without exceeding the 100 route limit, you may wish to use spa instead to avoid showing an unstyled 404 page to users.See Cloudflare Pages' Not Found behaviour for more info.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Options","routes"],"href":"/docs/kit/adapter-cloudflare#Options-routes","content":"Only for Cloudflare Pages. Allows you to customise the `_routes.json` file generated by adapter-cloudflare.`include` defines routes that will invoke a function, and defaults to `['/*']`\n`exclude` defines routes that will _not_ invoke a function — this is a faster and cheaper way to serve your app's static assets. This array can include the following special values:\n  - `<build>` contains your app's build artifacts (the files generated by Vite)\n  - `<files>` contains the contents of your `static` directory\n  - `<redirects>` contains a list of pathnames from your [`_redirects` file](https://developers.cloudflare.com/pages/configuration/redirects/) at the root\n  - `<prerendered>` contains a list of prerendered pages\n  - `<all>` (the default) contains all of the aboveYou can have up to 100 include and exclude rules combined. Generally you can omit the routes options, but if (for example) your <prerendered> paths exceed that limit, you may find it helpful to manually create an exclude list that includes '/articles/*' instead of the auto-generated ['/articles/foo', '/articles/bar', '/articles/baz', ...].","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Workers"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Workers","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Workers","Basic configuration"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Workers-Basic-configuration","content":"When building for Cloudflare Workers, this adapter expects to find a Wrangler configuration file in the project root. It should look something like this: \n{\n\t\"name\": \"<any-name-you-want>\",\n\t\"main\": \".svelte-kit/cloudflare/_worker.js\",\n\t\"compatibility_flags\": [\"nodejs_als\"],\n\t\"compatibility_date\": \"<YYYY-MM-DD>\",\n\t\"assets\": {\n\t\t\"binding\": \"ASSETS\",\n\t\t\"directory\": \".svelte-kit/cloudflare\",\n\t}\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Workers","Deployment"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Workers-Deployment","content":"You can use the Wrangler CLI to deploy your application by running npx wrangler deploy or use the Cloudflare Git integration to enable automatic builds and deployments on push.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Pages"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Pages","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Pages","Deployment"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Pages-Deployment","content":"Please follow the Get Started Guide for Cloudflare Pages to begin.If you're using the Git integration, your build settings should look like this:Framework preset – SvelteKit\nBuild command – `npm run build` or `vite build`\nBuild output directory – `.svelte-kit/cloudflare`Once configured, go to the Runtime section of your project settings, and add the nodejs_als compatibility flag to enable the Node.js AsyncLocalStorage. Alternatively, do this in your wrangler config using the compatibility_flags array.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Pages","Further reading"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Pages-Further-reading","content":"You may wish to refer to Cloudflare's documentation for deploying a SvelteKit site on Cloudflare Pages.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Cloudflare Pages","Notes"],"href":"/docs/kit/adapter-cloudflare#Cloudflare-Pages-Notes","content":"Functions contained in the `/functions` directory at the project's root will not be included in the deployment. Instead, functions should be implemented as server endpoints in your SvelteKit app, which is compiled to a single `_worker.js` file.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Runtime APIs"],"href":"/docs/kit/adapter-cloudflare#Runtime-APIs","content":"The `env` object contains your project's bindings, which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the platform property, along with `ctx`, `caches`, and `cf`, meaning that you can access it in hooks and endpoints: \n \n/** @type {import('./$types').RequestHandler} */\nexport async function POST({ request, platform }) {\n\tconst x = platform?.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x');\n}[!NOTE] SvelteKit's built-in [`$env` module]($env-static-private) should be preferred for environment variables.To make these types available to your app, install `@cloudflare/workers-types` and reference them in your src/app.d.ts: \n+++import { KVNamespace, DurableObjectNamespace } from '@cloudflare/workers-types';+++\n\ndeclare global {\n\tnamespace App {\n\t\tinterface Platform {\n+++\t\t\tenv: {\n\t\t\t\tYOUR_KV_NAMESPACE: KVNamespace;\n\t\t\t\tYOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;\n\t\t\t};+++\n\t\t}\n\t}\n}\n\nexport {};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Runtime APIs","Testing locally"],"href":"/docs/kit/adapter-cloudflare#Runtime-APIs-Testing-locally","content":"Cloudflare specific values in the platform property are emulated during dev and preview modes. Local bindings are created based on your Wrangler configuration file and are used to populate platform.env during development and preview. Use the adapter config `platformProxy` option to change your preferences for the bindings.For testing the build, you should use Wrangler version 4. Once you have built your site, run wrangler dev .svelte-kit/cloudflare/_worker.js if you're testing for Cloudflare Workers or wrangler pages dev .svelte-kit/cloudflare for Cloudflare Pages.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Headers and redirects"],"href":"/docs/kit/adapter-cloudflare#Headers-and-redirects","content":"The `_headers` and `_redirects` files, specific to Cloudflare, can be used for static asset responses (like images) by putting them into the project root folder.However, they will have no effect on responses dynamically rendered by SvelteKit, which should return custom headers or redirect responses from server endpoints or with the `handle` hook.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Troubleshooting"],"href":"/docs/kit/adapter-cloudflare#Troubleshooting","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Troubleshooting","Node.js compatibility"],"href":"/docs/kit/adapter-cloudflare#Troubleshooting-Node.js-compatibility","content":"If you would like to enable Node.js compatibility, you can add the nodejs_compat compatibility flag to your Wrangler configuration file: \n{\n\t\"compatibility_flags\": [\"nodejs_compat\"]\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Troubleshooting","Worker size limits"],"href":"/docs/kit/adapter-cloudflare#Troubleshooting-Worker-size-limits","content":"When deploying your application, the server generated by SvelteKit is bundled into a single file. Wrangler will fail to publish your worker if it exceeds the size limits after minification. You're unlikely to hit this limit usually, but some large libraries can cause this to happen. In that case, you can try to reduce the size of your worker by only importing such libraries on the client side. See the FAQ for more information.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Troubleshooting","Accessing the file system"],"href":"/docs/kit/adapter-cloudflare#Troubleshooting-Accessing-the-file-system","content":"You can't use fs in Cloudflare Workers.Instead, use the `read` function from $app/server to access your files. It works by fetching the file from the deployed public assets location.Alternatively, you can prerender the routes in question.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Migrating from Workers Sites"],"href":"/docs/kit/adapter-cloudflare#Migrating-from-Workers-Sites","content":"Cloudflare no longer recommends using Workers Sites and instead recommends using Workers Static Assets. To migrate, replace @sveltejs/adapter-cloudflare-workers with @sveltejs/adapter-cloudflare and remove all site configuration settings from your Wrangler configuration file, then add the assets.directory and assets.binding configuration settings:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Migrating from Workers Sites","svelte.config.js"],"href":"/docs/kit/adapter-cloudflare#Migrating-from-Workers-Sites-svelte.config.js","content":"---import adapter from '@sveltejs/adapter-cloudflare-workers';---\n+++import adapter from '@sveltejs/adapter-cloudflare';+++\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Migrating from Workers Sites","wrangler.toml"],"href":"/docs/kit/adapter-cloudflare#Migrating-from-Workers-Sites-wrangler.toml","content":"---site.bucket = \".cloudflare/public\"---\n+++assets.directory = \".cloudflare/public\"\nassets.binding = \"ASSETS\" # Exclude this if you don't have a `main` key configured.+++","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare","Migrating from Workers Sites","wrangler.jsonc"],"href":"/docs/kit/adapter-cloudflare#Migrating-from-Workers-Sites-wrangler.jsonc","content":"{\n---\t\"site\": {\n\t\t\"bucket\": \".cloudflare/public\"\n\t},---\n+++\t\"assets\": {\n\t\t\"directory\": \".cloudflare/public\",\n\t\t\"binding\": \"ASSETS\" // Exclude this if you don't have a `main` key configured.\n\t}+++\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers"],"href":"/docs/kit/adapter-cloudflare-workers","content":"[!NOTE] `adapter-cloudflare-workers` has been deprecated in favour of [`adapter-cloudflare`](adapter-cloudflare). We recommend using `adapter-cloudflare` to deploy to Cloudflare Workers with [Static Assets](https://developers.cloudflare.com/workers/static-assets/) since Cloudflare Workers Sites will be deprecated in favour of it.To deploy to Cloudflare Workers with Workers Sites, use adapter-cloudflare-workers.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Usage"],"href":"/docs/kit/adapter-cloudflare-workers#Usage","content":"Install with npm i -D @sveltejs/adapter-cloudflare-workers, then add the adapter to your svelte.config.js: \n \nimport adapter from '@sveltejs/adapter-cloudflare-workers';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// see below for options that can be set here\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Options"],"href":"/docs/kit/adapter-cloudflare-workers#Options","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Options","config"],"href":"/docs/kit/adapter-cloudflare-workers#Options-config","content":"Path to your Wrangler configuration file. If you would like to use a Wrangler configuration filename other than wrangler.jsonc, wrangler.json, or wrangler.toml you can specify it using this option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Options","platformProxy"],"href":"/docs/kit/adapter-cloudflare-workers#Options-platformProxy","content":"Preferences for the emulated platform.env local bindings. See the getPlatformProxy Wrangler API documentation for a full list of options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Basic Configuration"],"href":"/docs/kit/adapter-cloudflare-workers#Basic-Configuration","content":"This adapter expects to find a Wrangler configuration file in the project root. It should look something like this: \n{\n\t\"name\": \"<your-service-name>\",\n\t\"account_id\": \"<your-account-id>\",\n\t\"main\": \"./.cloudflare/worker.js\",\n\t\"site\": {\n\t\t\"bucket\": \"./.cloudflare/public\"\n\t},\n\t\"build\": {\n\t\t\"command\": \"npm run build\"\n\t},\n\t\"compatibility_date\": \"2021-11-12\"\n}<your-service-name> can be anything. <your-account-id> can be found by running wrangler whoami using the Wrangler CLI tool or by logging into your Cloudflare dashboard and grabbing it from the end of the URL:https://dash.cloudflare.com/<your-account-id>/home[!NOTE] You should add the `.cloudflare` directory (or whichever directories you specified for `main` and `site.bucket`) and the `.wrangler` directory to your `.gitignore`.You will need to install Wrangler and log in, if you haven't already:npm i -D wrangler\nwrangler loginThen, you can build your app and deploy it:wrangler deploy","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Runtime APIs"],"href":"/docs/kit/adapter-cloudflare-workers#Runtime-APIs","content":"The `env` object contains your project's bindings, which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the platform property, along with `ctx`, `caches`, and `cf`, meaning that you can access it in hooks and endpoints: \n \n/** @type {import('./$types').RequestHandler} */\nexport async function POST({ request, platform }) {\n\tconst x = platform?.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x');\n}[!NOTE] SvelteKit's built-in [`$env` module]($env-static-private) should be preferred for environment variables.To make these types available to your app, install `@cloudflare/workers-types` and reference them in your src/app.d.ts: \n+++import { KVNamespace, DurableObjectNamespace } from '@cloudflare/workers-types';+++\n\ndeclare global {\n\tnamespace App {\n\t\tinterface Platform {\n+++\t\t\tenv?: {\n\t\t\t\tYOUR_KV_NAMESPACE: KVNamespace;\n\t\t\t\tYOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;\n\t\t\t};+++\n\t\t}\n\t}\n}\n\nexport {};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Runtime APIs","Testing Locally"],"href":"/docs/kit/adapter-cloudflare-workers#Runtime-APIs-Testing-Locally","content":"Cloudflare Workers specific values in the platform property are emulated during dev and preview modes. Local bindings are created based on your Wrangler configuration file and are used to populate platform.env during development and preview. Use the adapter config `platformProxy` option to change your preferences for the bindings.For testing the build, you should use Wrangler version 4. Once you have built your site, run wrangler dev.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Troubleshooting"],"href":"/docs/kit/adapter-cloudflare-workers#Troubleshooting","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Troubleshooting","Node.js compatibility"],"href":"/docs/kit/adapter-cloudflare-workers#Troubleshooting-Node.js-compatibility","content":"If you would like to enable Node.js compatibility, you can add the nodejs_compat compatibility flag to your Wrangler configuration file: \n{\n\t\"compatibility_flags\": [\"nodejs_compat\"]\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Troubleshooting","Worker size limits"],"href":"/docs/kit/adapter-cloudflare-workers#Troubleshooting-Worker-size-limits","content":"When deploying your application, the server generated by SvelteKit is bundled into a single file. Wrangler will fail to publish your worker if it exceeds the size limits after minification. You're unlikely to hit this limit usually, but some large libraries can cause this to happen. In that case, you can try to reduce the size of your worker by only importing such libraries on the client side. See the FAQ for more information.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Cloudflare Workers","Troubleshooting","Accessing the file system"],"href":"/docs/kit/adapter-cloudflare-workers#Troubleshooting-Accessing-the-file-system","content":"You can't use fs in Cloudflare Workers — you must prerender the routes in question.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify"],"href":"/docs/kit/adapter-netlify","content":"To deploy to Netlify, use `adapter-netlify`.This adapter will be installed by default when you use `adapter-auto`, but adding it to your project allows you to specify Netlify-specific options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Usage"],"href":"/docs/kit/adapter-netlify#Usage","content":"Install with npm i -D @sveltejs/adapter-netlify, then add the adapter to your svelte.config.js: \n \nimport adapter from '@sveltejs/adapter-netlify';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\t// default options are shown\n\t\tadapter: adapter({\n\t\t\t// if true, will create a Netlify Edge Function rather\n\t\t\t// than using standard Node-based functions\n\t\t\tedge: false,\n\n\t\t\t// if true, will split your app into multiple functions\n\t\t\t// instead of creating a single one for the entire app.\n\t\t\t// if `edge` is true, this option cannot be used\n\t\t\tsplit: false\n\t\t})\n\t}\n};\n\nexport default config;Then, make sure you have a netlify.toml file in the project root. This will determine where to write static assets based on the build.publish settings, as per this sample configuration:[build]\n\tcommand = \"npm run build\"\n\tpublish = \"build\"If the netlify.toml file or the build.publish value is missing, a default value of \"build\" will be used. Note that if you have set the publish directory in the Netlify UI to something else then you will need to set it in netlify.toml too, or use the default value of \"build\".","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Usage","Node version"],"href":"/docs/kit/adapter-netlify#Usage-Node-version","content":"New projects will use the current Node LTS version by default. However, if you're upgrading a project you created a while ago it may be stuck on an older version. See the Netlify docs for details on manually specifying a current Node version.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Netlify Edge Functions"],"href":"/docs/kit/adapter-netlify#Netlify-Edge-Functions","content":"SvelteKit supports Netlify Edge Functions. If you pass the option edge: true to the adapter function, server-side rendering will happen in a Deno-based edge function that's deployed close to the site visitor. If set to false (the default), the site will deploy to Node-based Netlify Functions. \n \nimport adapter from '@sveltejs/adapter-netlify';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// will create a Netlify Edge Function using Deno-based\n\t\t\t// rather than using standard Node-based functions\n\t\t\tedge: true\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Netlify alternatives to SvelteKit functionality"],"href":"/docs/kit/adapter-netlify#Netlify-alternatives-to-SvelteKit-functionality","content":"You may build your app using functionality provided directly by SvelteKit without relying on any Netlify functionality. Using the SvelteKit versions of these features will allow them to be used in dev mode, tested with integration tests, and to work with other adapters should you ever decide to switch away from Netlify. However, in some scenarios you may find it beneficial to use the Netlify versions of these features. One example would be if you're migrating an app that's already hosted on Netlify to SvelteKit.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Netlify alternatives to SvelteKit functionality","_headers` and _redirects`"],"href":"/docs/kit/adapter-netlify#Netlify-alternatives-to-SvelteKit-functionality-_headers-and-_redirects","content":"The `_headers` and `_redirects` files specific to Netlify can be used for static asset responses (like images) by putting them into the project root folder. You can also use `[[redirects]]` in your netlify.toml.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Netlify alternatives to SvelteKit functionality","Netlify Forms"],"href":"/docs/kit/adapter-netlify#Netlify-alternatives-to-SvelteKit-functionality-Netlify-Forms","content":"Create your Netlify HTML form as described [here](https://docs.netlify.com/forms/setup/#html-forms), e.g. as `/routes/contact/+page.svelte`. (Don't forget to add the hidden `form-name` input element!)\nNetlify's build bot parses your HTML files at deploy time, which means your form must be [prerendered](page-options#prerender) as HTML. You can either add `export const prerender = true` to your `contact.svelte` to prerender just that page or set the `kit.prerender.force: true` option to prerender all pages.\nIf your Netlify form has a [custom success message](https://docs.netlify.com/forms/setup/#success-messages) like `<form netlify ... action=\"/success\">` then ensure the corresponding `/routes/success/+page.svelte` exists and is prerendered.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Netlify alternatives to SvelteKit functionality","Netlify Functions"],"href":"/docs/kit/adapter-netlify#Netlify-alternatives-to-SvelteKit-functionality-Netlify-Functions","content":"With this adapter, SvelteKit endpoints are hosted as Netlify Functions. Netlify function handlers have additional context, including Netlify Identity information. You can access this context via the event.platform.context field inside your hooks and +page.server or +layout.server endpoints. These are serverless functions when the edge property is false in the adapter config or edge functions when it is true. \n/** @type {import('./$types').PageServerLoad} */\nexport const load = async (event) => {\n\tconst context = event.platform?.context;\n\tconsole.log(context); // shows up in your functions log in the Netlify app\n};Additionally, you can add your own Netlify functions by creating a directory for them and adding the configuration to your netlify.toml file. For example:[build]\n\tcommand = \"npm run build\"\n\tpublish = \"build\"\n\n[functions]\n\tdirectory = \"functions\"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Troubleshooting"],"href":"/docs/kit/adapter-netlify#Troubleshooting","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Netlify","Troubleshooting","Accessing the file system"],"href":"/docs/kit/adapter-netlify#Troubleshooting-Accessing-the-file-system","content":"You can't use fs in edge deployments.You can use it in serverless deployments, but it won't work as expected, since files are not copied from your project into your deployment. Instead, use the `read` function from $app/server to access your files. It also works inside edge deployments by fetching the file from the deployed public assets location.Alternatively, you can prerender the routes in question.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel"],"href":"/docs/kit/adapter-vercel","content":"To deploy to Vercel, use `adapter-vercel`.This adapter will be installed by default when you use `adapter-auto`, but adding it to your project allows you to specify Vercel-specific options.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Usage"],"href":"/docs/kit/adapter-vercel#Usage","content":"Install with npm i -D @sveltejs/adapter-vercel, then add the adapter to your svelte.config.js: \nimport adapter from '@sveltejs/adapter-vercel';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\t// see below for options that can be set here\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Deployment configuration"],"href":"/docs/kit/adapter-vercel#Deployment-configuration","content":"To control how your routes are deployed to Vercel as functions, you can specify deployment configuration, either through the option shown above or with `export const config` inside +server.js, +page(.server).js and +layout(.server).js files.For example you could deploy one specific route as an individual serverless function, separate from the rest of your app: \n/** @type {import('@sveltejs/adapter-vercel').Config} */\nexport const config = {\n\tsplit: true\n};The following options apply to all functions:`runtime`: `'edge'`, `'nodejs20.x'` or `'nodejs22.x'`. By default, the adapter will select the `'nodejs<version>.x'` corresponding to the Node version your project is configured to use on the Vercel dashboard\n> [!NOTE] This option is deprecated and will be removed in a future version, at which point all your functions will use whichever Node version is specified in the project configuration on Vercel\n`regions`: an array of [edge network regions](https://vercel.com/docs/concepts/edge-network/regions) (defaulting to `[\"iad1\"]` for serverless functions) or `'all'` if `runtime` is `edge` (its default). Note that multiple regions for serverless functions are only supported on Enterprise plans\n`split`: if `true`, causes a route to be deployed as an individual function. If `split` is set to `true` at the adapter level, all routes will be deployed as individual functionsAdditionally, the following option applies to edge functions:`external`: an array of dependencies that esbuild should treat as external when bundling functions. This should only be used to exclude optional dependencies that will not run outside NodeAnd the following option apply to serverless functions:`memory`: the amount of memory available to the function. Defaults to `1024` Mb, and can be decreased to `128` Mb or [increased](https://vercel.com/docs/concepts/limits/overview#serverless-function-memory) in 64Mb increments up to `3008` Mb on Pro or Enterprise accounts\n`maxDuration`: [maximum execution duration](https://vercel.com/docs/functions/runtimes#max-duration) of the function. Defaults to `10` seconds for Hobby accounts, `15` for Pro and `900` for Enterprise\n`isr`: configuration Incremental Static Regeneration, described belowConfiguration set in a layout applies to all the routes beneath that layout, unless overridden at a more granular level.If your functions need to access data in a specific region, it's recommended that they be deployed in the same region (or close to it) for optimal performance.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Image Optimization"],"href":"/docs/kit/adapter-vercel#Image-Optimization","content":"You may set the images config to control how Vercel builds your images. See the image configuration reference for full details. As an example, you may set: \nimport adapter from '@sveltejs/adapter-vercel';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter({\n\t\t\timages: {\n\t\t\t\tsizes: [640, 828, 1200, 1920, 3840],\n\t\t\t\tformats: ['image/avif', 'image/webp'],\n\t\t\t\tminimumCacheTTL: 300,\n\t\t\t\tdomains: ['example-app.vercel.app'],\n\t\t\t}\n\t\t})\n\t}\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Incremental Static Regeneration"],"href":"/docs/kit/adapter-vercel#Incremental-Static-Regeneration","content":"Vercel supports Incremental Static Regeneration (ISR), which provides the performance and cost advantages of prerendered content with the flexibility of dynamically rendered content.[!NOTE] Use ISR only on routes where every visitor should see the same content (much like when you prerender). If there's anything user-specific happening (like session cookies), they should happen on the client via JavaScript only to not leak sensitive information across visitsTo add ISR to a route, include the isr property in your config object:import { BYPASS_TOKEN } from '$env/static/private';\n\n/** @type {import('@sveltejs/adapter-vercel').Config} */\nexport const config = {\n\tisr: {\n\t\texpiration: 60,\n\t\tbypassToken: BYPASS_TOKEN,\n\t\tallowQuery: ['search']\n\t}\n};[!NOTE] Using ISR on a route with `export const prerender = true` will have no effect, since the route is prerendered at build timeThe expiration property is required; all others are optional. The properties are discussed in more detail below.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Incremental Static Regeneration","expiration"],"href":"/docs/kit/adapter-vercel#Incremental-Static-Regeneration-expiration","content":"The expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to false means it will never expire. In that case, you likely want to define a bypass token to re-generate on demand.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Incremental Static Regeneration","bypassToken"],"href":"/docs/kit/adapter-vercel#Incremental-Static-Regeneration-bypassToken","content":"A random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset with a __prerender_bypass=<token> cookie.Making a GET or HEAD request with x-prerender-revalidate: <token> will force the asset to be re-validated.Note that the BYPASS_TOKEN string must be at least 32 characters long. You could generate one using the JavaScript console like so:crypto.randomUUID();Set this string as an environment variable on Vercel by logging in and going to your project then Settings > Environment Variables. For \"Key\" put BYPASS_TOKEN and for \"value\" use the string generated above, then hit \"Save\".To get this key known about for local development, you can use the Vercel CLI by running the vercel env pull command locally like so:vercel env pull .env.development.local","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Incremental Static Regeneration","allowQuery"],"href":"/docs/kit/adapter-vercel#Incremental-Static-Regeneration-allowQuery","content":"A list of valid query parameters that contribute to the cache key. Other parameters (such as utm tracking codes) will be ignored, ensuring that they do not result in content being re-generated unnecessarily. By default, query parameters are ignored.[!NOTE] Pages that are  [prerendered](page-options#prerender) will ignore ISR configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Environment variables"],"href":"/docs/kit/adapter-vercel#Environment-variables","content":"Vercel makes a set of deployment-specific environment variables available. Like other environment variables, these are accessible from $env/static/private and $env/dynamic/private (sometimes — more on that later), and inaccessible from their public counterparts. To access one of these variables from the client: \nimport { VERCEL_COMMIT_REF } from '$env/static/private';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport function load() {\n\treturn {\n\t\tdeploymentGitBranch: VERCEL_COMMIT_REF\n\t};\n}<!--- file: +layout.svelte --->\n<script>\n\t/** @type {import('./$types').LayoutProps} */\n\tlet { data } = $props();\n</script>\n\n<p>This staging environment was deployed from {data.deploymentGitBranch}.</p>Since all of these variables are unchanged between build time and run time when building on Vercel, we recommend using $env/static/private — which will statically replace the variables, enabling optimisations like dead code elimination — rather than $env/dynamic/private.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Skew protection"],"href":"/docs/kit/adapter-vercel#Skew-protection","content":"When a new version of your app is deployed, assets belonging to the previous version may no longer be accessible. If a user is actively using your app when this happens, it can cause errors when they navigate — this is known as version skew. SvelteKit mitigates this by detecting errors resulting from version skew and causing a hard reload to get the latest version of the app, but this will cause any client-side state to be lost. (You can also proactively mitigate it by observing `updated.current` from $app/state, which tells clients when a new version has been deployed.)Skew protection is a Vercel feature that routes client requests to their original deployment. When a user visits your app, a cookie is set with the deployment ID, and any subsequent requests will be routed to that deployment for as long as skew protection is active. When they reload the page, they will get the newest deployment. (updated.current is exempted from this behaviour, and so will continue to report new deployments.) To enable it, visit the Advanced section of your project settings on Vercel.Cookie-based skew protection comes with one caveat: if a user has multiple versions of your app open in multiple tabs, requests from older versions will be routed to the newer one, meaning they will fall back to SvelteKit's built-in skew protection.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Notes"],"href":"/docs/kit/adapter-vercel#Notes","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Notes","Vercel utilities"],"href":"/docs/kit/adapter-vercel#Notes-Vercel-utilities","content":"If you need Vercel-specific utilities like waitUntil, use the package `@vercel/functions`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Notes","Vercel functions"],"href":"/docs/kit/adapter-vercel#Notes-Vercel-functions","content":"If you have Vercel functions contained in the api directory at the project's root, any requests for /api/* will not be handled by SvelteKit. You should implement these as API routes in your SvelteKit app instead, unless you need to use a non-JavaScript language in which case you will need to ensure that you don't have any /api/* routes in your SvelteKit app.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Notes","Node version"],"href":"/docs/kit/adapter-vercel#Notes-Node-version","content":"Projects created before a certain date may default to using an older Node version than what SvelteKit currently requires. You can change the Node version in your project settings.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Troubleshooting"],"href":"/docs/kit/adapter-vercel#Troubleshooting","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Troubleshooting","Accessing the file system"],"href":"/docs/kit/adapter-vercel#Troubleshooting-Accessing-the-file-system","content":"You can't use fs in edge functions.You can use it in serverless functions, but it won't work as expected, since files are not copied from your project into your deployment. Instead, use the `read` function from $app/server to access your files. It also works inside routes deployed as edge functions by fetching the file from the deployed public assets location.Alternatively, you can prerender the routes in question.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Vercel","Troubleshooting","Deployment protection"],"href":"/docs/kit/adapter-vercel#Troubleshooting-Deployment-protection","content":"If using `read` in an edge function, SvelteKit will fetch the file in question from your deployment. If you are using Deployment Protection, you must also enable Protection Bypass for Automation so that the request does not result in a 401 Unauthorized response.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Build and deploy","Writing adapters"],"href":"/docs/kit/writing-adapters","content":"If an adapter for your preferred environment doesn't yet exist, you can build your own. We recommend looking at the source for an adapter to a platform similar to yours and copying it as a starting point.Adapter packages implement the following API, which creates an Adapter:/** @param {AdapterSpecificOptions} options */\nexport default function (options) {\n\t/** @type {import('@sveltejs/kit').Adapter} */\n\tconst adapter = {\n\t\tname: 'adapter-package-name',\n\t\tasync adapt(builder) {\n\t\t\t// adapter implementation\n\t\t},\n\t\tasync emulate() {\n\t\t\treturn {\n\t\t\t\tasync platform({ config, prerender }) {\n\t\t\t\t\t// the returned object becomes `event.platform` during dev, build and\n\t\t\t\t\t// preview. Its shape is that of `App.Platform`\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tsupports: {\n\t\t\tread: ({ config, route }) => {\n\t\t\t\t// Return `true` if the route with the given `config` can use `read`\n\t\t\t\t// from `$app/server` in production, return `false` if it can't.\n\t\t\t\t// Or throw a descriptive error describing how to configure the deployment\n\t\t\t},\n\t\t\tinstrumentation: () => {\n\t\t\t\t// Return `true` if this adapter supports loading `instrumentation.server.js`.\n\t\t\t\t// Return `false if it can't, or throw a descriptive error.\n\t\t\t}\n\t\t}\n\t};\n\n\treturn adapter;\n}Of these, name and adapt are required. emulate and supports are optional.Within the adapt method, there are a number of things that an adapter should do:Clear out the build directory\nWrite SvelteKit output with `builder.writeClient`, `builder.writeServer`, and `builder.writePrerendered`\nOutput code that:\n  - Imports `Server` from `${builder.getServerDirectory()}/index.js`\n  - Instantiates the app with a manifest generated with `builder.generateManifest({ relativePath })`\n  - Listens for requests from the platform, converts them to a standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) if necessary, calls the `server.respond(request, { getClientAddress })` function to generate a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) and responds with it\n  - expose any platform-specific information to SvelteKit via the `platform` option passed to `server.respond`\n  - Globally shims `fetch` to work on the target platform, if necessary. SvelteKit provides a `@sveltejs/kit/node/polyfills` helper for platforms that can use `undici`\nBundle the output to avoid needing to install dependencies on the target platform, if necessary\nPut the user's static files and the generated JS/CSS in the correct location for the target platformWhere possible, we recommend putting the adapter output under the build/ directory with any intermediate output placed under .svelte-kit/[adapter-name].","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing"],"href":"/docs/kit/advanced-routing","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Rest parameters"],"href":"/docs/kit/advanced-routing#Rest-parameters","content":"If the number of route segments is unknown, you can use rest syntax — for example you might implement GitHub's file viewer like so.../[org]/[repo]/tree/[branch]/[...file]...in which case a request for /sveltejs/kit/tree/main/documentation/docs/04-advanced-routing.md would result in the following parameters being available to the page: \n{\n\torg: 'sveltejs',\n\trepo: 'kit',\n\tbranch: 'main',\n\tfile: 'documentation/docs/04-advanced-routing.md'\n}[!NOTE] `src/routes/a/[...rest]/z/+page.svelte` will match `/a/z` (i.e. there's no parameter at all) as well as `/a/b/z` and `/a/b/c/z` and so on. Make sure you check that the value of the rest parameter is valid, for example using a [matcher](#Matching).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Rest parameters","404 pages"],"href":"/docs/kit/advanced-routing#Rest-parameters-404-pages","content":"Rest parameters also allow you to render custom 404s. Given these routes...src/routes/\n├ marx-brothers/\n│ ├ chico/\n│ ├ harpo/\n│ ├ groucho/\n│ └ +error.svelte\n└ +error.svelte...the marx-brothers/+error.svelte file will not be rendered if you visit /marx-brothers/karl, because no route was matched. If you want to render the nested error page, you should create a route that matches any /marx-brothers/* request, and return a 404 from it:src/routes/\n├ marx-brothers/\n+++| ├ [...path]/+++\n│ ├ chico/\n│ ├ harpo/\n│ ├ groucho/\n│ └ +error.svelte\n└ +error.svelte \nimport { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').PageLoad} */\nexport function load(event) {\n\terror(404, 'Not Found');\n}[!NOTE] If you don't handle 404 cases, they will appear in [`handleError`](hooks#Shared-hooks-handleError)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Optional parameters"],"href":"/docs/kit/advanced-routing#Optional-parameters","content":"A route like [lang]/home contains a parameter named lang which is required. Sometimes it's beneficial to make these parameters optional, so that in this example both home and en/home point to the same page. You can do that by wrapping the parameter in another bracket pair: [[lang]]/homeNote that an optional route parameter cannot follow a rest parameter ([...rest]/[[optional]]), since parameters are matched 'greedily' and the optional parameter would always be unused.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Matching"],"href":"/docs/kit/advanced-routing#Matching","content":"A route like src/routes/fruits/[page] would match /fruits/apple, but it would also match /fruits/rocketship. We don't want that. You can ensure that route parameters are well-formed by adding a matcher — which takes the parameter string (\"apple\" or \"rocketship\") and returns true if it is valid — to your src/params directory... \n/**\n * @param {string} param\n * @return {param is ('apple' | 'orange')}\n * @satisfies {import('@sveltejs/kit').ParamMatcher}\n */\nexport function match(param) {\n\treturn param === 'apple' || param === 'orange';\n}...and augmenting your routes:src/routes/fruits/[page+++=fruit+++]If the pathname doesn't match, SvelteKit will try to match other routes (using the sort order specified below), before eventually returning a 404.Each module in the params directory corresponds to a matcher, with the exception of *.test.js and *.spec.js files which may be used to unit test your matchers.[!NOTE] Matchers run both on the server and in the browser.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Sorting"],"href":"/docs/kit/advanced-routing#Sorting","content":"It's possible for multiple routes to match a given path. For example each of these routes would match /foo-abc:src/routes/[...catchall]/+page.svelte\nsrc/routes/[[a=x]]/+page.svelte\nsrc/routes/[b]/+page.svelte\nsrc/routes/foo-[c]/+page.svelte\nsrc/routes/foo-abc/+page.svelteSvelteKit needs to know which route is being requested. To do so, it sorts them according to the following rules...More specific routes are higher priority (e.g. a route with no parameters is more specific than a route with one dynamic parameter, and so on)\nParameters with [matchers](#Matching) (`[name=type]`) are higher priority than those without (`[name]`)\n`[[optional]]` and `[...rest]` parameters are ignored unless they are the final part of the route, in which case they are treated with lowest priority. In other words `x/[[y]]/z` is treated equivalently to `x/z` for the purposes of sorting\nTies are resolved alphabetically...resulting in this ordering, meaning that /foo-abc will invoke src/routes/foo-abc/+page.svelte, and /foo-def will invoke src/routes/foo-[c]/+page.svelte rather than less specific routes:src/routes/foo-abc/+page.svelte\nsrc/routes/foo-[c]/+page.svelte\nsrc/routes/[[a=x]]/+page.svelte\nsrc/routes/[b]/+page.svelte\nsrc/routes/[...catchall]/+page.svelte","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Encoding"],"href":"/docs/kit/advanced-routing#Encoding","content":"Some characters can't be used on the filesystem — / on Linux and Mac, \\ / : * ? \" < > | on Windows. The # and % characters have special meaning in URLs, and the [ ] ( ) characters have special meaning to SvelteKit, so these also can't be used directly as part of your route.To use these characters in your routes, you can use hexadecimal escape sequences, which have the format [x+nn] where nn is a hexadecimal character code:`\\` — `[x+5c]`\n`/` — `[x+2f]`\n`:` — `[x+3a]`\n`*` — `[x+2a]`\n`?` — `[x+3f]`\n`\"` — `[x+22]`\n`<` — `[x+3c]`\n`>` — `[x+3e]`\n`|` — `[x+7c]`\n`#` — `[x+23]`\n`%` — `[x+25]`\n`[` — `[x+5b]`\n`]` — `[x+5d]`\n`(` — `[x+28]`\n`)` — `[x+29]`For example, to create a /smileys/:-) route, you would create a src/routes/smileys/[x+3a]-[x+29]/+page.svelte file.You can determine the hexadecimal code for a character with JavaScript:':'.charCodeAt(0).toString(16); // '3a', hence '[x+3a]'You can also use Unicode escape sequences. Generally you won't need to as you can use the unencoded character directly, but if — for some reason — you can't have a filename with an emoji in it, for example, then you can use the escaped characters. In other words, these are equivalent:src/routes/[u+d83e][u+dd2a]/+page.svelte\nsrc/routes/🤪/+page.svelteThe format for a Unicode escape sequence is [u+nnnn] where nnnn is a valid value between 0000 and 10ffff. (Unlike JavaScript string escaping, there's no need to use surrogate pairs to represent code points above ffff.) To learn more about Unicode encodings, consult Programming with Unicode.[!NOTE] Since TypeScript [struggles](https://github.com/microsoft/TypeScript/issues/13399) with directories with a leading `.` character, you may find it useful to encode these characters when creating e.g. [`.well-known`](https://en.wikipedia.org/wiki/Well-known_URI) routes: `src/routes/[x+2e]well-known/...`","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts"],"href":"/docs/kit/advanced-routing#Advanced-layouts","content":"By default, the layout hierarchy mirrors the route hierarchy. In some cases, that might not be what you want.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts","(group)"],"href":"/docs/kit/advanced-routing#Advanced-layouts-(group)","content":"Perhaps you have some routes that are 'app' routes that should have one layout (e.g. /dashboard or /item), and others that are 'marketing' routes that should have a different layout (/about or /testimonials). We can group these routes with a directory whose name is wrapped in parentheses — unlike normal directories, (app) and (marketing) do not affect the URL pathname of the routes inside them:src/routes/\n+++│ (app)/+++\n│ ├ dashboard/\n│ ├ item/\n│ └ +layout.svelte\n+++│ (marketing)/+++\n│ ├ about/\n│ ├ testimonials/\n│ └ +layout.svelte\n├ admin/\n└ +layout.svelteYou can also put a +page directly inside a (group), for example if / should be an (app) or a (marketing) page.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts","Breaking out of layouts"],"href":"/docs/kit/advanced-routing#Advanced-layouts-Breaking-out-of-layouts","content":"The root layout applies to every page of your app — if omitted, it defaults to {@render children()}. If you want some pages to have a different layout hierarchy than the rest, then you can put your entire app inside one or more groups except the routes that should not inherit the common layouts.In the example above, the /admin route does not inherit either the (app) or (marketing) layouts.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts","+page@"],"href":"/docs/kit/advanced-routing#Advanced-layouts-page","content":"Pages can break out of the current layout hierarchy on a route-by-route basis. Suppose we have an /item/[id]/embed route inside the (app) group from the previous example:src/routes/\n├ (app)/\n│ ├ item/\n│ │ ├ [id]/\n│ │ │ ├ embed/\n+++│ │ │ │ └ +page.svelte+++\n│ │ │ └ +layout.svelte\n│ │ └ +layout.svelte\n│ └ +layout.svelte\n└ +layout.svelteOrdinarily, this would inherit the root layout, the (app) layout, the item layout and the [id] layout. We can reset to one of those layouts by appending @ followed by the segment name — or, for the root layout, the empty string. In this example, we can choose from the following options:`+page@[id].svelte` - inherits from `src/routes/(app)/item/[id]/+layout.svelte`\n`+page@item.svelte` - inherits from `src/routes/(app)/item/+layout.svelte`\n`+page@(app).svelte` - inherits from `src/routes/(app)/+layout.svelte`\n`+page@.svelte` - inherits from `src/routes/+layout.svelte`src/routes/\n├ (app)/\n│ ├ item/\n│ │ ├ [id]/\n│ │ │ ├ embed/\n+++│ │ │ │ └ +page@(app).svelte+++\n│ │ │ └ +layout.svelte\n│ │ └ +layout.svelte\n│ └ +layout.svelte\n└ +layout.svelte","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts","+layout@"],"href":"/docs/kit/advanced-routing#Advanced-layouts-layout","content":"Like pages, layouts can themselves break out of their parent layout hierarchy, using the same technique. For example, a +layout@.svelte component would reset the hierarchy for all its child routes.src/routes/\n├ (app)/\n│ ├ item/\n│ │ ├ [id]/\n│ │ │ ├ embed/\n│ │ │ │ └ +page.svelte  // uses (app)/item/[id]/+layout.svelte\n│ │ │ ├ +layout.svelte  // inherits from (app)/item/+layout@.svelte\n│ │ │ └ +page.svelte    // uses (app)/item/+layout@.svelte\n│ │ └ +layout@.svelte   // inherits from root layout, skipping (app)/+layout.svelte\n│ └ +layout.svelte\n└ +layout.svelte","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Advanced layouts","When to use layout groups"],"href":"/docs/kit/advanced-routing#Advanced-layouts-When-to-use-layout-groups","content":"Not all use cases are suited for layout grouping, nor should you feel compelled to use them. It might be that your use case would result in complex (group) nesting, or that you don't want to introduce a (group) for a single outlier. It's perfectly fine to use other means such as composition (reusable load functions or Svelte components) or if-statements to achieve what you want. The following example shows a layout that rewinds to the root layout and reuses components and functions that other layouts can also use:<!--- file: src/routes/nested/route/+layout@.svelte --->\n<script>\n\timport ReusableLayout from '$lib/ReusableLayout.svelte';\n\tlet { data, children } = $props();\n</script>\n\n<ReusableLayout {data}>\n\t{@render children()}\n</ReusableLayout>import { reusableLoad } from '$lib/reusable-load-function';\n\n/** @type {import('./$types').PageLoad} */\nexport function load(event) {\n\t// Add additional logic here, if needed\n\treturn reusableLoad(event);\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Advanced routing","Further reading"],"href":"/docs/kit/advanced-routing#Further-reading","content":"[Tutorial: Advanced Routing](/tutorial/kit/optional-params)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks"],"href":"/docs/kit/hooks","content":"'Hooks' are app-wide functions you declare that SvelteKit will call in response to specific events, giving you fine-grained control over the framework's behaviour.There are three hooks files, all optional:`src/hooks.server.js` — your app's server hooks\n`src/hooks.client.js` — your app's client hooks\n`src/hooks.js` — your app's hooks that run on both the client and serverCode in these modules will run when the application starts up, making them useful for initializing database clients and so on.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Server hooks"],"href":"/docs/kit/hooks#Server-hooks","content":"The following hooks can be added to src/hooks.server.js:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Server hooks","handle"],"href":"/docs/kit/hooks#Server-hooks-handle","content":"This function runs every time the SvelteKit server receives a request — whether that happens while the app is running, or during prerendering — and determines the response. It receives an event object representing the request and a function called resolve, which renders the route and generates a Response. This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example). \n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tif (event.url.pathname.startsWith('/custom')) {\n\t\treturn new Response('custom response');\n\t}\n\n\tconst response = await resolve(event);\n\treturn response;\n}[!NOTE] Requests for static assets — which includes pages that were already prerendered — are _not_ handled by SvelteKit.If unimplemented, defaults to ({ event, resolve }) => resolve(event).During prerendering, SvelteKit crawls your pages for links and renders each route it finds. Rendering the route invokes the handle function (and all other route dependencies, like load). If you need to exclude some code from running during this phase, check that the app is not `building` beforehand.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Server hooks","locals"],"href":"/docs/kit/hooks#Server-hooks-locals","content":"To add custom data to the request, which is passed to handlers in +server.js and server load functions, populate the event.locals object, as shown below./** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tevent.locals.user = await getUserInformation(event.cookies.get('sessionid'));\n\n\tconst response = await resolve(event);\n\n\t// Note that modifying response headers isn't always safe.\n\t// Response objects can have immutable headers\n\t// (e.g. Response.redirect() returned from an endpoint).\n\t// Modifying immutable headers throws a TypeError.\n\t// In that case, clone the response or avoid creating a\n\t// response object with immutable headers.\n\tresponse.headers.set('x-custom-header', 'potato');\n\n\treturn response;\n}You can define multiple handle functions and execute them with the `sequence` helper function.resolve also supports a second, optional parameter that gives you more control over how the response will be rendered. That parameter is an object that can have the following fields:`transformPageChunk(opts: { html: string, done: boolean }): MaybePromise<string | undefined>` — applies custom transforms to HTML. If `done` is true, it's the final chunk. Chunks are not guaranteed to be well-formed HTML (they could include an element's opening tag but not its closing tag, for example) but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components.\n`filterSerializedResponseHeaders(name: string, value: string): boolean` — determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. By default, none will be included.\n`preload(input: { type: 'js' | 'css' | 'font' | 'asset', path: string }): boolean` — determines what files should be added to the `<head>` tag to preload it. The method is called with each file that was found at build time while constructing the code chunks — so if you for example have `import './styles.css` in your `+page.svelte`, `preload` will be called with the resolved path to that CSS file when visiting that page. Note that in dev mode `preload` is _not_ called, since it depends on analysis that happens at build time. Preloading can improve performance by downloading assets sooner, but it can also hurt if too much is downloaded unnecessarily. By default, `js` and `css` files will be preloaded. `asset` files are not preloaded at all currently, but we may add this later after evaluating feedback. \n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tconst response = await resolve(event, {\n\t\ttransformPageChunk: ({ html }) => html.replace('old', 'new'),\n\t\tfilterSerializedResponseHeaders: (name) => name.startsWith('x-'),\n\t\tpreload: ({ type, path }) => type === 'js' || path.includes('/important/')\n\t});\n\n\treturn response;\n}Note that resolve(...) will never throw an error, it will always return a Promise<Response> with the appropriate status code. If an error is thrown elsewhere during handle, it is treated as fatal, and SvelteKit will respond with a JSON representation of the error or a fallback error page — which can be customised via src/error.html — depending on the Accept header. You can read more about error handling here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Server hooks","handleFetch"],"href":"/docs/kit/hooks#Server-hooks-handleFetch","content":"This function allows you to modify (or replace) the result of an `event.fetch` call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.For example, your load function might make a request to a public URL like https://api.yourapp.com when the user performs a client-side navigation to the respective page, but during SSR it might make sense to hit the API directly (bypassing whatever proxies and load balancers sit between it and the public internet). \n/** @type {import('@sveltejs/kit').HandleFetch} */\nexport async function handleFetch({ request, fetch }) {\n\tif (request.url.startsWith('https://api.yourapp.com/')) {\n\t\t// clone the original request, but change the URL\n\t\trequest = new Request(\n\t\t\trequest.url.replace('https://api.yourapp.com/', 'http://localhost:9999/'),\n\t\t\trequest\n\t\t);\n\t}\n\n\treturn fetch(request);\n}Requests made with event.fetch follow the browser's credentials model — for same-origin requests, cookie and authorization headers are forwarded unless the credentials option is set to \"omit\". For cross-origin requests, cookie will be included if the request URL belongs to a subdomain of the app — for example if your app is on my-domain.com, and your API is on api.my-domain.com, cookies will be included in the request.There is one caveat: if your app and your API are on sibling subdomains — www.my-domain.com and api.my-domain.com for example — then a cookie belonging to a common parent domain like my-domain.com will not be included, because SvelteKit has no way to know which domain the cookie belongs to. In these cases you will need to manually include the cookie using handleFetch: \n \n/** @type {import('@sveltejs/kit').HandleFetch} */\nexport async function handleFetch({ event, request, fetch }) {\n\tif (request.url.startsWith('https://api.my-domain.com/')) {\n\t\trequest.headers.set('cookie', event.request.headers.get('cookie'));\n\t}\n\n\treturn fetch(request);\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Server hooks","handleValidationError"],"href":"/docs/kit/hooks#Server-hooks-handleValidationError","content":"This hook is called when a remote function is called with an argument that does not match the provided Standard Schema. It must return an object matching the shape of `App.Error`.Say you have a remote function that expects a string as its argument ... \nimport * as v from 'valibot';\nimport { query } from '$app/server';\n\nexport const getTodo = query(v.string(), (id) => {\n\t// implementation...\n});...but it is called with something that doesn't match the schema — such as a number (e.g. await getTodos(1)) — then validation will fail, the server will respond with a 400 status code, and the function will throw with the message 'Bad Request'.To customise this message and add additional properties to the error object, implement handleValidationError: \n/** @type {import('@sveltejs/kit').HandleValidationError} */\nexport function handleValidationError({ issues }) {\n\treturn {\n\t\tmessage: 'No thank you'\n\t};\n}Be thoughtful about what information you expose here, as the most likely reason for validation to fail is that someone is sending malicious requests to your server.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Shared hooks"],"href":"/docs/kit/hooks#Shared-hooks","content":"The following can be added to src/hooks.server.js and src/hooks.client.js:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Shared hooks","handleError"],"href":"/docs/kit/hooks#Shared-hooks-handleError","content":"If an unexpected error is thrown during loading, rendering, or from an endpoint, this function will be called with the error, event, status code and message. This allows for two things:you can log the error\nyou can generate a custom representation of the error that is safe to show to users, omitting sensitive details like messages and stack traces. The returned value, which defaults to `{ message }`, becomes the value of `page.error`.For errors thrown from your code (or library code called by your code) the status will be 500 and the message will be \"Internal Error\". While error.message may contain sensitive information that should not be exposed to users, message is safe (albeit meaningless to the average user).To add more information to the page.error object in a type-safe way, you can customize the expected shape by declaring an App.Error interface (which must include message: string, to guarantee sensible fallback behavior). This allows you to — for example — append a tracking ID for users to quote in correspondence with your technical support staff: \ndeclare global {\n\tnamespace App {\n\t\tinterface Error {\n\t\t\tmessage: string;\n\t\t\terrorId: string;\n\t\t}\n\t}\n}\n\nexport {};import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({/*...*/})\n\n/** @type {import('@sveltejs/kit').HandleServerError} */\nexport async function handleError({ error, event, status, message }) {\n\tconst errorId = crypto.randomUUID();\n\n\t// example integration with https://sentry.io/\n\tSentry.captureException(error, {\n\t\textra: { event, errorId, status }\n\t});\n\n\treturn {\n\t\tmessage: 'Whoops!',\n\t\terrorId\n\t};\n}import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({/*...*/})\n\n/** @type {import('@sveltejs/kit').HandleClientError} */\nexport async function handleError({ error, event, status, message }) {\n\tconst errorId = crypto.randomUUID();\n\n\t// example integration with https://sentry.io/\n\tSentry.captureException(error, {\n\t\textra: { event, errorId, status }\n\t});\n\n\treturn {\n\t\tmessage: 'Whoops!',\n\t\terrorId\n\t};\n}[!NOTE] In `src/hooks.client.js`, the type of `handleError` is `HandleClientError` instead of `HandleServerError`, and `event` is a `NavigationEvent` rather than a `RequestEvent`.This function is not called for expected errors (those thrown with the `error` function imported from @sveltejs/kit).During development, if an error occurs because of a syntax error in your Svelte code, the passed in error has a frame property appended highlighting the location of the error.[!NOTE] Make sure that `handleError` _never_ throws an error","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Shared hooks","init"],"href":"/docs/kit/hooks#Shared-hooks-init","content":"This function runs once, when the server is created or the app starts in the browser, and is a useful place to do asynchronous work such as initializing a database connection.[!NOTE] If your environment supports top-level await, the `init` function is really no different from writing your initialisation logic at the top level of the module, but some environments — most notably, Safari — don't. \n \nimport * as db from '$lib/server/database';\n\n/** @type {import('@sveltejs/kit').ServerInit} */\nexport async function init() {\n\tawait db.connect();\n}[!NOTE]\nIn the browser, asynchronous work in `init` will delay hydration, so be mindful of what you put in there.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Universal hooks"],"href":"/docs/kit/hooks#Universal-hooks","content":"The following can be added to src/hooks.js. Universal hooks run on both server and client (not to be confused with shared hooks, which are environment-specific).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Universal hooks","reroute"],"href":"/docs/kit/hooks#Universal-hooks-reroute","content":"This function runs before handle and allows you to change how URLs are translated into routes. The returned pathname (which defaults to url.pathname) is used to select the route and its parameters.For example, you might have a src/routes/[[lang]]/about/+page.svelte page, which should be accessible as /en/about or /de/ueber-uns or /fr/a-propos. You could implement this with reroute: \n \n\n/** @type {Record<string, string>} */\nconst translated = {\n\t'/en/about': '/en/about',\n\t'/de/ueber-uns': '/de/about',\n\t'/fr/a-propos': '/fr/about',\n};\n\n/** @type {import('@sveltejs/kit').Reroute} */\nexport function reroute({ url }) {\n\tif (url.pathname in translated) {\n\t\treturn translated[url.pathname];\n\t}\n}The lang parameter will be correctly derived from the returned pathname.Using reroute will not change the contents of the browser's address bar, or the value of event.url.Since version 2.18, the reroute hook can be asynchronous, allowing it to (for example) fetch data from your backend to decide where to reroute to. Use this carefully and make sure it's fast, as it will delay navigation otherwise. If you need to fetch data, use the fetch provided as an argument. It has the same benefits as the fetch provided to load functions, with the caveat that params and id are unavailable to `handleFetch` because the route is not yet known. \n \n\n/** @type {import('@sveltejs/kit').Reroute} */\nexport async function reroute({ url, fetch }) {\n\t// Ask a special endpoint within your app about the destination\n\tif (url.pathname === '/api/reroute') return;\n\n\tconst api = new URL('/api/reroute', url);\n\tapi.searchParams.set('pathname', url.pathname);\n\n\tconst result = await fetch(api).then(r => r.json());\n\treturn result.pathname;\n}[!NOTE] `reroute` is considered a pure, idempotent function. As such, it must always return the same output for the same input and not have side effects. Under these assumptions, SvelteKit caches the result of `reroute` on the client so it is only called once per unique URL.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Universal hooks","transport"],"href":"/docs/kit/hooks#Universal-hooks-transport","content":"This is a collection of transporters, which allow you to pass custom types — returned from load and form actions — across the server/client boundary. Each transporter contains an encode function, which encodes values on the server (or returns a falsy value for anything that isn't an instance of the type) and a corresponding decode function: \n \nimport { Vector } from '$lib/math';\n\n/** @type {import('@sveltejs/kit').Transport} */\nexport const transport = {\n\tVector: {\n\t\tencode: (value) => value instanceof Vector && [value.x, value.y],\n\t\tdecode: ([x, y]) => new Vector(x, y)\n\t}\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Hooks","Further reading"],"href":"/docs/kit/hooks#Further-reading","content":"[Tutorial: Hooks](/tutorial/kit/handle)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors"],"href":"/docs/kit/errors","content":"Errors are an inevitable fact of software development. SvelteKit handles errors differently depending on where they occur, what kind of errors they are, and the nature of the incoming request.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Error objects"],"href":"/docs/kit/errors#Error-objects","content":"SvelteKit distinguishes between expected and unexpected errors, both of which are represented as simple { message: string } objects by default.You can add additional properties, like a code or a tracking id, as shown in the examples below. (When using TypeScript this requires you to redefine the Error type as described in  type safety).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Expected errors"],"href":"/docs/kit/errors#Expected-errors","content":"An expected error is one created with the `error` helper imported from @sveltejs/kit:import { error } from '@sveltejs/kit';\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n\tconst post = await db.getPost(params.slug);\n\n\tif (!post) {\n\t\terror(404, {\n\t\t\tmessage: 'Not found'\n\t\t});\n\t}\n\n\treturn { post };\n}This throws an exception that SvelteKit catches, causing it to set the response status code to 404 and render an `+error.svelte` component, where page.error is the object provided as the second argument to error(...).<!--- file: src/routes/+error.svelte --->\n<script>\n\timport { page } from '$app/state';\n</script>\n\n<h1>{page.error.message}</h1>[!LEGACY]\n`$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.You can add extra properties to the error object if needed...error(404, {\n\tmessage: 'Not found',\n\t+++code: 'NOT_FOUND'+++\n});...otherwise, for convenience, you can pass a string as the second argument:---error(404, { message: 'Not found' });---\n+++error(404, 'Not found');+++[!NOTE] [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the `error` yourself","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Unexpected errors"],"href":"/docs/kit/errors#Unexpected-errors","content":"An unexpected error is any other exception that occurs while handling a request. Since these can contain sensitive information, unexpected error messages and stack traces are not exposed to users.By default, unexpected errors are printed to the console (or, in production, your server logs), while the error that is exposed to the user has a generic shape:{ \"message\": \"Internal Error\" }Unexpected errors will go through the `handleError` hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object which becomes page.error.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Rendering errors"],"href":"/docs/kit/errors#Rendering-errors","content":"Ordinarily, if an error happens during server-side rendering (for example inside a component's <script> block or template), SvelteKit will return a 500 error page.Since SvelteKit 2.54 and Svelte 5.53, you can change this by enabling the experimental handleRenderingErrors option in your config: \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\texperimental: {\n\t\t\thandleRenderingErrors: true\n\t\t}\n\t}\n};\n\nexport default config;When this is enabled, SvelteKit will wrap your route components in an error boundary. If an error occurs during rendering, the nearest `+error.svelte` page will be shown, just as if the error had occurred in a load function.The error is first passed to `handleError`, allowing you to report it and transform it, before the resulting object is passed to the +error.svelte component.[!NOTE]\nSince rendering errors occur after the page has started rendering, and multiple boundaries could in parallel catch distinct errors, the [`page`]($app-state#page) object (and its `error` property) will not be updated. Instead, the error is passed directly to the `+error.svelte` component as a prop.<!--- file: +error.svelte --->\n<script>\n\tlet { error } = $props();\n</script>\n\n<h1>{error.message}</h1>The same applies for other error boundaries you define in your code:<svelte:boundary>\n\t...\n\t{#snippet failed(error: App.Error)}\n\t\t<!-- error went through handleError and is of type App.Error -->\n\t\t{error.message}\n\t{/snippet}\n</svelte:boundary>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Responses"],"href":"/docs/kit/errors#Responses","content":"If an error occurs inside handle or inside a `+server.js` request handler, SvelteKit will respond with either a fallback error page or a JSON representation of the error object, depending on the request's Accept headers.You can customise the fallback error page by adding a src/error.html file:<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>%sveltekit.error.message%</title>\n\t</head>\n\t<body>\n\t\t<h1>My custom error page</h1>\n\t\t<p>Status: %sveltekit.status%</p>\n\t\t<p>Message: %sveltekit.error.message%</p>\n\t</body>\n</html>SvelteKit will replace %sveltekit.status% and %sveltekit.error.message% with their corresponding values.If the error instead occurs inside a load function while rendering a page, SvelteKit will render the `+error.svelte` component nearest to where the error occurred. If the error occurs inside a load function in +layout(.server).js, the closest error boundary in the tree is an +error.svelte file above that layout (not next to it).The exception is when the error occurs inside the root +layout.js or +layout.server.js, since the root layout would ordinarily contain the +error.svelte component. In this case, SvelteKit uses the fallback error page.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Type safety"],"href":"/docs/kit/errors#Type-safety","content":"If you're using TypeScript and need to customize the shape of errors, you can do so by declaring an App.Error interface in your app (by convention, in src/app.d.ts, though it can live anywhere that TypeScript can 'see'): \ndeclare global {\n\tnamespace App {\n\t\tinterface Error {\n+++\t\t\tcode: string;\n\t\t\tid: string;+++\n\t\t}\n\t}\n}\n\nexport {};This interface always includes a message: string property.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Errors","Further reading"],"href":"/docs/kit/errors#Further-reading","content":"[Tutorial: Errors and redirects](/tutorial/kit/error-basics)\n[Tutorial: Hooks](/tutorial/kit/handle)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options"],"href":"/docs/kit/link-options","content":"In SvelteKit, <a> elements (rather than framework-specific <Link> components) are used to navigate between the routes of your app. If the user clicks on a link whose href is 'owned' by the app (as opposed to, say, a link to an external site) then SvelteKit will navigate to the new page by importing its code and then calling any load functions it needs to fetch data.You can customise the behaviour of links with data-sveltekit-* attributes. These can be applied to the <a> itself, or to a parent element.These options also apply to <form> elements with `method=\"GET\"`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-preload-data"],"href":"/docs/kit/link-options#data-sveltekit-preload-data","content":"Before the browser registers that the user has clicked on a link, we can detect that they've hovered the mouse over it (on desktop) or that a touchstart or mousedown event was triggered. In both cases, we can make an educated guess that a click event is coming.SvelteKit can use this information to get a head start on importing the code and fetching the page's data, which can give us an extra couple of hundred milliseconds — the difference between a user interface that feels laggy and one that feels snappy.We can control this behaviour with the data-sveltekit-preload-data attribute, which can have one of two values:`\"hover\"` means that preloading will start if the mouse comes to a rest over a link. On mobile, preloading begins on `touchstart`\n`\"tap\"` means that preloading will start as soon as a `touchstart` or `mousedown` event is registeredThe default project template has a data-sveltekit-preload-data=\"hover\" attribute applied to the <body> element in src/app.html, meaning that every link is preloaded on hover by default:<body data-sveltekit-preload-data=\"hover\">\n\t<div style=\"display: contents\">%sveltekit.body%</div>\n</body>Sometimes, calling load when the user hovers over a link might be undesirable, either because it's likely to result in false positives (a click needn't follow a hover) or because data is updating very quickly and a delay could mean staleness.In these cases, you can specify the \"tap\" value, which causes SvelteKit to call load only when the user taps or clicks on a link:<a data-sveltekit-preload-data=\"tap\" href=\"/stonks\">\n\tGet current stonk values\n</a>[!NOTE] You can also programmatically invoke `preloadData` from `$app/navigation`.Data will never be preloaded if the user has chosen reduced data usage, meaning `navigator.connection.saveData` is true.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-preload-code"],"href":"/docs/kit/link-options#data-sveltekit-preload-code","content":"Even in cases where you don't want to preload data for a link, it can be beneficial to preload the code. The data-sveltekit-preload-code attribute works similarly to data-sveltekit-preload-data, except that it can take one of four values, in decreasing 'eagerness':`\"eager\"` means that links will be preloaded straight away\n`\"viewport\"` means that links will be preloaded once they enter the viewport\n`\"hover\"` - as above, except that only code is preloaded\n`\"tap\"` - as above, except that only code is preloadedNote that viewport and eager only apply to links that are present in the DOM immediately following navigation — if a link is added later (in an {#if ...} block, for example) it will not be preloaded until triggered by hover or tap. This is to avoid performance pitfalls resulting from aggressively observing the DOM for changes.[!NOTE] Since preloading code is a prerequisite for preloading data, this attribute will only have an effect if it specifies a more eager value than any `data-sveltekit-preload-data` attribute that is present.As with data-sveltekit-preload-data, this attribute will be ignored if the user has chosen reduced data usage.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-reload"],"href":"/docs/kit/link-options#data-sveltekit-reload","content":"Occasionally, we need to tell SvelteKit not to handle a link, but allow the browser to handle it. Adding a data-sveltekit-reload attribute to a link...<a data-sveltekit-reload href=\"/path\">Path</a>...will cause a full-page navigation when the link is clicked.Links with a rel=\"external\" attribute will receive the same treatment. In addition, they will be ignored during prerendering.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-replacestate"],"href":"/docs/kit/link-options#data-sveltekit-replacestate","content":"Sometimes you don't want navigation to create a new entry in the browser's session history. Adding a data-sveltekit-replacestate attribute to a link...<a data-sveltekit-replacestate href=\"/path\">Path</a>...will replace the current history entry rather than creating a new one with pushState when the link is clicked.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-keepfocus"],"href":"/docs/kit/link-options#data-sveltekit-keepfocus","content":"Sometimes you don't want focus to be reset after navigation. For example, maybe you have a search form that submits as the user is typing, and you want to keep focus on the text input.  Adding a data-sveltekit-keepfocus attribute to it...<form data-sveltekit-keepfocus>\n\t<input type=\"text\" name=\"query\">\n</form>...will cause the currently focused element to retain focus after navigation. In general, avoid using this attribute on links, since the focused element would be the <a> tag (and not a previously focused element) and screen reader and other assistive technology users often expect focus to be moved after a navigation. You should also only use this attribute on elements that still exist after navigation. If the element no longer exists, the user's focus will be lost, making for a confusing experience for assistive technology users.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","data-sveltekit-noscroll"],"href":"/docs/kit/link-options#data-sveltekit-noscroll","content":"When navigating to internal links, SvelteKit mirrors the browser's default navigation behaviour: it will change the scroll position to 0,0 so that the user is at the very top left of the page (unless the link includes a #hash, in which case it will scroll to the element with a matching ID).In certain cases, you may wish to disable this behaviour. Adding a data-sveltekit-noscroll attribute to a link...<a href=\"path\" data-sveltekit-noscroll>Path</a>...will prevent scrolling after the link is clicked.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Link options","Disabling options"],"href":"/docs/kit/link-options#Disabling-options","content":"To disable any of these options inside an element where they have been enabled, use the \"false\" value:<div data-sveltekit-preload-data>\n\t<!-- these links will be preloaded -->\n\t<a href=\"/a\">a</a>\n\t<a href=\"/b\">b</a>\n\t<a href=\"/c\">c</a>\n\n\t<div data-sveltekit-preload-data=\"false\">\n\t\t<!-- these links will NOT be preloaded -->\n\t\t<a href=\"/d\">d</a>\n\t\t<a href=\"/e\">e</a>\n\t\t<a href=\"/f\">f</a>\n\t</div>\n</div>To apply an attribute to an element conditionally, do this:<div data-sveltekit-preload-data={condition ? 'hover' : false}>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Service workers"],"href":"/docs/kit/service-workers","content":"Service workers act as proxy servers that handle network requests inside your app. This makes it possible to make your app work offline, but even if you don't need offline support (or can't realistically implement it because of the type of app you're building), it's often worth using service workers to speed up navigation by precaching your built JS and CSS.In SvelteKit, if you have a src/service-worker.js file (or src/service-worker/index.js) it will be bundled and automatically registered.You can disable automatic registration if you need to register the service worker with your own logic or use another solution. The default registration looks something like this:if ('serviceWorker' in navigator) {\n\taddEventListener('load', function () {\n\t\tnavigator.serviceWorker.register('./path/to/service-worker.js');\n\t});\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Service workers","Inside the service worker"],"href":"/docs/kit/service-workers#Inside-the-service-worker","content":"Inside the service worker you have access to the `$service-worker` module, which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string, which you can use for creating a unique cache name, and the deployment's base path. If your Vite config specifies define (used for global variable replacements), this will be applied to service workers as well as your server/client builds.The following example caches the built app and any files in static eagerly, and caches all other requests as they happen. This would make each page work offline once visited. \n \n// Disables access to DOM typings like `HTMLElement` which are not available\n// inside a service worker and instantiates the correct globals\n/// <reference no-default-lib=\"true\"/>\n/// <reference lib=\"esnext\" />\n/// <reference lib=\"webworker\" />\n\n// Ensures that the `$service-worker` import has proper type definitions\n/// <reference types=\"@sveltejs/kit\" />\n\n// Only necessary if you have an import from `$env/static/public`\n/// <reference types=\"../.svelte-kit/ambient.d.ts\" />\n\nimport { build, files, version } from '$service-worker';\n\n// This gives `self` the correct types\nconst self = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (globalThis.self));\n\n// Create a unique cache name for this deployment\nconst CACHE = `cache-${version}`;\n\nconst ASSETS = [\n\t...build, // the app itself\n\t...files  // everything in `static`\n];\n\nself.addEventListener('install', (event) => {\n\t// Create a new cache and add all files to it\n\tasync function addFilesToCache() {\n\t\tconst cache = await caches.open(CACHE);\n\t\tawait cache.addAll(ASSETS);\n\t}\n\n\tevent.waitUntil(addFilesToCache());\n});\n\nself.addEventListener('activate', (event) => {\n\t// Remove previous cached data from disk\n\tasync function deleteOldCaches() {\n\t\tfor (const key of await caches.keys()) {\n\t\t\tif (key !== CACHE) await caches.delete(key);\n\t\t}\n\t}\n\n\tevent.waitUntil(deleteOldCaches());\n});\n\nself.addEventListener('fetch', (event) => {\n\t// ignore POST requests etc\n\tif (event.request.method !== 'GET') return;\n\n\tasync function respond() {\n\t\tconst url = new URL(event.request.url);\n\t\tconst cache = await caches.open(CACHE);\n\n\t\t// `build`/`files` can always be served from the cache\n\t\tif (ASSETS.includes(url.pathname)) {\n\t\t\tconst response = await cache.match(url.pathname);\n\n\t\t\tif (response) {\n\t\t\t\treturn response;\n\t\t\t}\n\t\t}\n\n\t\t// for everything else, try the network first, but\n\t\t// fall back to the cache if we're offline\n\t\ttry {\n\t\t\tconst response = await fetch(event.request);\n\n\t\t\t// if we're offline, fetch can return a value that is not a Response\n\t\t\t// instead of throwing - and we can't pass this non-Response to respondWith\n\t\t\tif (!(response instanceof Response)) {\n\t\t\t\tthrow new Error('invalid response from fetch');\n\t\t\t}\n\n\t\t\tif (response.status === 200 && !response.headers.get('cache-control')?.includes('no-store')) {\n\t\t\t\tcache.put(event.request, response.clone());\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (err) {\n\t\t\tconst response = await cache.match(event.request);\n\n\t\t\tif (response) {\n\t\t\t\treturn response;\n\t\t\t}\n\n\t\t\t// if there's no cache, then just error out\n\t\t\t// as there is nothing we can do to respond to this request\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tevent.respondWith(respond());\n});[!NOTE] Be careful when caching! In some cases, stale data might be worse than data that's unavailable while offline. Since browsers will empty caches if they get too full, you should also be careful about caching large assets like video files.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Service workers","During development"],"href":"/docs/kit/service-workers#During-development","content":"The service worker is bundled for production, but not during development. For that reason, only browsers that support modules in service workers will be able to use them at dev time. If you are manually registering your service worker, you will need to pass the { type: 'module' } option in development:import { dev } from '$app/environment';\n\nnavigator.serviceWorker.register('/service-worker.js', {\n\ttype: dev ? 'module' : 'classic'\n});[!NOTE] `build` and `prerendered` are empty arrays during development","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Service workers","Other solutions"],"href":"/docs/kit/service-workers#Other-solutions","content":"SvelteKit's service worker implementation is designed to be easy to work with and is probably a good solution for most users. However, outside of SvelteKit, many PWA applications leverage the Workbox library. If you're used to using Workbox you may prefer Vite PWA plugin.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Service workers","References"],"href":"/docs/kit/service-workers#References","content":"For more general information on service workers, we recommend the MDN web docs.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules"],"href":"/docs/kit/server-only-modules","content":"Like a good friend, SvelteKit keeps your secrets. When writing your backend and frontend in the same repository, it can be easy to accidentally import sensitive data into your front-end code (environment variables containing API keys, for example). SvelteKit provides a way to prevent this entirely: server-only modules.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules","Private environment variables"],"href":"/docs/kit/server-only-modules#Private-environment-variables","content":"The `$env/static/private` and `$env/dynamic/private` modules can only be imported into modules that only run on the server, such as `hooks.server.js` or `+page.server.js`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules","Server-only utilities"],"href":"/docs/kit/server-only-modules#Server-only-utilities","content":"The `$app/server` module, which contains a `read` function for reading assets from the filesystem, can likewise only be imported by code that runs on the server.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules","Your modules"],"href":"/docs/kit/server-only-modules#Your-modules","content":"You can make your own modules server-only in two ways:adding `.server` to the filename, e.g. `secrets.server.js`\nplacing them in `$lib/server`, e.g. `$lib/server/secrets.js`","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules","How it works"],"href":"/docs/kit/server-only-modules#How-it-works","content":"Any time you have public-facing code that imports server-only code (whether directly or indirectly)... \n \nexport const atlantisCoordinates = [/* redacted */]; \n \nexport { atlantisCoordinates } from '$lib/server/secrets.js';\n\nexport const add = (a, b) => a + b; \n<script>\n\timport { add } from './utils.js';\n</script>...SvelteKit will error:Cannot import $lib/server/secrets.ts into code that runs in the browser, as this could leak sensitive information.\n\n src/routes/+page.svelte imports\n  src/routes/utils.js imports\n   $lib/server/secrets.ts\n\nIf you're only using the import as a type, change it to `import type`.Even though the public-facing code — src/routes/+page.svelte — only uses the add export and not the secret atlantisCoordinates export, the secret code could end up in JavaScript that the browser downloads, and so the import chain is considered unsafe.This feature also works with dynamic imports, even interpolated ones like await import(`./${foo}.js`).[!NOTE] Unit testing frameworks like Vitest do not distinguish between server-only and public-facing code. For this reason, illegal import detection is disabled when running tests, as determined by `process.env.TEST === 'true'`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Server-only modules","Further reading"],"href":"/docs/kit/server-only-modules#Further-reading","content":"[Tutorial: Environment variables](/tutorial/kit/env-static-private)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Snapshots"],"href":"/docs/kit/snapshots","content":"Ephemeral DOM state — like scroll positions on sidebars, the content of <input> elements and so on — is discarded when you navigate from one page to another.For example, if the user fills out a form but navigates away and then back before submitting, or if the user refreshes the page, the values they filled in will be lost. In cases where it's valuable to preserve that input, you can take a snapshot of DOM state, which can then be restored if the user navigates back.To do this, export a snapshot object with capture and restore methods from a +page.svelte or +layout.svelte:<!--- file: +page.svelte --->\n<script>\n\tlet comment = $state('');\n\n\t/** @type {import('./$types').Snapshot<string>} */\n\texport const snapshot = {\n\t\tcapture: () => comment,\n\t\trestore: (value) => comment = value\n\t};\n</script>\n\n<form method=\"POST\">\n\t<label for=\"comment\">Comment</label>\n\t<textarea id=\"comment\" bind:value={comment} />\n\t<button>Post comment</button>\n</form>When you navigate away from this page, the capture function is called immediately before the page updates, and the returned value is associated with the current entry in the browser's history stack. If you navigate back, the restore function is called with the stored value as soon as the page is updated.The data must be serializable as JSON so that it can be persisted to sessionStorage. This allows the state to be restored when the page is reloaded, or when the user navigates back from a different site.[!NOTE] Avoid returning very large objects from `capture` — once captured, objects will be retained in memory for the duration of the session, and in extreme cases may be too large to persist to `sessionStorage`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Shallow routing"],"href":"/docs/kit/shallow-routing","content":"As you navigate around a SvelteKit app, you create history entries. Clicking the back and forward buttons traverses through this list of entries, re-running any load functions and replacing page components as necessary.Sometimes, it's useful to create history entries without navigating. For example, you might want to show a modal dialog that the user can dismiss by navigating back. This is particularly valuable on mobile devices, where swipe gestures are often more natural than interacting directly with the UI. In these cases, a modal that is not associated with a history entry can be a source of frustration, as a user may swipe backwards in an attempt to dismiss it and find themselves on the wrong page.SvelteKit makes this possible with the `pushState` and `replaceState` functions, which allow you to associate state with a history entry without navigating. For example, to implement a history-driven modal:<!--- file: +page.svelte --->\n<script>\n\timport { pushState } from '$app/navigation';\n\timport { page } from '$app/state';\n\timport Modal from './Modal.svelte';\n\n\tfunction showModal() {\n\t\tpushState('', {\n\t\t\tshowModal: true\n\t\t});\n\t}\n</script>\n\n{#if page.state.showModal}\n\t<Modal close={() => history.back()} />\n{/if}The modal can be dismissed by navigating back (unsetting page.state.showModal) or by interacting with it in a way that causes the close callback to run, which will navigate back programmatically.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Shallow routing","API"],"href":"/docs/kit/shallow-routing#API","content":"The first argument to pushState is the URL, relative to the current URL. To stay on the current URL, use ''.The second argument is the new page state, which can be accessed via the page object as page.state. You can make page state type-safe by declaring an `App.PageState` interface (usually in src/app.d.ts).To set page state without creating a new history entry, use replaceState instead of pushState.[!LEGACY]\n`page.state` from `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$page.state` from `$app/stores` instead.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Shallow routing","Loading data for a route"],"href":"/docs/kit/shallow-routing#Loading-data-for-a-route","content":"When shallow routing, you may want to render another +page.svelte inside the current page. For example, clicking on a photo thumbnail could pop up the detail view without navigating to the photo page.For this to work, you need to load the data that the +page.svelte expects. A convenient way to do this is to use `preloadData` inside the click handler of an <a> element. If the element (or a parent) uses `data-sveltekit-preload-data`, the data will have already been requested, and preloadData will reuse that request.<!--- file: src/routes/photos/+page.svelte --->\n<script>\n\timport { preloadData, pushState, goto } from '$app/navigation';\n\timport { page } from '$app/state';\n\timport Modal from './Modal.svelte';\n\timport PhotoPage from './[id]/+page.svelte';\n\n\tlet { data } = $props();\n</script>\n\n{#each data.thumbnails as thumbnail}\n\t<a\n\t\thref=\"/photos/{thumbnail.id}\"\n\t\tonclick={async (e) => {\n\t\t\tif (innerWidth < 640        // bail if the screen is too small\n\t\t\t\t|| e.shiftKey             // or the link is opened in a new window\n\t\t\t\t|| e.metaKey || e.ctrlKey // or a new tab (mac: metaKey, win/linux: ctrlKey)\n\t\t\t\t// should also consider clicking with a mouse scroll wheel\n\t\t\t) return;\n\n\t\t\t// prevent navigation\n\t\t\te.preventDefault();\n\n\t\t\tconst { href } = e.currentTarget;\n\n\t\t\t// run `load` functions (or rather, get the result of the `load` functions\n\t\t\t// that are already running because of `data-sveltekit-preload-data`)\n\t\t\tconst result = await preloadData(href);\n\n\t\t\tif (result.type === 'loaded' && result.status === 200) {\n\t\t\t\tpushState(href, { selected: result.data });\n\t\t\t} else {\n\t\t\t\t// something bad happened! try navigating\n\t\t\t\tgoto(href);\n\t\t\t}\n\t\t}}\n\t>\n\t\t<img alt={thumbnail.alt} src={thumbnail.src} />\n\t</a>\n{/each}\n\n{#if page.state.selected}\n\t<Modal onclose={() => history.back()}>\n\t\t<!-- pass page data to the +page.svelte component,\n\t\t     just like SvelteKit would on navigation -->\n\t\t<PhotoPage data={page.state.selected} />\n\t</Modal>\n{/if}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Shallow routing","Caveats"],"href":"/docs/kit/shallow-routing#Caveats","content":"During server-side rendering, page.state is always an empty object. The same is true for the first page the user lands on — if the user reloads the page (or returns from another document), state will not be applied until they navigate.Shallow routing is a feature that requires JavaScript to work. Be mindful when using it and try to think of sensible fallback behavior in case JavaScript isn't available.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Observability"],"href":"/docs/kit/observability","content":"Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side OpenTelemetry spans for the following:The [`handle`](hooks#Server-hooks-handle) hook and `handle` functions running in a [`sequence`](@sveltejs-kit-hooks#sequence) (these will show up as children of each other and the root `handle` hook)\nServer [`load`](load) functions and universal `load` functions when they're run on the server\n[Form actions](form-actions)\n[Remote functions](remote-functions)Just telling SvelteKit to emit spans won't get you far, though — you need to actually collect them somewhere to be able to view them. SvelteKit provides src/instrumentation.server.ts as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it.Both of these features are currently experimental, meaning they are likely to contain bugs and are subject to change without notice. You must opt in by adding the kit.experimental.tracing.server and kit.experimental.instrumentation.server option in your svelte.config.js: \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\texperimental: {\n\t\t\t+++tracing: {\n\t\t\t\tserver: true\n\t\t\t},\n\t\t\tinstrumentation: {\n\t\t\t\tserver: true\n\t\t\t}+++\n\t\t}\n\t}\n};\n\nexport default config;[!NOTE] Tracing — and more significantly, observability instrumentation — can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Observability","Augmenting the built-in tracing"],"href":"/docs/kit/observability#Augmenting-the-built-in-tracing","content":"SvelteKit provides access to the root span and the current span on the request event. The root span is the one associated with your root handle function, and the current span could be associated with handle, load, a form action, or a remote function, depending on the context. You can annotate these spans with any attributes you wish to record:import { getRequestEvent } from '$app/server';\nimport { getAuthenticatedUser } from '$lib/auth-core';\n\nasync function authenticate() {\n\tconst user = await getAuthenticatedUser();\n\tconst event = getRequestEvent();\n\tevent.tracing.root.setAttribute('userId', user.id);\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Observability","Development quickstart"],"href":"/docs/kit/observability#Development-quickstart","content":"To view your first trace, you'll need to set up a local collector. We'll use Jaeger in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally:Turn on the experimental flags mentioned earlier in your `svelte.config.js` file\nUse your package manager to install the dependencies you'll need:\n```sh\nnpm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto import-in-the-middle\n```\nCreate `src/instrumentation.server.js` with the following: \n \nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport { createAddHookMessageChannel } from 'import-in-the-middle';\nimport { register } from 'node:module';\n\nconst { registerOptions } = createAddHookMessageChannel();\nregister('import-in-the-middle/hook.mjs', import.meta.url, registerOptions);\n\nconst sdk = new NodeSDK({\n\tserviceName: 'test-sveltekit-tracing',\n\ttraceExporter: new OTLPTraceExporter(),\n\tinstrumentations: [getNodeAutoInstrumentations()]\n});\n\nsdk.start();Now, server-side requests will begin generating traces, which you can view in Jaeger's web console at localhost:16686.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Observability","@opentelemetry/api"],"href":"/docs/kit/observability#opentelemetry-api","content":"SvelteKit uses @opentelemetry/api to generate its spans. This is declared as an optional peer dependency so that users not needing traces see no impact on install size or runtime performance. In most cases, if you're configuring your application to collect SvelteKit's spans, you'll end up installing a library like @opentelemetry/sdk-node or @vercel/otel, which in turn depend on @opentelemetry/api, which will satisfy SvelteKit's dependency as well. If you see an error from SvelteKit telling you it can't find @opentelemetry/api, it may just be because you haven't set up your trace collection yet. If you have done that and are still seeing the error, you can install @opentelemetry/api yourself.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging"],"href":"/docs/kit/packaging","content":"You can use SvelteKit to build apps as well as component libraries, using the @sveltejs/package package (npx sv create has an option to set this up for you).When you're creating an app, the contents of src/routes is the public-facing stuff; `src/lib` contains your app's internal library.A component library has the exact same structure as a SvelteKit app, except that src/lib is the public-facing bit, and your root package.json is used to publish the package. src/routes might be a documentation or demo site that accompanies the library, or it might just be a sandbox you use during development.Running the svelte-package command from @sveltejs/package will take the contents of src/lib and generate a dist directory (which can be configured) containing the following:All the files in `src/lib`. Svelte components will be preprocessed, TypeScript files will be transpiled to JavaScript.\nType definitions (`d.ts` files) which are generated for Svelte, JavaScript and TypeScript files. You need to install `typescript >= 4.0.0` for this. Type definitions are placed next to their implementation, hand-written `d.ts` files are copied over as is. You can [disable generation](#Options), but we strongly recommend against it — people using your library might use TypeScript, for which they require these type definition files.[!NOTE] `@sveltejs/package` version 1 generated a `package.json`. This is no longer the case and it will now use the `package.json` from your project and validate that it is correct instead. If you're still on version 1, see [this PR](https://github.com/sveltejs/kit/pull/8922) for migration instructions.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json","content":"Since you're now building a library for public use, the contents of your package.json will become more important. Through it, you configure the entry points of your package, which files are published to npm, and which dependencies your library has. Let's go through the most important fields one by one.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","name"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-name","content":"This is the name of your package. It will be available for others to install using that name, and visible on https://npmjs.com/package/<name>.{\n\t\"name\": \"your-library\"\n}Read more about it here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","license"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-license","content":"Every package should have a license field so people know how they are allowed to use it. A very popular license which is also very permissive in terms of distribution and reuse without warranty is MIT.{\n\t\"license\": \"MIT\"\n}Read more about it here. Note that you should also include a LICENSE file in your package.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","files"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-files","content":"This tells npm which files it will pack up and upload to npm. It should contain your output folder (dist by default). Your package.json and README and LICENSE will always be included, so you don't need to specify them.{\n\t\"files\": [\"dist\"]\n}To exclude unnecessary files (such as unit tests, or modules that are only imported from src/routes etc) you can add them to an .npmignore file. This will result in smaller packages that are faster to install.Read more about it here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","exports"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-exports","content":"The \"exports\" field contains the package's entry points. If you set up a new library project through npx sv create, it's set to a single export, the package root:{\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"types\": \"./dist/index.d.ts\",\n\t\t\t\"svelte\": \"./dist/index.js\"\n\t\t}\n\t}\n}This tells bundlers and tooling that your package only has one entry point, the root, and everything should be imported through that, like this: \nimport { Something } from 'your-library';The types and svelte keys are export conditions. They tell tooling what file to import when they look up the your-library import:TypeScript sees the `types` condition and looks up the type definition file. If you don't publish type definitions, omit this condition.\nSvelte-aware tooling sees the `svelte` condition and knows this is a Svelte component library. If you publish a library that does not export any Svelte components and that could also work in non-Svelte projects (for example a Svelte store library), you can replace this condition with `default`.[!NOTE] Previous versions of `@sveltejs/package` also added a `package.json` export. This is no longer part of the template because all tooling can now deal with a `package.json` not being explicitly exported.You can adjust exports to your liking and provide more entry points. For example, if instead of a src/lib/index.js file that re-exported components you wanted to expose a src/lib/Foo.svelte component directly, you could create the following export map...{\n\t\"exports\": {\n\t\t\"./Foo.svelte\": {\n\t\t\t\"types\": \"./dist/Foo.svelte.d.ts\",\n\t\t\t\"svelte\": \"./dist/Foo.svelte\"\n\t\t}\n\t}\n}...and a consumer of your library could import the component like so:import Foo from 'your-library/Foo.svelte';[!NOTE] Beware that doing this will need additional care if you provide type definitions. Read more about the caveat [here](#TypeScript)In general, each key of the exports map is the path the user will have to use to import something from your package, and the value is the path to the file that will be imported or a map of export conditions which in turn contains these file paths.Read more about exports here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","svelte"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-svelte","content":"This is a legacy field that enabled tooling to recognise Svelte component libraries. It's no longer necessary when using the svelte export condition, but for backwards compatibility with outdated tooling that doesn't yet know about export conditions it's good to keep it around. It should point towards your root entry point.{\n\t\"svelte\": \"./dist/index.js\"\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Anatomy of a package.json","sideEffects"],"href":"/docs/kit/packaging#Anatomy-of-a-package.json-sideEffects","content":"The sideEffects field in package.json is used by bundlers to determine if a module may contain code that has side effects. A module is considered to have side effects if it makes changes that are observable from other scripts outside the module when it's imported. For example, side effects include modifying global variables or the prototype of built-in JavaScript objects. Because a side effect could potentially affect the behavior of other parts of the application, these files/modules will be included in the final bundle regardless of whether their exports are used in the application. It is a best practice to avoid side effects in your code.Setting the sideEffects field in package.json can help the bundler to be more aggressive in eliminating unused exports from the final bundle, a process known as tree-shaking. This results in smaller and more efficient bundles. Different bundlers handle sideEffects in various manners. While not necessary for Vite, we recommend that libraries state that all CSS files have side effects so that your library will be compatible with webpack. This is the configuration that comes with newly created projects: \n{\n\t\"sideEffects\": [\"**/*.css\"]\n}[!NOTE] If the scripts in your library have side effects, ensure that you update the `sideEffects` field. All scripts are marked as side effect free by default in newly created projects. If a file with side effects is incorrectly marked as having no side effects, it can result in broken functionality.If your package has files with side effects, you can specify them in an array: \n{\n\t\"sideEffects\": [\n\t\t\"**/*.css\",\n\t\t\"./dist/sideEffectfulFile.js\"\n\t]\n}This will treat only the specified files as having side effects.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","TypeScript"],"href":"/docs/kit/packaging#TypeScript","content":"You should ship type definitions for your library even if you don't use TypeScript yourself so that people who do get proper intellisense when using your library. @sveltejs/package makes the process of generating types mostly opaque to you. By default, when packaging your library, type definitions are auto-generated for JavaScript, TypeScript and Svelte files. All you need to ensure is that the types condition in the exports map points to the correct files. When initialising a library project through npx sv create, this is automatically set up for the root export.If you have something else than a root export however — for example providing a your-library/foo import — you need to take additional care for providing type definitions. Unfortunately, TypeScript by default will not resolve the types condition for an export like { \"./foo\": { \"types\": \"./dist/foo.d.ts\", ... }}. Instead, it will search for a foo.d.ts relative to the root of your library (i.e. your-library/foo.d.ts instead of your-library/dist/foo.d.ts). To fix this, you have two options:The first option is to require people using your library to set the moduleResolution option in their tsconfig.json (or jsconfig.json) to bundler (available since TypeScript 5, the best and recommended option in the future), node16 or nodenext. This opts TypeScript into actually looking at the exports map and resolving the types correctly.The second option is to (ab)use the typesVersions feature from TypeScript to wire up the types. This is a field inside package.json TypeScript uses to check for different type definitions depending on the TypeScript version, and also contains a path mapping feature for that. We leverage that path mapping feature to get what we want. For the mentioned foo export above, the corresponding typesVersions looks like this:{\n\t\"exports\": {\n\t\t\"./foo\": {\n\t\t\t\"types\": \"./dist/foo.d.ts\",\n\t\t\t\"svelte\": \"./dist/foo.js\"\n\t\t}\n\t},\n\t\"typesVersions\": {\n\t\t\">4.0\": {\n\t\t\t\"foo\": [\"./dist/foo.d.ts\"]\n\t\t}\n\t}\n}>4.0 tells TypeScript to check the inner map if the used TypeScript version is greater than 4 (which should in practice always be true). The inner map tells TypeScript that the typings for your-library/foo are found within ./dist/foo.d.ts, which essentially replicates the exports condition. You also have * as a wildcard at your disposal to make many type definitions at once available without repeating yourself. Note that if you opt into typesVersions you have to declare all type imports through it, including the root import (which is defined as \"index.d.ts\": [..]).You can read more about that feature here.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Best practices"],"href":"/docs/kit/packaging#Best-practices","content":"You should avoid using SvelteKit-specific modules like $app/environment in your packages unless you intend for them to only be consumable by other SvelteKit projects. E.g. rather than using import { browser } from '$app/environment' you could use import { BROWSER } from 'esm-env' (see esm-env docs). You may also wish to pass in things like the current URL or a navigation action as a prop rather than relying directly on $app/state, $app/navigation, etc. Writing your app in this more generic fashion will also make it easier to set up tools for testing, UI demos and so on.Ensure that you add aliases via svelte.config.js (not vite.config.js or tsconfig.json), so that they are processed by svelte-package.You should think carefully about whether or not the changes you make to your package are a bug fix, a new feature, or a breaking change, and update the package version accordingly. Note that if you remove any paths from exports or any export conditions inside them from your existing library, that should be regarded as a breaking change.{\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"types\": \"./dist/index.d.ts\",\n// changing `svelte` to `default` is a breaking change:\n---\t\t\t\"svelte\": \"./dist/index.js\"---\n+++\t\t\t\"default\": \"./dist/index.js\"+++\n\t\t},\n// removing this is a breaking change:\n---\t\t\"./foo\": {\n\t\t\t\"types\": \"./dist/foo.d.ts\",\n\t\t\t\"svelte\": \"./dist/foo.js\",\n\t\t\t\"default\": \"./dist/foo.js\"\n\t\t},---\n// adding this is ok:\n+++\t\t\"./bar\": {\n\t\t\t\"types\": \"./dist/bar.d.ts\",\n\t\t\t\"svelte\": \"./dist/bar.js\",\n\t\t\t\"default\": \"./dist/bar.js\"\n\t\t}+++\n\t}\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Source maps"],"href":"/docs/kit/packaging#Source-maps","content":"You can create so-called declaration maps (d.ts.map files) by setting \"declarationMap\": true in your tsconfig.json. This will allow editors such as VS Code to go to the original .ts or .svelte file when using features like Go to Definition. This means you also need to publish your source files alongside your dist folder in a way that the relative path inside the declaration files leads to a file on disk. Assuming that you have all your library code inside src/lib as suggested by Svelte's CLI, this is as simple as adding src/lib to files in your package.json:{\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"!dist/**/*.test.*\",\n\t\t\"!dist/**/*.spec.*\",\n\t\t+++\"src/lib\",\n\t\t\"!src/lib/**/*.test.*\",\n\t\t\"!src/lib/**/*.spec.*\"+++\n\t]\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Options"],"href":"/docs/kit/packaging#Options","content":"svelte-package accepts the following options:`-w`/`--watch` — watch files in `src/lib` for changes and rebuild the package\n`-i`/`--input` — the input directory which contains all the files of the package. Defaults to `src/lib`\n`-o`/`--output` — the output directory where the processed files are written to. Your `package.json`'s `exports` should point to files inside there, and the `files` array should include that folder. Defaults to `dist`\n`-p`/`--preserve-output` — prevent deletion of the output directory before packaging. Defaults to `false`, which means that the output directory will be emptied first\n`-t`/`--types` — whether or not to create type definitions (`d.ts` files). We strongly recommend doing this as it fosters ecosystem library quality. Defaults to `true`\n`--tsconfig` - the path to a tsconfig or jsconfig. When not provided, searches for the next upper tsconfig/jsconfig in the workspace path.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Publishing"],"href":"/docs/kit/packaging#Publishing","content":"To publish the generated package:npm publish","rank":null},{"breadcrumbs":["Docs","SvelteKit","Advanced","Packaging","Caveats"],"href":"/docs/kit/packaging#Caveats","content":"All relative file imports need to be fully specified, adhering to Node's ESM algorithm. This means that for a file like src/lib/something/index.js, you must include the filename with the extension: \nimport { something } from './something+++/index.js+++';If you are using TypeScript, you need to import .ts files the same way, but using a .js file ending, not a .ts file ending. (This is a TypeScript design decision outside our control.) Setting \"moduleResolution\": \"NodeNext\" in your tsconfig.json or jsconfig.json will help you with this.All files except Svelte files (preprocessed) and TypeScript files (transpiled to JavaScript) are copied across as-is.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Auth"],"href":"/docs/kit/auth","content":"Auth refers to authentication and authorization, which are common needs when building a web application. Authentication means verifying that the user is who they say they are based on their provided credentials. Authorization means determining which actions they are allowed to take.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Auth","Sessions vs tokens"],"href":"/docs/kit/auth#Sessions-vs-tokens","content":"After the user has provided their credentials such as a username and password, we want to allow them to use the application without needing to provide their credentials again for future requests. Users are commonly authenticated on subsequent requests with either a session identifier or signed token such as a JSON Web Token (JWT).Session IDs are most commonly stored in a database. They can be immediately revoked, but require a database query to be made on each request.In contrast, JWT generally are not checked against a datastore, which means they cannot be immediately revoked. The advantage of this method is improved latency and reduced load on your datastore.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Auth","Integration points"],"href":"/docs/kit/auth#Integration-points","content":"Auth cookies can be checked inside server hooks. If a user is found matching the provided credentials, the user information can be stored in `locals`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Auth","Libraries"],"href":"/docs/kit/auth#Libraries","content":"The Svelte CLI gives the option to set up Better Auth with a new project or add it to an existing project.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Auth","Guides"],"href":"/docs/kit/auth#Guides","content":"If you'd like to implement your own auth system, the Lucia auth guide provides a reference for session-based web app auth with SvelteKit examples.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance"],"href":"/docs/kit/performance","content":"Out of the box, SvelteKit does a lot of work to make your applications as performant as possible:Code-splitting, so that only the code you need for the current page is loaded\nAsset preloading, so that 'waterfalls' (of files requesting other files) are prevented\nFile hashing, so that your assets can be cached forever\nRequest coalescing, so that data fetched from separate server `load` functions is grouped into a single HTTP request\nParallel loading, so that separate universal `load` functions fetch data simultaneously\nData inlining, so that requests made with `fetch` during server rendering can be replayed in the browser without issuing a new request\nConservative invalidation, so that `load` functions are only re-run when necessary\nPrerendering (configurable on a per-route basis, if necessary) so that pages without dynamic data can be served instantaneously\nLink preloading, so that data and code requirements for a client-side navigation are eagerly anticipatedNevertheless, we can't (yet) eliminate all sources of slowness. To eke out maximum performance, you should be mindful of the following tips.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Diagnosing issues"],"href":"/docs/kit/performance#Diagnosing-issues","content":"Google's PageSpeed Insights and (for more advanced analysis) WebPageTest are excellent ways to understand the performance characteristics of a site that is already deployed to the internet.Your browser also includes useful developer tools for analysing your site, whether deployed or running locally:Chrome - [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools), [Network](https://developer.chrome.com/docs/devtools/network), and [Performance](https://developer.chrome.com/docs/devtools/performance) devtools\nEdge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/lighthouse/lighthouse-tool), [Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/) devtools\nFirefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) devtools\nSafari - [enhancing the performance of your webpage](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html)Note that your site running locally in dev mode will exhibit different behaviour than your production app, so you should do performance testing in preview mode after building.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Diagnosing issues","Instrumenting"],"href":"/docs/kit/performance#Diagnosing-issues-Instrumenting","content":"If you see in the network tab of your browser that an API call is taking a long time and you'd like to understand why, you may consider instrumenting your backend with a tool like OpenTelemetry or Server-Timing headers.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Optimizing assets"],"href":"/docs/kit/performance#Optimizing-assets","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Optimizing assets","Images"],"href":"/docs/kit/performance#Optimizing-assets-Images","content":"Reducing the size of image files is often one of the most impactful changes you can make to a site's performance. Svelte provides the @sveltejs/enhanced-img package, detailed on the images page, for making this easier. Additionally, Lighthouse is useful for identifying the worst offenders.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Optimizing assets","Videos"],"href":"/docs/kit/performance#Optimizing-assets-Videos","content":"Video files can be very large, so extra care should be taken to ensure that they're optimized:Compress videos with tools such as [Handbrake](https://handbrake.fr/). Consider converting the videos to web-friendly formats such as `.webm` or `.mp4`.\nYou can [lazy-load videos](https://web.dev/articles/lazy-loading-video) located below the fold with `preload=\"none\"` (though note that this will slow down playback when the user _does_ initiate it).\nStrip the audio track out of muted videos using a tool like [FFmpeg](https://ffmpeg.org/).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Optimizing assets","Fonts"],"href":"/docs/kit/performance#Optimizing-assets-Fonts","content":"SvelteKit automatically preloads critical .js and .css files when the user visits a page, but it does not preload fonts by default, since this may cause unnecessary files (such as font weights that are referenced by your CSS but not actually used on the current page) to be downloaded. Having said that, preloading fonts correctly can make a big difference to how fast your site feels. In your `handle` hook, you can call resolve with a preload filter that includes your fonts.You can reduce the size of font files by subsetting your fonts.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Reducing code size"],"href":"/docs/kit/performance#Reducing-code-size","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Reducing code size","Svelte version"],"href":"/docs/kit/performance#Reducing-code-size-Svelte-version","content":"We recommend running the latest version of Svelte. Svelte 5 is smaller and faster than Svelte 4, which is smaller and faster than Svelte 3.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Reducing code size","Packages"],"href":"/docs/kit/performance#Reducing-code-size-Packages","content":"`rollup-plugin-visualizer` can be helpful for identifying which packages are contributing the most to the size of your site. You may also find opportunities to remove code by manually inspecting the build output (use build: { minify: false } in your Vite config to make the output readable, but remember to undo that before deploying your app), or via the network tab of your browser's devtools.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Reducing code size","External scripts"],"href":"/docs/kit/performance#Reducing-code-size-External-scripts","content":"Try to minimize the number of third-party scripts running in the browser. For example, instead of using JavaScript-based analytics consider using server-side implementations, such as those offered by many platforms with SvelteKit adapters including Cloudflare, Netlify, and Vercel.To run third party scripts in a web worker (which avoids blocking the main thread), use Partytown's SvelteKit integration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Reducing code size","Selective loading"],"href":"/docs/kit/performance#Reducing-code-size-Selective-loading","content":"Code imported with static import declarations will be automatically bundled with the rest of your page. If there is a piece of code you need only when some condition is met, use the dynamic import(...) form to selectively lazy-load the component.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Navigation"],"href":"/docs/kit/performance#Navigation","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Navigation","Preloading"],"href":"/docs/kit/performance#Navigation-Preloading","content":"You can speed up client-side navigations by eagerly preloading the necessary code and data, using link options. This is configured by default on the <body> element when you create a new SvelteKit app.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Navigation","Non-essential data"],"href":"/docs/kit/performance#Navigation-Non-essential-data","content":"For slow-loading data that isn't needed immediately, the object returned from your load function can contain promises rather than the data itself. For server load functions, this will cause the data to stream in after the navigation (or initial page load).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Navigation","Preventing waterfalls"],"href":"/docs/kit/performance#Navigation-Preventing-waterfalls","content":"One of the biggest performance killers is what is referred to as a waterfall, which is a series of requests that is made sequentially. This can happen on the server or in the browser, but is especially costly when dealing with data that has to travel further or across slower networks, such as a mobile user making a call to a distant server.In the browser, waterfalls can occur when your HTML kicks off request chains such as requesting JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding `modulepreload` tags or headers, but you should view the network tab in your devtools to check whether additional resources need to be preloaded.Pay special attention to this if you use [web fonts](#Optimizing-assets-Fonts) since they need to be handled manually.\nEnabling [single page app (SPA) mode](single-page-apps) will cause such waterfalls. With SPA mode, an empty page is generated, which fetches JavaScript, which ultimately loads and renders the page. This results in extra network round trips before a single pixel can be displayed.Waterfalls can also occur on calls to the backend whether made from the browser or server. E.g. if a universal load function makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses that response to fetch the details for each item, the browser will end up making multiple sequential requests. This is deadly for performance, especially for users that are physically located far from your backend.Avoid this issue by using [server `load` functions](load#Universal-vs-server) to make requests to backend services that are dependencies from the server rather than from the browser. Note, however, that server `load` functions are also not immune to waterfalls (though they are much less costly since they rarely involve round trips with high latency). For example, if you query a database to get the current user and then use that data to make a second query for a list of saved items, it will typically be more performant to issue a single query with a database join.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Hosting"],"href":"/docs/kit/performance#Hosting","content":"Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the edge, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support configuring deployment on a per-route basis. You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many SvelteKit adapters will do this automatically.Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Performance","Further reading"],"href":"/docs/kit/performance#Further-reading","content":"For the most part, building a performant SvelteKit app is the same as building any performant web app. You should be able to apply information from general performance resources such as Core Web Vitals to any web experience you build.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Icons"],"href":"/docs/kit/icons","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Icons","CSS"],"href":"/docs/kit/icons#CSS","content":"A great way to use icons is to define them purely via CSS. Iconify offers support for many popular icon sets that can be included via CSS. This method can also be used with popular CSS frameworks by leveraging the Iconify Tailwind CSS plugin or UnoCSS plugin. As opposed to libraries based on Svelte components, it doesn't require each icon to be imported into your .svelte file.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Icons","Svelte"],"href":"/docs/kit/icons#Svelte","content":"There are many icon libraries for Svelte. When choosing an icon library, it is recommended to avoid those that provide a .svelte file per icon, as these libraries can have thousands of .svelte files which really slow down Vite's dependency optimization. This can become especially pathological if the icons are imported both via an umbrella import and subpath import as described in the `vite-plugin-svelte` FAQ.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images"],"href":"/docs/kit/images","content":"Images can have a big impact on your app's performance. For best results, you should optimize them by doing the following:generate optimal formats like `.avif` and `.webp`\ncreate different sizes for different screens\nensure that assets can be cached effectivelyDoing this manually is tedious. There are a variety of techniques you can use, depending on your needs and preferences.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","Vite's built-in handling"],"href":"/docs/kit/images#Vite's-built-in-handling","content":"Vite will automatically process imported assets for improved performance. This includes assets referenced via the CSS url() function. Hashes will be added to the filenames so that they can be cached, and assets smaller than assetsInlineLimit will be inlined. Vite's asset handling is most often used for images, but is also useful for video, audio, etc.<script>\n\timport logo from '$lib/assets/logo.png';\n</script>\n\n<img alt=\"The project logo\" src={logo} />","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img"],"href":"/docs/kit/images#sveltejs-enhanced-img","content":"@sveltejs/enhanced-img is a plugin offered on top of Vite's built-in asset handling. It provides plug and play image processing that serves smaller file formats like avif or webp, automatically sets the intrinsic width and height of the image to avoid layout shift, creates images of multiple sizes for various devices, and strips EXIF data for privacy. It will work in any Vite-based project including, but not limited to, SvelteKit projects.[!NOTE] As a build plugin, `@sveltejs/enhanced-img` can only optimize files located on your machine during the build process. If you have an image located elsewhere (such as a path served from your database, CMS, or backend), please read about [loading images dynamically from a CDN](#Loading-images-dynamically-from-a-CDN).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","Setup"],"href":"/docs/kit/images#sveltejs-enhanced-img-Setup","content":"Install:npm i -D @sveltejs/enhanced-imgAdjust vite.config.js:import { sveltekit } from '@sveltejs/kit/vite';\n+++import { enhancedImages } from '@sveltejs/enhanced-img';+++\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n\tplugins: [\n\t\t+++enhancedImages(), // must come before the SvelteKit plugin+++\n\t\tsveltekit()\n\t]\n});Building will take longer on the first build due to the computational expense of transforming images. However, the build output will be cached in ./node_modules/.cache/imagetools so that subsequent builds will be fast.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","Basic usage"],"href":"/docs/kit/images#sveltejs-enhanced-img-Basic-usage","content":"Use in your .svelte components by using <enhanced:img> rather than <img> and referencing the image file with a Vite asset import path:<enhanced:img src=\"./path/to/your/image.jpg\" alt=\"An alt text\" />At build time, your <enhanced:img> tag will be replaced with an <img> wrapped by a <picture> providing multiple image types and sizes. It's only possible to downscale images without losing quality, which means that you should provide the highest resolution image that you need — smaller versions will be generated for the various device types that may request an image.You should provide your image at 2x resolution for HiDPI displays (a.k.a. retina displays). <enhanced:img> will automatically take care of serving smaller versions to smaller devices.[!NOTE] if you wish to use a [tag name CSS selector](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Basic_selectors#type_selectors) in your `<style>` block you will need to write `enhanced\\:img` to escape the colon in the tag name.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","Dynamically choosing an image"],"href":"/docs/kit/images#sveltejs-enhanced-img-Dynamically-choosing-an-image","content":"You can also manually import an image asset and pass it to an <enhanced:img>. This is useful when you have a collection of static images and would like to dynamically choose one or iterate over them. In this case you will need to update both the import statement and <img> element as shown below to indicate you'd like process them.<script>\n\timport MyImage from './path/to/your/image.jpg?enhanced';\n</script>\n\n<enhanced:img src={MyImage} alt=\"some alt text\" />You can also use Vite's `import.meta.glob`. Note that you will have to specify enhanced via a custom query:<script>\n\tconst imageModules = import.meta.glob(\n\t\t'/path/to/assets/*.{avif,AVIF,gif,GIF,heif,HEIF,jpeg,JPEG,jpg,JPG,png,PNG,tiff,TIFF,webp,WEBP}',\n\t\t{\n\t\t\teager: true,\n\t\t\tquery: {\n\t\t\t\tenhanced: true\n\t\t\t}\n\t\t}\n\t)\n</script>\n\n{#each Object.entries(imageModules) as [_path, module]}\n\t<enhanced:img src={module.default} alt=\"some alt text\" />\n{/each}[!NOTE] svg images are currently only supported statically","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","Intrinsic Dimensions"],"href":"/docs/kit/images#sveltejs-enhanced-img-Intrinsic-Dimensions","content":"width and height are optional as they can be inferred from the source image and will be automatically added when the <enhanced:img> tag is preprocessed. With these attributes, the browser can reserve the correct amount of space, preventing layout shift. If you'd like to use a different width and height you can style the image with CSS. Because the preprocessor adds a width and height for you, if you'd like one of the dimensions to be automatically calculated then you will need to specify that:<style>\n\t.hero-image img {\n\t\twidth: var(--size);\n\t\theight: auto;\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","srcset` and sizes`"],"href":"/docs/kit/images#sveltejs-enhanced-img-srcset-and-sizes","content":"If you have a large image, such as a hero image taking the width of the design, you should specify sizes so that smaller versions are requested on smaller devices. E.g. if you have a 1280px image you may want to specify something like:<enhanced:img src=\"./image.png\" sizes=\"min(1280px, 100vw)\"/>If sizes is specified, <enhanced:img> will generate small images for smaller devices and populate the srcset attribute.The smallest picture generated automatically will have a width of 540px. If you'd like smaller images or would otherwise like to specify custom widths, you can do that with the w query parameter:<enhanced:img\n\tsrc=\"./image.png?w=1280;640;400\"\n\tsizes=\"(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px\"\n/>If sizes is not provided, then a HiDPI/Retina image and a standard resolution image will be generated. The image you provide should be 2x the resolution you wish to display so that the browser can display that image on devices with a high device pixel ratio.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","@sveltejs/enhanced-img","Per-image transforms"],"href":"/docs/kit/images#sveltejs-enhanced-img-Per-image-transforms","content":"By default, enhanced images will be transformed to more efficient formats. However, you may wish to apply other transforms such as a blur, quality, flatten, or rotate operation. You can run per-image transforms by appending a query string:<enhanced:img src=\"./path/to/your/image.jpg?blur=15\" alt=\"An alt text\" />See the imagetools repo for the full list of directives.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","Loading images dynamically from a CDN"],"href":"/docs/kit/images#Loading-images-dynamically-from-a-CDN","content":"In some cases, the images may not be accessible at build time — e.g. they may live inside a content management system or elsewhere.Using a content delivery network (CDN) can allow you to optimize these images dynamically, and provides more flexibility with regards to sizes, but it may involve some setup overhead and usage costs. Depending on caching strategy, the browser may not be able to use a cached copy of the asset until a 304 response is received from the CDN. Building HTML to target CDNs allows using an <img> tag since the CDN can serve the appropriate format based on the User-Agent header, whereas build-time optimizations must produce <picture> tags with multiple sources. Finally, some CDNs may generate images lazily, which could have a negative performance impact for sites with low traffic and frequently changing images.CDNs can generally be used without any need for a library. However, there are a number of libraries with Svelte support that make it easier. `@unpic/svelte` is a CDN-agnostic library with support for a large number of providers. You may also find that specific CDNs like Cloudinary have Svelte support. Finally, some content management systems (CMS) which support Svelte (such as Contentful, Storyblok, and Contentstack) have built-in support for image handling.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Images","Best practices"],"href":"/docs/kit/images#Best-practices","content":"For each image type, use the appropriate solution from those discussed above. You can mix and match all three solutions in one project. For example, you may use Vite's built-in handling to provide images for `<meta>` tags, display images on your homepage with `@sveltejs/enhanced-img`, and display user-submitted content with a dynamic approach.\nConsider serving all images via CDN regardless of the image optimization types you use. CDNs reduce latency by distributing copies of static assets globally.\nYour original images should have a good quality/resolution and should have 2x the width it will be displayed at to serve HiDPI devices. Image processing can size images down to save bandwidth when serving smaller screens, but it would be a waste of bandwidth to invent pixels to size images up.\nFor images which are much larger than the width of a mobile device (roughly 400px), such as a hero image taking the width of the page design, specify `sizes` so that smaller images can be served on smaller devices.\nFor important images, such as the [largest contentful paint (LCP)](https://web.dev/articles/lcp) image, set `fetchpriority=\"high\"` and avoid `loading=\"lazy\"` to prioritize loading as early as possible.\nGive the image a container or styling so that it is constrained and does not jump around while the page is loading affecting your [cumulative layout shift (CLS)](https://web.dev/articles/cls). `width` and `height` help the browser to reserve space while the image is still loading, so `@sveltejs/enhanced-img` will add a `width` and `height` for you.\nAlways provide a good `alt` text. The Svelte compiler will warn you if you don't do this.\nDo not use `em` or `rem` in `sizes` and change the default size of these measures. When used in `sizes` or `@media` queries, `em` and `rem` are both defined to mean the user's default `font-size`. For a `sizes` declaration like `sizes=\"(min-width: 768px) min(100vw, 108rem), 64rem\"`, the actual `em` or `rem` that controls how the image is laid out on the page can be different if changed by CSS. For example, do not do something like `html { font-size: 62.5%; }` as the slot reserved by the browser preloader will now end up being larger than the actual slot of the CSS object model once it has been created.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Accessibility"],"href":"/docs/kit/accessibility","content":"SvelteKit strives to provide an accessible platform for your app by default. Svelte's compile-time accessibility checks will also apply to any SvelteKit application you build.Here's how SvelteKit's built-in accessibility features work and what you need to do to help these features to work as well as possible. Keep in mind that while SvelteKit provides an accessible foundation, you are still responsible for making sure your application code is accessible. If you're new to accessibility, see the \"further reading\" section of this guide for additional resources.We recognize that accessibility can be hard to get right. If you want to suggest improvements to how SvelteKit handles accessibility, please open a GitHub issue.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Accessibility","Route announcements"],"href":"/docs/kit/accessibility#Route-announcements","content":"In traditional server-rendered applications, every navigation (e.g. clicking on an <a> tag) triggers a full page reload. When this happens, screen readers and other assistive technology will read out the new page's title so that users understand that the page has changed.Since navigation between pages in SvelteKit happens without reloading the page (known as client-side routing), SvelteKit injects a live region onto the page that will read out the new page name after each navigation. This determines the page name to announce by inspecting the <title> element.Because of this behavior, every page in your app should have a unique, descriptive title. In SvelteKit, you can do this by placing a <svelte:head> element on each page:<!--- file: src/routes/+page.svelte --->\n<svelte:head>\n\t<title>Todo List</title>\n</svelte:head>This will allow screen readers and other assistive technology to identify the new page after a navigation occurs. Providing a descriptive title is also important for SEO.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Accessibility","Focus management"],"href":"/docs/kit/accessibility#Focus-management","content":"In traditional server-rendered applications, every navigation will reset focus to the top of the page. This ensures that people browsing the web with a keyboard or screen reader will start interacting with the page from the beginning.To simulate this behavior during client-side routing, SvelteKit focuses the <body> element after each navigation and enhanced form submission. There is one exception - if an element with the `autofocus` attribute is present, SvelteKit will focus that element instead. Make sure to consider the implications for assistive technology when using that attribute.If you want to customize SvelteKit's focus management, you can use the afterNavigate hook:import { afterNavigate } from '$app/navigation';\n\nafterNavigate(() => {\n\t/** @type {HTMLElement | null} */\n\tconst to_focus = document.querySelector('.focus-me');\n\tto_focus?.focus();\n});You can also programmatically navigate to a different page using the `goto` function. By default, this will have the same client-side routing behavior as clicking on a link. However, goto also accepts a keepFocus option that will preserve the currently-focused element instead of resetting focus. If you enable this option, make sure the currently-focused element still exists on the page after navigation. If the element no longer exists, the user's focus will be lost, making for a confusing experience for assistive technology users.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Accessibility","The \"lang\" attribute"],"href":"/docs/kit/accessibility#The-lang-attribute","content":"By default, SvelteKit's page template sets the default language of the document to English. If your content is not in English, you should update the <html> element in src/app.html to have the correct `lang` attribute. This will ensure that any assistive technology reading the document uses the correct pronunciation. For example, if your content is in German, you should update app.html to the following: \n<html lang=\"de\">If your content is available in multiple languages, you should set the lang attribute based on the language of the current page. You can do this with SvelteKit's handle hook: \n<html lang=\"%lang%\">/** @type {import('@sveltejs/kit').Handle} */\nexport function handle({ event, resolve }) {\n\treturn resolve(event, {\n\t\ttransformPageChunk: ({ html }) => html.replace('%lang%', get_lang(event))\n\t});\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","Accessibility","Further reading"],"href":"/docs/kit/accessibility#Further-reading","content":"For the most part, building an accessible SvelteKit app is the same as building an accessible web app. You should be able to apply information from the following general accessibility resources to any web experience you build:[MDN Web Docs: Accessibility](https://developer.mozilla.org/en-US/docs/Learn/Accessibility)\n[The A11y Project](https://www.a11yproject.com/)\n[How to Meet WCAG (Quick Reference)](https://www.w3.org/WAI/WCAG21/quickref/)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO"],"href":"/docs/kit/seo","content":"The most important aspect of SEO is to create high-quality content that is widely linked to from around the web. However, there are a few technical considerations for building sites that rank well.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Out of the box"],"href":"/docs/kit/seo#Out-of-the-box","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Out of the box","SSR"],"href":"/docs/kit/seo#Out-of-the-box-SSR","content":"While search engines have got better in recent years at indexing content that was rendered with client-side JavaScript, server-side rendered content is indexed more frequently and reliably. SvelteKit employs SSR by default, and while you can disable it in `handle`, you should leave it on unless you have a good reason not to.[!NOTE] SvelteKit's rendering is highly configurable and you can implement [dynamic rendering](https://developers.google.com/search/docs/advanced/javascript/dynamic-rendering) if necessary. It's not generally recommended, since SSR has other benefits beyond SEO.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Out of the box","Performance"],"href":"/docs/kit/seo#Out-of-the-box-Performance","content":"Signals such as Core Web Vitals impact search engine ranking. Because Svelte and SvelteKit introduce minimal overhead, they make it easier to build high performance sites. You can test your site's performance using Google's PageSpeed Insights or Lighthouse. With just a few key actions like using SvelteKit's default hybrid rendering mode and optimizing your images, you can greatly improve your site's speed. Read the performance page for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Out of the box","Normalized URLs"],"href":"/docs/kit/seo#Out-of-the-box-Normalized-URLs","content":"SvelteKit redirects pathnames with trailing slashes to ones without (or vice versa depending on your configuration), as duplicate URLs are bad for SEO.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Manual setup"],"href":"/docs/kit/seo#Manual-setup","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Manual setup","&lt;title&gt; and &lt;meta&gt;"],"href":"/docs/kit/seo#Manual-setup-title-and-meta","content":"Every page should have well-written and unique <title> and <meta name=\"description\"> elements inside a `<svelte:head>`. Guidance on how to write descriptive titles and descriptions, along with other suggestions on making content understandable by search engines, can be found on Google's Lighthouse SEO audits documentation.[!NOTE] A common pattern is to return SEO-related `data` from page [`load`](load) functions, then use it (as [`page.data`]($app-state)) in a `<svelte:head>` in your root [layout](routing#layout).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Manual setup","Sitemaps"],"href":"/docs/kit/seo#Manual-setup-Sitemaps","content":"Sitemaps help search engines prioritize pages within your site, particularly when you have a large amount of content. You can create a sitemap dynamically using an endpoint: \nexport async function GET() {\n\treturn new Response(\n\t\t`\n\t\t<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\t\t<urlset\n\t\t\txmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n\t\t\txmlns:xhtml=\"http://www.w3.org/1999/xhtml\"\n\t\t\txmlns:mobile=\"http://www.google.com/schemas/sitemap-mobile/1.0\"\n\t\t\txmlns:news=\"http://www.google.com/schemas/sitemap-news/0.9\"\n\t\t\txmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\"\n\t\t\txmlns:video=\"http://www.google.com/schemas/sitemap-video/1.1\"\n\t\t>\n\t\t\t<!-- <url> elements go here -->\n\t\t</urlset>`.trim(),\n\t\t{\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/xml'\n\t\t\t}\n\t\t}\n\t);\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Best practices","SEO","Manual setup","AMP"],"href":"/docs/kit/seo#Manual-setup-AMP","content":"An unfortunate reality of modern web development is that it is sometimes necessary to create an Accelerated Mobile Pages (AMP) version of your site. In SvelteKit this can be done by setting the `inlineStyleThreshold` option... \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\t// since <link rel=\"stylesheet\"> isn't\n\t\t// allowed, inline all styles\n\t\tinlineStyleThreshold: Infinity\n\t}\n};\n\nexport default config;...disabling csr in your root +layout.js/+layout.server.js... \nexport const csr = false;...adding amp to your app.html<html amp>\n......and transforming the HTML using transformPageChunk along with transform imported from @sveltejs/amp: \nimport * as amp from '@sveltejs/amp';\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tlet buffer = '';\n\treturn await resolve(event, {\n\t\ttransformPageChunk: ({ html, done }) => {\n\t\t\tbuffer += html;\n\t\t\tif (done) return amp.transform(buffer);\n\t\t}\n\t});\n}To prevent shipping any unused CSS as a result of transforming the page to amp, we can use `dropcss`: \n \nimport * as amp from '@sveltejs/amp';\nimport dropcss from 'dropcss';\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tlet buffer = '';\n\n\treturn await resolve(event, {\n\t\ttransformPageChunk: ({ html, done }) => {\n\t\t\tbuffer += html;\n\n\t\t\tif (done) {\n\t\t\t\tlet css = '';\n\t\t\t\tconst markup = amp\n\t\t\t\t\t.transform(buffer)\n\t\t\t\t\t.replace('⚡', 'amp') // dropcss can't handle this character\n\t\t\t\t\t.replace(/<style amp-custom([^>]*?)>([^]+?)<\\/style>/, (match, attributes, contents) => {\n\t\t\t\t\t\tcss = contents;\n\t\t\t\t\t\treturn `<style amp-custom${attributes}></style>`;\n\t\t\t\t\t});\n\n\t\t\t\tcss = dropcss({ css, html: markup }).css;\n\t\t\t\treturn markup.replace('</style>', `${css}</style>`);\n\t\t\t}\n\t\t}\n\t});\n}\n[!NOTE] It's a good idea to use the `handle` hook to validate the transformed HTML using `amphtml-validator`, but only if you're prerendering pages since it's very slow.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions"],"href":"/docs/kit/faq","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","Other resources"],"href":"/docs/kit/faq#Other-resources","content":"Please see the Svelte FAQ and `vite-plugin-svelte` FAQ as well for the answers to questions deriving from those libraries.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","What can I make with SvelteKit?"],"href":"/docs/kit/faq#What-can-I-make-with-SvelteKit","content":"See the documentation regarding project types for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I include details from package.json in my application?"],"href":"/docs/kit/faq#How-do-I-include-details-from-package.json-in-my-application","content":"If you'd like to include your application's version number or other information from package.json in your application, you can load JSON like so: \n \nimport pkg from './package.json' with { type: 'json' };","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I fix the error I'm getting trying to include a package?"],"href":"/docs/kit/faq#How-do-I-fix-the-error-I'm-getting-trying-to-include-a-package","content":"Most issues related to including a library are due to incorrect packaging. You can check if a library's packaging is compatible with Node.js by entering it into the publint website.Here are a few things to keep in mind when checking if a library is packaged correctly:`exports` takes precedence over the other entry point fields such as `main` and `module`. Adding an `exports` field may not be backwards-compatible as it prevents deep imports.\nESM files should end with `.mjs` unless `\"type\": \"module\"` is set in which any case CommonJS files should end with `.cjs`.\n`main` should be defined if `exports` is not. It should be either a CommonJS or ESM file and adhere to the previous bullet. If a `module` field is defined, it should refer to an ESM file.\nSvelte components should be distributed as uncompiled `.svelte` files with any JS in the package written as ESM only. Custom script and style languages, like TypeScript and SCSS, should be preprocessed as vanilla JS and CSS respectively. We recommend using [`svelte-package`](./packaging) for packaging Svelte libraries, which will do this for you.Libraries work best in the browser with Vite when they distribute an ESM version, especially if they are dependencies of a Svelte component library. You may wish to suggest to library authors that they provide an ESM version. However, CommonJS (CJS) dependencies should work as well since, by default, `vite-plugin-svelte` will ask Vite to pre-bundle them using esbuild to convert them to ESM.If you are still encountering issues we recommend searching both the Vite issue tracker and the issue tracker of the library in question. Sometimes issues can be worked around by fiddling with the `optimizeDeps` or `ssr` config values though we recommend this as only a short-term workaround in favor of fixing the library in question.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use the view transitions API?"],"href":"/docs/kit/faq#How-do-I-use-the-view-transitions-API","content":"While SvelteKit does not have any specific integration with view transitions, you can call document.startViewTransition in `onNavigate` to trigger a view transition on every client-side navigation. \nimport { onNavigate } from '$app/navigation';\n\nonNavigate((navigation) => {\n\tif (!document.startViewTransition) return;\n\n\treturn new Promise((resolve) => {\n\t\tdocument.startViewTransition(async () => {\n\t\t\tresolve();\n\t\t\tawait navigation.complete;\n\t\t});\n\t});\n});For more, see \"Unlocking view transitions\" on the Svelte blog.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I set up a database?"],"href":"/docs/kit/faq#How-do-I-set-up-a-database","content":"Put the code to query your database in a server route - don't query the database in .svelte files. You can create a db.js or similar that sets up a connection immediately and makes the client accessible throughout the app as a singleton. You can execute any one-time setup code in hooks.server.js and import your database helpers into any endpoint that needs them.You can use the Svelte CLI to automatically set up database integrations.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use a client-side library accessing `document` or `window`?"],"href":"/docs/kit/faq#How-do-I-use-a-client-side-library-accessing-document-or-window","content":"If you need access to the document or window variables or otherwise need code to run only on the client-side you can wrap it in a browser check:import { browser } from '$app/environment';\n\nif (browser) {\n\t// client-only code here\n}You can also run code in onMount if you'd like to run it after the component has been first rendered to the DOM:import { onMount } from 'svelte';\n\nonMount(async () => {\n\tconst { method } = await import('some-browser-only-library');\n\tmethod('hello world');\n});If the library you'd like to use is side-effect free you can also statically import it and it will be tree-shaken out in the server-side build where onMount will be automatically replaced with a no-op:import { onMount } from 'svelte';\nimport { method } from 'some-browser-only-library';\n\nonMount(() => {\n\tmethod('hello world');\n});Finally, you may also consider using an {#await} block:<!--- file: index.svelte --->\n<script>\n\timport { browser } from '$app/environment';\n\n\tconst ComponentConstructor = browser ?\n\t\timport('some-browser-only-library').then((module) => module.Component) :\n\t\tnew Promise(() => {});\n</script>\n\n{#await ComponentConstructor}\n\t<p>Loading...</p>\n{:then component}\n\t<svelte:component this={component} />\n{:catch error}\n\t<p>Something went wrong: {error.message}</p>\n{/await}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use a different backend API server?"],"href":"/docs/kit/faq#How-do-I-use-a-different-backend-API-server","content":"You can use `event.fetch` to request data from an external API server, but be aware that you would need to deal with CORS, which will result in complications such as generally requiring requests to be preflighted resulting in higher latency. Requests to a separate subdomain may also increase latency due to an additional DNS lookup, TLS setup, etc. If you wish to use this method, you may find `handleFetch` helpful.Another approach is to set up a proxy to bypass CORS headaches. In production, you would rewrite a path like /api to the API server; for local development, use Vite's `server.proxy` option.How to set up rewrites in production will depend on your deployment platform. If rewrites aren't an option, you could alternatively add an API route: \n/** @type {import('./$types').RequestHandler} */\nexport function GET({ params, url }) {\n\treturn fetch(`https://example.com/${params.path + url.search}`);\n}(Note that you may also need to proxy POST/PATCH etc requests, and forward request.headers, depending on your needs.)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use middleware?"],"href":"/docs/kit/faq#How-do-I-use-middleware","content":"adapter-node builds a middleware that you can use with your own server for production mode. In dev, you can add middleware to Vite by using a Vite plugin. For example: \nimport { sveltekit } from '@sveltejs/kit/vite';\n\n/** @type {import('vite').Plugin} */\nconst myPlugin = {\n\tname: 'log-request-middleware',\n\tconfigureServer(server) {\n\t\tserver.middlewares.use((req, res, next) => {\n\t\t\tconsole.log(`Got request ${req.url}`);\n\t\t\tnext();\n\t\t});\n\t}\n};\n\n/** @type {import('vite').UserConfig} */\nconst config = {\n\tplugins: [myPlugin, sveltekit()]\n};\n\nexport default config;See Vite's `configureServer` docs for more details including how to control ordering.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use Yarn?"],"href":"/docs/kit/faq#How-do-I-use-Yarn","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use Yarn?","Does it work with Yarn 2?"],"href":"/docs/kit/faq#How-do-I-use-Yarn-Does-it-work-with-Yarn-2","content":"Sort of. The Plug'n'Play feature, aka 'pnp', is broken (it deviates from the Node module resolution algorithm, and doesn't yet work with native JavaScript modules which SvelteKit — along with an increasing number of packages — uses). You can use nodeLinker: 'node-modules' in your `.yarnrc.yml` file to disable pnp, but it's probably easier to just use npm or pnpm, which is similarly fast and efficient but without the compatibility headaches.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Frequently asked questions","How do I use Yarn?","How do I use with Yarn 3?"],"href":"/docs/kit/faq#How-do-I-use-Yarn-How-do-I-use-with-Yarn-3","content":"Currently ESM Support within the latest Yarn (version 3) is considered experimental.The below seems to work although your results may vary. First create a new application:yarn create svelte myapp\ncd myappAnd enable Yarn Berry:yarn set version berry\nyarn installOne of the more interesting features of Yarn Berry is the ability to have a single global cache for packages, instead of having multiple copies for each project on the disk. However, setting enableGlobalCache to true causes building to fail, so it is recommended to add the following to the .yarnrc.yml file:nodeLinker: node-modulesThis will cause packages to be downloaded into a local node_modules directory but avoids the above problem and is your best bet for using version 3 of Yarn at this point in time.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations"],"href":"/docs/kit/integrations","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","vitePreprocess"],"href":"/docs/kit/integrations#vitePreprocess","content":"`vitePreprocess` preprocesses <style> and <script> tags in .svelte files.// svelte.config.js\nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tpreprocess: [\n\t\tvitePreprocess({\n\t\t\tstyle: true,      // default value\n\t\t\tscript: false     // default value\n\t\t})\n\t]\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","vitePreprocess","style"],"href":"/docs/kit/integrations#vitePreprocess-style","content":"Use vitePreprocess() to enable CSS preprocessors in <style> tags: PostCSS, SCSS, Less, Stylus, and SugarSS.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","vitePreprocess","script"],"href":"/docs/kit/integrations#vitePreprocess-script","content":"Use vitePreprocess({ script: true }) if:your project is before Svelte 5\nyou are using advanced TypeScript features that emit code _(check [`vitePreprocess`](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md) documentation)_[!NOTE]\nTypeScript is supported natively in Svelte 5, so if you are using Svelte 5 and you don't need to use advanced TypeScript features that emit code, you probably don't need to use `vitePreprocess`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Add-ons"],"href":"/docs/kit/integrations#Add-ons","content":"Run `npx sv add` to set up many different complex integrations with a single command including:prettier (formatting)\neslint (linting)\nvitest (unit testing)\nplaywright (e2e testing)\nbetter-auth (auth)\ntailwind (CSS)\ndrizzle (DB)\nparaglide (i18n)\nmdsvex (markdown)\nstorybook (frontend workshop)\nadapters (hosting)\nmcp (LLM tooling)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Packages"],"href":"/docs/kit/integrations#Packages","content":"Check out the packages page for a curated set of high quality Svelte packages. You can also see sveltesociety.dev for additional libraries, templates, and resources.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Additional integrations"],"href":"/docs/kit/integrations#Additional-integrations","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Additional integrations","svelte-preprocess"],"href":"/docs/kit/integrations#Additional-integrations-svelte-preprocess","content":"svelte-preprocess has some additional functionality not found in vitePreprocess such as support for Pug, Babel, and global styles. However, vitePreprocess may be faster and require less configuration, so it is used by default. Note that CoffeeScript is not supported by SvelteKit.You will need to install svelte-preprocess with npm i -D svelte-preprocess and add it to your `svelte.config.js`. After that, you will often need to install the corresponding library such as npm i -D sass or npm i -D less.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Vite plugins"],"href":"/docs/kit/integrations#Vite-plugins","content":"Since SvelteKit projects are built with Vite, you can use Vite plugins to enhance your project. See a list of available plugins at `vitejs/awesome-vite`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Integrations","Integration FAQs"],"href":"/docs/kit/integrations#Integration-FAQs","content":"The SvelteKit FAQ answers many questions about how to do X with SvelteKit, which may be helpful if you still have questions.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging"],"href":"/docs/kit/debugging","content":"In addition to the `@debug` tag, you can also debug Svelte and SvelteKit projects using breakpoints within various tools and development environments. This includes both frontend and backend code.The following guides assume your JavaScript runtime environment is Node.js.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging","Visual Studio Code"],"href":"/docs/kit/debugging#Visual-Studio-Code","content":"With the built-in debug terminal, you can set up breakpoints in source files within VSCode.Open the command palette: `CMD/Ctrl` + `Shift` + `P`.\nFind and launch \"Debug: JavaScript Debug Terminal\".\nStart your project using the debug terminal. For example: `npm run dev`.\nSet some breakpoints in your client or server-side source code.\nTrigger the breakpoint.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging","Visual Studio Code","Launch via debug pane"],"href":"/docs/kit/debugging#Visual-Studio-Code-Launch-via-debug-pane","content":"You may alternatively set up a .vscode/launch.json in your project. To set one up automatically:Go to the \"Run and Debug\" pane.\nIn the \"Run\" select menu, choose \"Node.js...\".\nSelect the \"run script\" that corresponds to your project, such as \"Run script: dev\".\nPress the \"Start debugging\" play button, or hit `F5` to begin breakpoint debugging.Here's an example launch.json:{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"command\": \"npm run dev\",\n\t\t\t\"name\": \"Run development server\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"type\": \"node-terminal\"\n\t\t}\n\t]\n}Further reading: https://code.visualstudio.com/docs/editor/debugging.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging","Other Editors"],"href":"/docs/kit/debugging#Other-Editors","content":"If you use a different editor, these community guides might be useful for you:[WebStorm Svelte: Debug Your Application](https://www.jetbrains.com/help/webstorm/svelte.html#ws_svelte_debug)\n[Debugging JavaScript Frameworks in Neovim](https://theosteiner.de/debugging-javascript-frameworks-in-neovim)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging","Google Chrome and Microsoft Edge Developer Tools"],"href":"/docs/kit/debugging#Google-Chrome-and-Microsoft-Edge-Developer-Tools","content":"It's possible to debug Node.js applications using a browser-based debugger.[!NOTE] Note this only works with debugging client-side SvelteKit source maps.Run the `--inspect` flag when starting the Vite server with Node.js. For instance: `NODE_OPTIONS=\"--inspect\" npm run dev`\nOpen your site in a new tab. Typically at `localhost:5173`.\nOpen your browser's dev tools, and click on the \"Open dedicated DevTools for Node.js\" icon near the top-left. It should display the Node.js logo.\nSet up breakpoints and debug your application.You may alternatively open the debugger devtools by navigating to chrome://inspect in Google Chrome, or edge://inspect in Microsoft Edge.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Breakpoint Debugging","References"],"href":"/docs/kit/debugging#References","content":"[Debugging Node.js](https://nodejs.org/en/learn/getting-started/debugging)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2"],"href":"/docs/kit/migrating-to-sveltekit-2","content":"Upgrading from SvelteKit version 1 to version 2 should be mostly seamless. There are a few breaking changes to note, which are listed here. You can use npx sv migrate sveltekit-2 to migrate some of these changes automatically.We highly recommend upgrading to the most recent 1.x version before upgrading to 2.0, so that you can take advantage of targeted deprecation warnings. We also recommend updating to Svelte 4 first: Later versions of SvelteKit 1.x support it, and SvelteKit 2.0 requires it.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","redirect` and error` are no longer thrown by you"],"href":"/docs/kit/migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you","content":"Previously, you had to throw the values returned from error(...) and redirect(...) yourself. In SvelteKit 2 this is no longer the case — calling the functions is sufficient.import { error } from '@sveltejs/kit'\n\n// ...\n---throw error(500, 'something went wrong');---\n+++error(500, 'something went wrong');+++svelte-migrate will do these changes automatically for you.If the error or redirect is thrown inside a try {...} block (hint: don't do this!), you can distinguish them from unexpected errors using `isHttpError` and `isRedirect` imported from @sveltejs/kit.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","path is required when setting cookies"],"href":"/docs/kit/migrating-to-sveltekit-2#path-is-required-when-setting-cookies","content":"When receiving a Set-Cookie header that doesn't specify a path, browsers will set the cookie path to the parent of the resource in question. This behaviour isn't particularly helpful or intuitive, and frequently results in bugs because the developer expected the cookie to apply to the domain as a whole.As of SvelteKit 2.0, you need to set a path when calling cookies.set(...), cookies.delete(...) or cookies.serialize(...) so that there's no ambiguity. Most of the time, you probably want to use path: '/', but you can set it to whatever you like, including relative paths — '' means 'the current path', '.' means 'the current directory'./** @type {import('./$types').PageServerLoad} */\nexport function load({ cookies }) {\n\tcookies.set(name, value, +++{ path: '/' }+++);\n\treturn { response }\n}svelte-migrate will add comments highlighting the locations that need to be adjusted.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Top-level promises are no longer awaited"],"href":"/docs/kit/migrating-to-sveltekit-2#Top-level-promises-are-no-longer-awaited","content":"In SvelteKit version 1, if the top-level properties of the object returned from a load function were promises, they were automatically awaited. With the introduction of streaming this behavior became a bit awkward as it forces you to nest your streamed data one level deep.As of version 2, SvelteKit no longer differentiates between top-level and non-top-level promises. To get back the blocking behavior, use await (with Promise.all to prevent waterfalls, where appropriate):// If you have a single promise\n/** @type {import('./$types').PageServerLoad} */\nexport +++async+++ function load({ fetch }) {\n\tconst response = +++await+++ fetch(url).then(r => r.json());\n\treturn { response }\n}// If you have multiple promises\n/** @type {import('./$types').PageServerLoad} */\nexport +++async+++ function load({ fetch }) {\n---\tconst a = fetch(url1).then(r => r.json());---\n---\tconst b = fetch(url2).then(r => r.json());---\n+++\tconst [a, b] = await Promise.all([\n\t\tfetch(url1).then(r => r.json()),\n\t\tfetch(url2).then(r => r.json()),\n\t]);+++\n\treturn { a, b };\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","goto(...) changes"],"href":"/docs/kit/migrating-to-sveltekit-2#goto()-changes","content":"goto(...) no longer accepts external URLs. To navigate to an external URL, use window.location.href = url. The state object now determines $page.state and must adhere to the App.PageState interface, if declared. See shallow routing for more details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","paths are now relative by default"],"href":"/docs/kit/migrating-to-sveltekit-2#paths-are-now-relative-by-default","content":"In SvelteKit 1, %sveltekit.assets% in your app.html was replaced with a relative path by default (i.e. . or .. or ../.. etc, depending on the path being rendered) during server-side rendering unless the `paths.relative` config option was explicitly set to false. The same was true for base and assets imported from $app/paths, but only if the paths.relative option was explicitly set to true.This inconsistency is fixed in version 2. Paths are either always relative or always absolute, depending on the value of `paths.relative`. It defaults to true as this results in more portable apps: if the base is something other than the app expected (as is the case when viewed on the Internet Archive, for example) or unknown at build time (as is the case when deploying to IPFS and so on), fewer things are likely to break.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Server fetches are not trackable anymore"],"href":"/docs/kit/migrating-to-sveltekit-2#Server-fetches-are-not-trackable-anymore","content":"Previously it was possible to track URLs from fetches on the server in order to rerun load functions. This poses a possible security risk (private URLs leaking), and for this reason it was behind the dangerZone.trackServerFetches setting, which is now removed.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","preloadCode` arguments must be prefixed with base`"],"href":"/docs/kit/migrating-to-sveltekit-2#preloadCode-arguments-must-be-prefixed-with-base","content":"SvelteKit exposes two functions, `preloadCode` and `preloadData`, for programmatically loading the code and data associated with a particular path. In version 1, there was a subtle inconsistency — the path passed to preloadCode did not need to be prefixed with the base path (if set), while the path passed to preloadData did.This is fixed in SvelteKit 2 — in both cases, the path should be prefixed with base if it is set.Additionally, preloadCode now takes a single argument rather than n arguments.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","`resolvePath` has been removed"],"href":"/docs/kit/migrating-to-sveltekit-2#resolvePath-has-been-removed","content":"SvelteKit 1 included a function called resolvePath which allows you to resolve a route ID (like /blog/[slug]) and a set of parameters (like { slug: 'hello' }) to a pathname. Unfortunately the return value didn't include the base path, limiting its usefulness in cases where base was set.For this reason, SvelteKit 2 replaces resolvePath with a (slightly better named) function called resolveRoute, which is imported from $app/paths and which takes base into account.---import { resolvePath } from '@sveltejs/kit';\nimport { base } from '$app/paths';---\n+++import { resolveRoute } from '$app/paths';+++\n\n---const path = base + resolvePath('/blog/[slug]', { slug });---\n+++const path = resolveRoute('/blog/[slug]', { slug });+++svelte-migrate will do the method replacement for you, though if you later prepend the result with base, you need to remove that yourself.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Improved error handling"],"href":"/docs/kit/migrating-to-sveltekit-2#Improved-error-handling","content":"Errors are handled inconsistently in SvelteKit 1. Some errors trigger the handleError hook but there is no good way to discern their status (for example, the only way to tell a 404 from a 500 is by seeing if event.route.id is null), while others (such as 405 errors for POST requests to pages without actions) don't trigger handleError at all, but should. In the latter case, the resulting $page.error will deviate from the `App.Error` type, if it is specified.SvelteKit 2 cleans this up by calling handleError hooks with two new properties: status and message. For errors thrown from your code (or library code called by your code) the status will be 500 and the message will be Internal Error. While error.message may contain sensitive information that should not be exposed to users, message is safe.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Dynamic environment variables cannot be used during prerendering"],"href":"/docs/kit/migrating-to-sveltekit-2#Dynamic-environment-variables-cannot-be-used-during-prerendering","content":"The $env/dynamic/public and $env/dynamic/private modules provide access to run time environment variables, as opposed to the build time environment variables exposed by $env/static/public and $env/static/private.During prerendering in SvelteKit 1, they are one and the same. This means that prerendered pages that make use of 'dynamic' environment variables are really 'baking in' build time values, which is incorrect. Worse, $env/dynamic/public is populated in the browser with these stale values if the user happens to land on a prerendered page before navigating to dynamically-rendered pages.Because of this, dynamic environment variables can no longer be read during prerendering in SvelteKit 2 — you should use the static modules instead. If the user lands on a prerendered page, SvelteKit will request up-to-date values for $env/dynamic/public from the server (by default from a module called /_app/env.js) instead of reading them from the server-rendered HTML.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","form` and data` have been removed from `use:enhance` callbacks"],"href":"/docs/kit/migrating-to-sveltekit-2#form-and-data-have-been-removed-from-use:enhance-callbacks","content":"If you provide a callback to `use:enhance`, it will be called with an object containing various useful properties.In SvelteKit 1, those properties included form and data. These were deprecated some time ago in favour of formElement and formData, and have been removed altogether in SvelteKit 2.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Forms containing file inputs must use `multipart/form-data`"],"href":"/docs/kit/migrating-to-sveltekit-2#Forms-containing-file-inputs-must-use-multipart-form-data","content":"If a form contains an <input type=\"file\"> but does not have an enctype=\"multipart/form-data\" attribute, non-JS submissions will omit the file. SvelteKit 2 will throw an error if it encounters a form like this during a use:enhance submission to ensure that your forms work correctly when JavaScript is not present.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Generated `tsconfig.json` is more strict"],"href":"/docs/kit/migrating-to-sveltekit-2#Generated-tsconfig.json-is-more-strict","content":"Previously, the generated tsconfig.json was trying its best to still produce a somewhat valid config when your tsconfig.json included paths or baseUrl. In SvelteKit 2, the validation is more strict and will warn when you use either paths or baseUrl in your tsconfig.json. These settings are used to generate path aliases and you should use the `alias` config option in your svelte.config.js instead, to also create a corresponding alias for the bundler.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","`getRequest` no longer throws errors"],"href":"/docs/kit/migrating-to-sveltekit-2#getRequest-no-longer-throws-errors","content":"The @sveltejs/kit/node module exports helper functions for use in Node environments, including getRequest which turns a Node `ClientRequest` into a standard `Request` object.In SvelteKit 1, getRequest could throw if the Content-Length header exceeded the specified size limit. In SvelteKit 2, the error will not be thrown until later, when the request body (if any) is being read. This enables better diagnostics and simpler code.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","vitePreprocess` is no longer exported from `@sveltejs/kit/vite"],"href":"/docs/kit/migrating-to-sveltekit-2#vitePreprocess-is-no-longer-exported-from-sveltejs-kit-vite","content":"Since @sveltejs/vite-plugin-svelte is now a peer dependency, SvelteKit 2 no longer re-exports vitePreprocess. You should import it directly from @sveltejs/vite-plugin-svelte.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","Updated dependency requirements"],"href":"/docs/kit/migrating-to-sveltekit-2#Updated-dependency-requirements","content":"SvelteKit 2 requires Node 18.13 or higher, and the following minimum dependency versions:`svelte@4`\n`vite@5`\n`typescript@5`\n`@sveltejs/vite-plugin-svelte@3` (this is now required as a `peerDependency` of SvelteKit — previously it was directly depended upon)\n`@sveltejs/adapter-cloudflare@3` (if you're using these adapters)\n`@sveltejs/adapter-cloudflare-workers@2`\n`@sveltejs/adapter-netlify@3`\n`@sveltejs/adapter-node@2`\n`@sveltejs/adapter-static@3`\n`@sveltejs/adapter-vercel@4`svelte-migrate will update your package.json for you.As part of the TypeScript upgrade, the generated tsconfig.json (the one your tsconfig.json extends from) now uses \"moduleResolution\": \"bundler\" (which is recommended by the TypeScript team, as it properly resolves types from packages with an exports map in package.json) and verbatimModuleSyntax (which replaces the existing importsNotUsedAsValues  and preserveValueImports flags — if you have those in your tsconfig.json, remove them. svelte-migrate will do this for you).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating to SvelteKit v2","SvelteKit 2.12: $app/stores deprecated"],"href":"/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated","content":"SvelteKit 2.12 introduced $app/state based on the Svelte 5 runes API. $app/state provides everything that $app/stores provides but with more flexibility as to where and how you use it. Most importantly, the page object is now fine-grained, e.g. updates to page.state will not invalidate page.data and vice-versa.As a consequence, $app/stores is deprecated and subject to be removed in SvelteKit 3. We recommend upgrading to Svelte 5, if you haven't already, and then migrate away from $app/stores. Most of the replacements should be pretty simple: Replace the $app/stores import with $app/state and remove the $ prefixes from the usage sites.<script>\n\t---import { page } from '$app/stores';---\n\t+++import { page } from '$app/state';+++\n</script>\n\n---{$page.data}---\n+++{page.data}+++Use npx sv migrate app-state to auto-migrate most of your $app/stores usages inside .svelte components.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper"],"href":"/docs/kit/migrating","content":"SvelteKit is the successor to Sapper and shares many elements of its design.If you have an existing Sapper app that you plan to migrate to SvelteKit, there are a number of changes you will need to make. You may find it helpful to view some examples while migrating.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","package.json"],"href":"/docs/kit/migrating#package.json","content":"","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","package.json","type: \"module\""],"href":"/docs/kit/migrating#package.json-type:-module","content":"Add \"type\": \"module\" to your package.json. You can do this step separately from the rest as part of an incremental migration if you are using Sapper 0.29.3\nor newer.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","package.json","dependencies"],"href":"/docs/kit/migrating#package.json-dependencies","content":"Remove polka or express, if you're using one of those, and any middleware such as sirv or compression.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","package.json","devDependencies"],"href":"/docs/kit/migrating#package.json-devDependencies","content":"Remove sapper from your devDependencies and replace it with @sveltejs/kit and whichever adapter you plan to use (see next section).","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","package.json","scripts"],"href":"/docs/kit/migrating#package.json-scripts","content":"Any scripts that reference sapper should be updated:`sapper build` should become `vite build` using the Node [adapter](adapters)\n`sapper export` should become `vite build` using the static [adapter](adapters)\n`sapper dev` should become `vite dev`\n`node __sapper__/build` should become `node build`","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files"],"href":"/docs/kit/migrating#Project-files","content":"The bulk of your app, in src/routes, can be left where it is, but several project files will need to be moved or updated.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","Configuration"],"href":"/docs/kit/migrating#Project-files-Configuration","content":"Your webpack.config.js or rollup.config.js should be replaced with a svelte.config.js, as documented here. Svelte preprocessor options should be moved to config.preprocess.You will need to add an adapter. sapper build is roughly equivalent to adapter-node while sapper export is roughly equivalent to adapter-static, though you might prefer to use an adapter designed for the platform you're deploying to.If you were using plugins for filetypes that are not automatically handled by Vite, you will need to find Vite equivalents and add them to the Vite config.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","src/client.js"],"href":"/docs/kit/migrating#Project-files-src-client.js","content":"This file has no equivalent in SvelteKit. Any custom logic (beyond sapper.start(...)) should be expressed in your +layout.svelte file, inside an onMount callback.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","src/server.js"],"href":"/docs/kit/migrating#Project-files-src-server.js","content":"When using adapter-node the equivalent is a custom server. Otherwise, this file has no direct equivalent, since SvelteKit apps can run in serverless environments.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","src/service-worker.js"],"href":"/docs/kit/migrating#Project-files-src-service-worker.js","content":"Most imports from @sapper/service-worker have equivalents in `$service-worker`:`files` is unchanged\n`routes` has been removed\n`shell` is now `build`\n`timestamp` is now `version`","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","src/template.html"],"href":"/docs/kit/migrating#Project-files-src-template.html","content":"The src/template.html file should be renamed src/app.html.Remove %sapper.base%, %sapper.scripts% and %sapper.styles%. Replace %sapper.head% with %sveltekit.head% and %sapper.html% with %sveltekit.body%. The <div id=\"sapper\"> is no longer necessary.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Project files","src/node_modules"],"href":"/docs/kit/migrating#Project-files-src-node_modules","content":"A common pattern in Sapper apps is to put your internal library in a directory inside src/node_modules. This doesn't work with Vite, so we use `src/lib` instead.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts"],"href":"/docs/kit/migrating#Pages-and-layouts","content":"","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Renamed files"],"href":"/docs/kit/migrating#Pages-and-layouts-Renamed-files","content":"Routes now are made up of the folder name exclusively to remove ambiguity, the folder names leading up to a +page.svelte correspond to the route. See the routing docs for an overview. The following shows a comparison between old and new routing structures:Old ,New \nroutes/about/index.svelte ,routes/about/+page.svelte \nroutes/about.svelte ,routes/about/+page.svelte Your custom error page component should be renamed from _error.svelte to +error.svelte. Any _layout.svelte files should likewise be renamed +layout.svelte. Any other files are ignored.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Imports"],"href":"/docs/kit/migrating#Pages-and-layouts-Imports","content":"The goto, prefetch and prefetchRoutes imports from @sapper/app should be replaced with goto, preloadData and preloadCode imports respectively from `$app/navigation`.The stores import from @sapper/app should be replaced — see the Stores section below.Any files you previously imported from directories in src/node_modules will need to be replaced with `$lib` imports.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Preload"],"href":"/docs/kit/migrating#Pages-and-layouts-Preload","content":"As before, pages and layouts can export a function that allows data to be loaded before rendering takes place.This function has been renamed from preload to `load`, it now lives in a +page.js (or +layout.js) next to its +page.svelte (or +layout.svelte), and its API has changed. Instead of two arguments — page and session — there is a single event argument.There is no more this object, and consequently no this.fetch, this.error or this.redirect. Instead, you can get `fetch` from the input methods, and both `error` and `redirect` are now thrown.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Stores"],"href":"/docs/kit/migrating#Pages-and-layouts-Stores","content":"In Sapper, you would get references to provided stores like so:import { stores } from '@sapper/app';\nconst { preloading, page, session } = stores();The page store still exists; preloading has been replaced with a navigating store that contains from and to properties. page now has url and params properties, but no path or query.You access them differently in SvelteKit. stores is now getStores, but in most cases it is unnecessary since you can import navigating, and page directly from `$app/stores`. If you're on Svelte 5 and SvelteKit 2.12 or higher, consider using `$app/state` instead.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Routing"],"href":"/docs/kit/migrating#Pages-and-layouts-Routing","content":"Regex routes are no longer supported. Instead, use advanced route matching.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","Segments"],"href":"/docs/kit/migrating#Pages-and-layouts-Segments","content":"Previously, layout components received a segment prop indicating the child segment. This has been removed; you should use the more flexible $page.url.pathname (or page.url.pathname) value to derive the segment you're interested in.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","URLs"],"href":"/docs/kit/migrating#Pages-and-layouts-URLs","content":"In Sapper, all relative URLs were resolved against the base URL — usually /, unless the basepath option was used — rather than against the current page.This caused problems and is no longer the case in SvelteKit. Instead, relative URLs are resolved against the current page (or the destination page, for fetch URLs in load functions) instead. In most cases, it's easier to use root-relative (i.e. starts with /) URLs, since their meaning is not context-dependent.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Pages and layouts","&lt;a&gt; attributes"],"href":"/docs/kit/migrating#Pages-and-layouts-a-attributes","content":"`sapper:prefetch` is now `data-sveltekit-preload-data`\n`sapper:noscroll` is now `data-sveltekit-noscroll`","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Endpoints"],"href":"/docs/kit/migrating#Endpoints","content":"In Sapper, server routes received the req and res objects exposed by Node's http module (or the augmented versions provided by frameworks like Polka and Express).SvelteKit is designed to be agnostic as to where the app is running — it could be running on a Node server, but could equally be running on a serverless platform or in a Cloudflare Worker. For that reason, you no longer interact directly with req and res. Your endpoints will need to be updated to match the new signature.To support this environment-agnostic behavior, fetch is now available in the global context, so you don't need to import node-fetch, cross-fetch, or similar server-side fetch implementations in order to use it.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Integrations"],"href":"/docs/kit/migrating#Integrations","content":"See integrations for detailed information about integrations.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Migrating from Sapper","Integrations","HTML minifier"],"href":"/docs/kit/migrating#Integrations-HTML-minifier","content":"Sapper includes html-minifier by default. SvelteKit does not include this, but you can add it as a prod dependency and then use it through a hook:import { minify } from 'html-minifier';\nimport { building } from '$app/environment';\n\nconst minification_options = {\n\tcollapseBooleanAttributes: true,\n\tcollapseWhitespace: true,\n\tconservativeCollapse: true,\n\tdecodeEntities: true,\n\thtml5: true,\n\tignoreCustomComments: [/^#/],\n\tminifyCSS: true,\n\tminifyJS: false,\n\tremoveAttributeQuotes: true,\n\tremoveComments: false, // some hydration code needs comments, so leave them in\n\tremoveOptionalTags: true,\n\tremoveRedundantAttributes: true,\n\tremoveScriptTypeAttributes: true,\n\tremoveStyleLinkTypeAttributes: true,\n\tsortAttributes: true,\n\tsortClassName: true\n};\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n\tlet page = '';\n\n\treturn resolve(event, {\n\t\ttransformPageChunk: ({ html, done }) => {\n\t\t\tpage += html;\n\t\t\tif (done) {\n\t\t\t\treturn building ? minify(page, minification_options) : page;\n\t\t\t}\n\t\t}\n\t});\n}Note that prerendering is false when using vite preview to test the production build of the site, so to verify the results of minifying, you'll need to inspect the built HTML files directly.","rank":1},{"breadcrumbs":["Docs","SvelteKit","Appendix","Additional resources"],"href":"/docs/kit/additional-resources","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Additional resources","FAQs"],"href":"/docs/kit/additional-resources#FAQs","content":"Please see the SvelteKit FAQ for solutions to common issues and helpful tips and tricks.The Svelte FAQ and `vite-plugin-svelte` FAQ may also be helpful for questions deriving from those libraries.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Additional resources","Examples"],"href":"/docs/kit/additional-resources#Examples","content":"We've written and published a few different SvelteKit sites as examples:[`sveltejs/realworld`](https://github.com/sveltejs/realworld) contains an example blog site\n[A HackerNews clone](https://github.com/sveltejs/sites/tree/master/sites/hn.svelte.dev)\n[`svelte.dev`](https://github.com/sveltejs/svelte.dev)SvelteKit users have also published plenty of examples on GitHub, under the #sveltekit and #sveltekit-template topics, as well as on the Svelte Society site. Note that these have not been vetted by the maintainers and may not be up to date.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Additional resources","Support"],"href":"/docs/kit/additional-resources#Support","content":"You can ask for help on Discord and StackOverflow. Please first search for information related to your issue in the FAQ, Google or another search engine, issue tracker, and Discord chat history in order to be respectful of others' time. There are many more people asking questions than answering them, so this will help in allowing the community to grow in a scalable fashion.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary"],"href":"/docs/kit/glossary","content":"The core of SvelteKit provides a highly configurable rendering engine. This section describes some of the terms used when discussing rendering. A reference for setting these options is provided in the documentation above.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","CSR"],"href":"/docs/kit/glossary#CSR","content":"Client-side rendering (CSR) is the generation of the page contents in the web browser using JavaScript.In SvelteKit, client-side rendering will be used by default, but you can turn off JavaScript with the `csr = false` page option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","Edge"],"href":"/docs/kit/glossary#Edge","content":"Rendering on the edge refers to rendering an application in a content delivery network (CDN) near the user. Edge rendering allows the request and response for a page to travel a shorter distance thus improving latency.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","Hybrid app"],"href":"/docs/kit/glossary#Hybrid-app","content":"SvelteKit uses a hybrid rendering mode by default where it loads the initial HTML from the server (SSR), and then updates the page contents on subsequent navigations via client-side rendering (CSR).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","Hydration"],"href":"/docs/kit/glossary#Hydration","content":"Svelte components store some state and update the DOM when the state is updated. When fetching data during SSR, by default SvelteKit will store this data and transmit it to the client along with the server-rendered HTML. The components can then be initialized on the client with that data without having to call the same API endpoints again. Svelte will then check that the DOM is in the expected state and attach event listeners in a process called hydration. Once the components are fully hydrated, they can react to changes to their properties just like any newly created Svelte component.In SvelteKit, pages will be hydrated by default, but you can turn off JavaScript with the `csr = false` page option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","ISR"],"href":"/docs/kit/glossary#ISR","content":"Incremental static regeneration (ISR) allows you to generate static pages on your site as visitors request those pages without redeploying. This may reduces build times compared to SSG sites with a large number of pages. You can do ISR with `adapter-vercel`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","MPA"],"href":"/docs/kit/glossary#MPA","content":"Traditional applications that render each page view on the server — such as those written in languages other than JavaScript — are often referred to as multi-page apps (MPA).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","Prerendering"],"href":"/docs/kit/glossary#Prerendering","content":"Prerendering means computing the contents of a page at build time and saving the HTML for display. This approach has the same benefits as traditional server-rendered pages, but avoids recomputing the page for each visitor and so scales nearly for free as the number of visitors increases. The tradeoff is that the build process is more expensive and prerendered content can only be updated by building and deploying a new version of the application.For content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain actions. Note that you can still prerender content that is loaded based on the page's parameters as long as all users will be seeing the same prerendered content. Prerendering all of your pages is also known as Static Site Generation.Pre-rendered pages are not limited to static content. You can build personalized pages if user-specific data is fetched and rendered client-side. This is subject to the caveat that you will experience the downsides of not doing SSR for that content as discussed above.In SvelteKit, you can control prerendering with the `prerender` page option and `prerender` config in svelte.config.js.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","PWA"],"href":"/docs/kit/glossary#PWA","content":"A progressive web app (PWA) is an app that's built using web APIs and technologies, but functions like a mobile or desktop app. Sites served as PWAs can be installed, allowing you to add a shortcut to the application on your launcher, home screen, or start menu. Many PWAs will utilize service workers to build offline capabilities.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","Routing"],"href":"/docs/kit/glossary#Routing","content":"By default, when you navigate to a new page (by clicking on a link or using the browser's forward or back buttons), SvelteKit will intercept the attempted navigation and handle it instead of allowing the browser to send a request to the server for the destination page. SvelteKit will then update the displayed contents on the client by rendering the component for the new page, which in turn can make calls to the necessary API endpoints. This process of updating the page on the client in response to attempted navigation is called client-side routing.In SvelteKit, client-side routing will be used by default, but you can skip it with `data-sveltekit-reload`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","SPA"],"href":"/docs/kit/glossary#SPA","content":"A single-page app (SPA) is an application in which all requests to the server load a single HTML file which then does client-side rendering based on the requested URL. All navigation is handled on the client-side in a process called client-side routing with per-page contents being updated and common layout elements remaining largely unchanged. Throughout this site, when we refer to a SPA, we use this definition where a SPA simply serves an empty shell on the initial request. It should not be confused with a hybrid app, which serves HTML on the initial request. It has a large performance impact by forcing two network round trips before rendering can begin. Because SPA mode has large negative performance and SEO impacts, it is recommended only in very limited circumstances such as when being wrapped in a mobile app.In SvelteKit, you can build SPAs with `adapter-static`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","SSG"],"href":"/docs/kit/glossary#SSG","content":"Static Site Generation (SSG) is a term that refers to a site where every page is prerendered. One benefit of fully prerendering a site is that you do not need to maintain or pay for servers to perform SSR. Once generated, the site can be served from CDNs, leading to great “time to first byte” performance. This delivery model is often referred to as JAMstack.In SvelteKit, you can do static site generation by using `adapter-static` or by configuring every page to be prerendered using the `prerender` page option or `prerender` config in svelte.config.js.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Appendix","Glossary","SSR"],"href":"/docs/kit/glossary#SSR","content":"Server-side rendering (SSR) is the generation of the page contents on the server. Returning the page contents from the server via SSR or prerendering is highly preferred for performance and SEO. It significantly improves performance by avoiding the introduction of extra round trips necessary in a SPA, and makes your app accessible to users if JavaScript fails or is disabled (which happens more often than you probably think). While some search engines can index content that is dynamically generated on the client-side, it is likely to take longer even in these cases.In SvelteKit, pages are server-side rendered by default. You can disable SSR with the `ssr` page option.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit"],"href":"/docs/kit/@sveltejs-kit","content":"import {\n\tServer,\n\tVERSION,\n\terror,\n\tfail,\n\tinvalid,\n\tisActionFailure,\n\tisHttpError,\n\tisRedirect,\n\tisValidationError,\n\tjson,\n\tnormalizeUrl,\n\tredirect,\n\ttext\n} from '@sveltejs/kit';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Server"],"href":"/docs/kit/@sveltejs-kit#Server","content":"class Server {/*…*/}\nconstructor(manifest: SSRManifest);\n\ninit(options: ServerInitOptions): Promise<void>;\n\nrespond(request: Request, options: RequestOptions): Promise<Response>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","VERSION"],"href":"/docs/kit/@sveltejs-kit#VERSION","content":"const VERSION: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","error"],"href":"/docs/kit/@sveltejs-kit#error","content":"Throws an error with a HTTP status code and an optional message.\nWhen called during request handling, this will cause SvelteKit to\nreturn an error response without invoking handleError.\nMake sure you're not catching the thrown error, which would prevent SvelteKit from handling it.\nfunction error(status: number, body: App.Error): never;\n\nfunction error(\n\tstatus: number,\n\tbody?: {\n\t\tmessage: string;\n\t} extends App.Error\n\t\t? App.Error | string | undefined\n\t\t: never\n): never;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","fail"],"href":"/docs/kit/@sveltejs-kit#fail","content":"Create an ActionFailure object. Call when form submission fails.\nfunction fail(status: number): ActionFailure<undefined>;\n\nfunction fail<T = undefined>(\n\tstatus: number,\n\tdata: T\n): ActionFailure<T>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","invalid"],"href":"/docs/kit/@sveltejs-kit#invalid","content":"Available since 2.47.3\nUse this to throw a validation error to imperatively fail form validation.\nCan be used in combination with issue passed to form actions to create field-specific issues.import { invalid } from '@sveltejs/kit';\nimport { form } from '$app/server';\nimport { tryLogin } from '$lib/server/auth';\nimport * as v from 'valibot';\n\nexport const login = form(\n\tv.object({ name: v.string(), _password: v.string() }),\n\tasync ({ name, _password }) => {\n\t\tconst success = tryLogin(name, _password);\n\t\tif (!success) {\n\t\t\tinvalid('Incorrect username or password');\n\t\t}\n\n\t\t// ...\n\t}\n);\nfunction invalid(\n\t...issues: (StandardSchemaV1.Issue | string)[]\n): never;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","isActionFailure"],"href":"/docs/kit/@sveltejs-kit#isActionFailure","content":"Checks whether this is an action failure thrown by fail.\nfunction isActionFailure(e: unknown): e is ActionFailure;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","isHttpError"],"href":"/docs/kit/@sveltejs-kit#isHttpError","content":"Checks whether this is an error thrown by error.\nfunction isHttpError<T extends number>(\n\te: unknown,\n\tstatus?: T\n): e is HttpError_1 & {\n\tstatus: T extends undefined ? never : T;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","isRedirect"],"href":"/docs/kit/@sveltejs-kit#isRedirect","content":"Checks whether this is a redirect thrown by redirect.\nfunction isRedirect(e: unknown): e is Redirect_1;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","isValidationError"],"href":"/docs/kit/@sveltejs-kit#isValidationError","content":"Available since 2.47.3\nChecks whether this is an validation error thrown by invalid.\nfunction isValidationError(e: unknown): e is ActionFailure;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","json"],"href":"/docs/kit/@sveltejs-kit#json","content":"Create a JSON Response object from the supplied data.\nfunction json(data: any, init?: ResponseInit): Response;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","normalizeUrl"],"href":"/docs/kit/@sveltejs-kit#normalizeUrl","content":"Available since 2.18.0\nStrips possible SvelteKit-internal suffixes and trailing slashes from the URL pathname.\nReturns the normalized URL as well as a method for adding the potential suffix back\nbased on a new pathname (possibly including search) or URL. \nimport { normalizeUrl } from '@sveltejs/kit';\n\nconst { url, denormalize } = normalizeUrl('/blog/post/__data.json');\nconsole.log(url.pathname); // /blog/post\nconsole.log(denormalize('/blog/post/a')); // /blog/post/a/__data.json\nfunction normalizeUrl(url: URL | string): {\n\turl: URL;\n\twasNormalized: boolean;\n\tdenormalize: (url?: string | URL) => URL;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","redirect"],"href":"/docs/kit/@sveltejs-kit#redirect","content":"Redirect a request. When called during request handling, SvelteKit will return a redirect response.\nMake sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it.Most common status codes:`303 See Other`: redirect as a GET request (often used after a form POST request)\n`307 Temporary Redirect`: redirect will keep the request method\n`308 Permanent Redirect`: redirect will keep the request method, SEO will be transferred to the new pageSee all redirect status codes\nfunction redirect(\n\tstatus:\n\t\t| 300\n\t\t| 301\n\t\t| 302\n\t\t| 303\n\t\t| 304\n\t\t| 305\n\t\t| 306\n\t\t| 307\n\t\t| 308\n\t\t| ({} & number),\n\tlocation: string | URL\n): never;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","text"],"href":"/docs/kit/@sveltejs-kit#text","content":"Create a Response object from the supplied body.\nfunction text(body: string, init?: ResponseInit): Response;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Action"],"href":"/docs/kit/@sveltejs-kit#Action","content":"Shape of a form action method that is part of export const actions = {...} in +page.server.js.\nSee form actions for more information.\ntype Action<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tOutputData extends Record<string, any> | void = Record<\n\t\tstring,\n\t\tany\n\t> | void,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> = (\n\tevent: RequestEvent<Params, RouteId>\n) => MaybePromise<OutputData>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ActionFailure"],"href":"/docs/kit/@sveltejs-kit#ActionFailure","content":"interface ActionFailure<T = undefined> {/*…*/}\nstatus: number;\n\ndata: T;\n\n[uniqueSymbol]: true;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ActionResult"],"href":"/docs/kit/@sveltejs-kit#ActionResult","content":"When calling a form action via fetch, the response will be one of these shapes.<form method=\"post\" use:enhance={() => {\n\treturn ({ result }) => {\n\t\t// result is of type ActionResult\n\t};\n}}\ntype ActionResult<\n\tSuccess extends Record<string, unknown> | undefined =\n\t\tRecord<string, any>,\n\tFailure extends Record<string, unknown> | undefined =\n\t\tRecord<string, any>\n> =\n\t| { type: 'success'; status: number; data?: Success }\n\t| { type: 'failure'; status: number; data?: Failure }\n\t| { type: 'redirect'; status: number; location: string }\n\t| { type: 'error'; status?: number; error: any };","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Actions"],"href":"/docs/kit/@sveltejs-kit#Actions","content":"Shape of the export const actions = {...} object in +page.server.js.\nSee form actions for more information.\ntype Actions<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tOutputData extends Record<string, any> | void = Record<\n\t\tstring,\n\t\tany\n\t> | void,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> = Record<string, Action<Params, OutputData, RouteId>>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Adapter"],"href":"/docs/kit/@sveltejs-kit#Adapter","content":"Adapters are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing.\ninterface Adapter {/*…*/}\nname: string;\nThe name of the adapter, using for logging. Will typically correspond to the package name.\n\nadapt: (builder: Builder) => MaybePromise<void>;\n\n`builder` An object provided by SvelteKit that contains methods for adapting the app\nThis function is called after SvelteKit has built your app.\n\nsupports?: {/*…*/}\nChecks called during dev and build to determine whether specific features will work in production with this adapter.\nread?: (details: { config: any; route: { id: string } }) => boolean;\n\n`details.config` The merged adapter-specific route config exported from the route with `export const config`\nTest support for read from $app/server.\ninstrumentation?: () => boolean;\n\n<span class=\"tag since\">available since</span> v2.31.0\nTest support for instrumentation.server.js. To pass, the adapter must support running instrumentation.server.js prior to the application code.\n\n\nemulate?: () => MaybePromise<Emulator>;\nCreates an Emulator, which allows the adapter to influence the environment\nduring dev, build and prerendering.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","AfterNavigate"],"href":"/docs/kit/@sveltejs-kit#AfterNavigate","content":"The argument passed to `afterNavigate` callbacks.\ntype AfterNavigate = (Navigation | NavigationEnter) & {\n\ttype: Exclude<NavigationType, 'leave'>;\n\t/**\n\t * Since `afterNavigate` callbacks are called after a navigation completes, they will never be called with a navigation that unloads the page.\n\t */\n\twillUnload: false;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","AwaitedActions"],"href":"/docs/kit/@sveltejs-kit#AwaitedActions","content":"type AwaitedActions<\n\tT extends Record<string, (...args: any) => any>\n> = OptionalUnion<\n\t{\n\t\t[Key in keyof T]: UnpackValidationError<\n\t\t\tAwaited<ReturnType<T[Key]>>\n\t\t>;\n\t}[keyof T]\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","BeforeNavigate"],"href":"/docs/kit/@sveltejs-kit#BeforeNavigate","content":"The argument passed to `beforeNavigate` callbacks.\ntype BeforeNavigate = Navigation & {\n\t/**\n\t * Call this to prevent the navigation from starting.\n\t */\n\tcancel: () => void;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Builder"],"href":"/docs/kit/@sveltejs-kit#Builder","content":"This object is passed to the adapt function of adapters.\nIt contains various methods and properties that are useful for adapting the app.\ninterface Builder {/*…*/}\nlog: Logger;\nPrint messages to the console. log.info and log.minor are silent unless Vite's logLevel is info.\n\nrimraf: (dir: string) => void;\nRemove dir and all its contents.\n\nmkdirp: (dir: string) => void;\nCreate dir and any required parent directories.\n\nconfig: ValidatedConfig;\nThe fully resolved Svelte config.\n\nprerendered: Prerendered;\nInformation about prerendered pages and assets, if any.\n\nroutes: RouteDefinition[];\nAn array of all routes (including prerendered)\n\ncreateEntries: (fn: (route: RouteDefinition) => AdapterEntry) => Promise<void>;\n\n`fn` A function that groups a set of routes into an entry point\n<span class=\"tag deprecated\">deprecated</span> Use `builder.routes` instead\nCreate separate functions that map to one or more routes of your app.\n\nfindServerAssets: (routes: RouteDefinition[]) => string[];\nFind all the assets imported by server files belonging to routes\n\ngenerateFallback: (dest: string) => Promise<void>;\nGenerate a fallback page for a static webserver to use when no route is matched. Useful for single-page apps.\n\ngenerateEnvModule: () => void;\nGenerate a module exposing build-time environment variables as $env/dynamic/public if the app uses it.\n\ngenerateManifest: (opts: { relativePath: string; routes?: RouteDefinition[] }) => string;\n\n`opts` a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated\nGenerate a server-side manifest to initialise the SvelteKit server with.\n\ngetBuildDirectory: (name: string) => string;\n\n`name` path to the file, relative to the build directory\nResolve a path to the name directory inside outDir, e.g. /path/to/.svelte-kit/my-adapter.\n\ngetClientDirectory: () => string;\nGet the fully resolved path to the directory containing client-side assets, including the contents of your static directory.\n\ngetServerDirectory: () => string;\nGet the fully resolved path to the directory containing server-side code.\n\ngetAppPath: () => string;\nGet the application path including any configured base path, e.g. my-base-path/_app.\n\nwriteClient: (dest: string) => string[];\n\n`dest` the destination folder\n<span class=\"tag\">returns</span> an array of files written to `dest`\nWrite client assets to dest.\n\nwritePrerendered: (dest: string) => string[];\n\n`dest` the destination folder\n<span class=\"tag\">returns</span> an array of files written to `dest`\nWrite prerendered files to dest.\n\nwriteServer: (dest: string) => string[];\n\n`dest` the destination folder\n<span class=\"tag\">returns</span> an array of files written to `dest`\nWrite server-side code to dest.\n\ncopy: (\n\tfrom: string,\n\tto: string,\n\topts?: {\n\t\tfilter?(basename: string): boolean;\n\t\treplace?: Record<string, string>;\n\t}\n) => string[];\n\n`from` the source file or directory\n`to` the destination file or directory\n`opts.filter` a function to determine whether a file or directory should be copied\n`opts.replace` a map of strings to replace\n<span class=\"tag\">returns</span> an array of files that were copied\nCopy a file or directory.\n\nhasServerInstrumentationFile: () => boolean;\n\n<span class=\"tag\">returns</span> true if the server instrumentation file exists, false otherwise\n<span class=\"tag since\">available since</span> v2.31.0\nCheck if the server instrumentation file exists.\n\ninstrument: (args: {\n\tentrypoint: string;\n\tinstrumentation: string;\n\tstart?: string;\n\tmodule?:\n\t\t| {\n\t\t\t\texports: string[];\n\t\t  }\n\t\t| {\n\t\t\t\tgenerateText: (args: { instrumentation: string; start: string }) => string;\n\t\t  };\n}) => void;\n\n`options` an object containing the following properties:\n`options.entrypoint` the path to the entrypoint to trace.\n`options.instrumentation` the path to the instrumentation file.\n`options.start` the name of the start file. This is what `entrypoint` will be renamed to.\n`options.module` configuration for the resulting entrypoint module.\n`options.module.generateText` a function that receives the relative paths to the instrumentation and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await.\n<span class=\"tag since\">available since</span> v2.31.0\nInstrument entrypoint with instrumentation.Renames entrypoint to start and creates a new module at\nentrypoint which imports instrumentation and then dynamically imports start. This allows\nthe module hooks necessary for instrumentation libraries to be loaded prior to any application code.Caveats:\"Live exports\" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup.\nIf `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it.\nUse `hasServerInstrumentationFile` to check if the user has a server instrumentation file; if they don't, you shouldn't do this.\n\ncompress: (directory: string) => Promise<void>;\n\n`directory` The directory containing the files to be compressed\nCompress files in directory with gzip and brotli, where appropriate. Generates .gz and .br files alongside the originals.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ClientInit"],"href":"/docs/kit/@sveltejs-kit#ClientInit","content":"Available since 2.10.0\nThe `init` will be invoked once the app starts in the browser\ntype ClientInit = () => MaybePromise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Config"],"href":"/docs/kit/@sveltejs-kit#Config","content":"See the configuration reference for details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Cookies"],"href":"/docs/kit/@sveltejs-kit#Cookies","content":"interface Cookies {/*…*/}\nget: (name: string, opts?: import('cookie').CookieParseOptions) => string | undefined;\n\n`name` the name of the cookie\n`opts` the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options)\nGets a cookie that was previously set with cookies.set, or from the request headers.\n\ngetAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string; value: string }>;\n\n`opts` the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options)\nGets all cookies that were previously set with cookies.set, or from the request headers.\n\nset: (\n\tname: string,\n\tvalue: string,\n\topts: import('cookie').CookieSerializeOptions & { path: string }\n) => void;\n\n`name` the name of the cookie\n`value` the cookie value\n`opts` the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)\nSets a cookie. This will add a set-cookie header to the response, but also make the cookie available via cookies.get or cookies.getAll during the current request.The httpOnly and secure options are true by default (except on http://localhost, where secure is false), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The sameSite option defaults to lax.You must specify a path for the cookie. In most cases you should explicitly set path: '/' to make the cookie available throughout your app. You can use relative paths, or set path: '' to make the cookie only available on the current path and its children\n\ndelete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void;\n\n`name` the name of the cookie\n`opts` the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)\nDeletes a cookie by setting its value to an empty string and setting the expiry date in the past.You must specify a path for the cookie. In most cases you should explicitly set path: '/' to make the cookie available throughout your app. You can use relative paths, or set path: '' to make the cookie only available on the current path and its children\n\nserialize: (\n\tname: string,\n\tvalue: string,\n\topts: import('cookie').CookieSerializeOptions & { path: string }\n) => string;\n\n`name` the name of the cookie\n`value` the cookie value\n`opts` the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)\nSerialize a cookie name-value pair into a Set-Cookie header string, but don't apply it to the response.The httpOnly and secure options are true by default (except on http://localhost, where secure is false), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The sameSite option defaults to lax.You must specify a path for the cookie. In most cases you should explicitly set path: '/' to make the cookie available throughout your app. You can use relative paths, or set path: '' to make the cookie only available on the current path and its children","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Emulator"],"href":"/docs/kit/@sveltejs-kit#Emulator","content":"A collection of functions that influence the environment during dev, build and prerendering\ninterface Emulator {/*…*/}\nplatform?(details: { config: any; prerender: PrerenderOption }): MaybePromise<App.Platform>;\nA function that is called with the current route config and prerender option\nand returns an App.Platform object","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","EnvVarConfig"],"href":"/docs/kit/@sveltejs-kit#EnvVarConfig","content":"Environment variables can be configured by exporting\na variables object from src/env.ts, using `defineEnvVars`.\ninterface EnvVarConfig<T> {/*…*/}\npublic?: boolean;\n\n<span class=\"tag\">default</span> `false`\nWhether the environment variable can be accessed by client-side code.if `true`, it can be imported from `$app/env/public`\nif `false`, it can be imported from `$app/env/private`, which is a [server-only module](/docs/kit/server-only-modules)\n\nstatic?: boolean;\n\n<span class=\"tag\">default</span> `false`\nWhether the value is determined at build time or when the app runs.if `true`, the build time value is inlined into the bundle. This enables optimisations like dead-code elimination\nif `false`, the value is read from the environment when the app starts\n\nschema?: StandardSchemaV1<string | undefined, T>;\nA Standard Schema validator that is applied to the value when the app starts.\nThe validator can output any value — not necessarily a string — but public, non-static values must be\nserializable by devalue so that they can be sent to the browser.If omitted, the value must be a non-empty string.\n\ndescription?: string;\nA description of the variable that will be used for inline documentation on hover.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Handle"],"href":"/docs/kit/@sveltejs-kit#Handle","content":"The `handle` hook runs every time the SvelteKit server receives a request and\ndetermines the response.\nIt receives an event object representing the request and a function called resolve, which renders the route and generates a Response.\nThis allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).\ntype Handle = (input: {\n\tevent: RequestEvent;\n\tresolve: (\n\t\tevent: RequestEvent,\n\t\topts?: ResolveOptions\n\t) => MaybePromise<Response>;\n}) => MaybePromise<Response>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HandleClientError"],"href":"/docs/kit/@sveltejs-kit#HandleClientError","content":"The client-side `handleError` hook runs when an unexpected error is thrown while navigating.If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event.\nMake sure that this function never throws an error.\ntype HandleClientError = (input: {\n\terror: unknown;\n\tevent: NavigationEvent;\n\tstatus: number;\n\tmessage: string;\n}) => MaybePromise<void | App.Error>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HandleFetch"],"href":"/docs/kit/@sveltejs-kit#HandleFetch","content":"The `handleFetch` hook allows you to modify (or replace) the result of an `event.fetch` call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.\ntype HandleFetch = (input: {\n\tevent: RequestEvent;\n\trequest: Request;\n\tfetch: typeof fetch;\n}) => MaybePromise<Response>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HandleServerError"],"href":"/docs/kit/@sveltejs-kit#HandleServerError","content":"The server-side `handleError` hook runs when an unexpected error is thrown while responding to a request.If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event.\nMake sure that this function never throws an error.\ntype HandleServerError = (input: {\n\terror: unknown;\n\tevent: RequestEvent;\n\tstatus: number;\n\tmessage: string;\n}) => MaybePromise<void | App.Error>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HandleValidationError"],"href":"/docs/kit/@sveltejs-kit#HandleValidationError","content":"The `handleValidationError` hook runs when the argument to a remote function fails validation.It will be called with the validation issues and the event, and must return an object shape that matches App.Error.\ntype HandleValidationError<\n\tIssue extends StandardSchemaV1.Issue =\n\t\tStandardSchemaV1.Issue\n> = (input: {\n\tissues: Issue[];\n\tevent: RequestEvent;\n}) => MaybePromise<App.Error>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HttpError"],"href":"/docs/kit/@sveltejs-kit#HttpError","content":"The object returned by the `error` function.\ninterface HttpError {/*…*/}\nstatus: number;\nThe HTTP status code, in the range 400-599.\n\nbody: App.Error;\nThe content of the error.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","InvalidField"],"href":"/docs/kit/@sveltejs-kit#InvalidField","content":"A function and proxy object used to imperatively create validation errors in form handlers.Access properties to create field-specific issues: issue.fieldName('message').\nThe type structure mirrors the input data structure for type-safe field access.\nCall invalid(issue.foo(...), issue.nested.bar(...)) to throw a validation error.\ntype InvalidField<T> =\n\tWillRecurseIndefinitely<T> extends true\n\t\t? Record<string | number, any>\n\t\t: NonNullable<T> extends\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| boolean\n\t\t\t\t\t| File\n\t\t\t? (message: string) => StandardSchemaV1.Issue\n\t\t\t: NonNullable<T> extends Array<infer U>\n\t\t\t\t? {\n\t\t\t\t\t\t[K in number]: InvalidField<U>;\n\t\t\t\t\t} & ((message: string) => StandardSchemaV1.Issue)\n\t\t\t\t: NonNullable<T> extends RemoteFormInput\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t[K in keyof T]-?: InvalidField<T[K]>;\n\t\t\t\t\t\t} & ((\n\t\t\t\t\t\t\tmessage: string\n\t\t\t\t\t\t) => StandardSchemaV1.Issue)\n\t\t\t\t\t: Record<string, never>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","KitConfig"],"href":"/docs/kit/@sveltejs-kit#KitConfig","content":"See the configuration reference for details.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","LessThan"],"href":"/docs/kit/@sveltejs-kit#LessThan","content":"type LessThan<\n\tTNumber extends number,\n\tTArray extends any[] = []\n> = TNumber extends TArray['length']\n\t? TArray[number]\n\t: LessThan<TNumber, [...TArray, TArray['length']]>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","LiveQueryRequestedResult"],"href":"/docs/kit/@sveltejs-kit#LiveQueryRequestedResult","content":"type LiveQueryRequestedResult<Validated, Output> = Iterable<\n\tLiveRequestedEntry<Validated, Output>\n> &\n\tAsyncIterable<LiveRequestedEntry<Validated, Output>> & {\n\t\t/**\n\t\t * Call `reconnect` on all live queries selected by this `requested` invocation.\n\t\t * This is identical to:\n\t\t * ```ts\n\t\t * import { requested } from '$app/server';\n\t\t *\n\t\t * for await (const { query } of requested(liveQuery, ...)) {\n\t\t *   void query.reconnect();\n\t\t * }\n\t\t * ```\n\t\t */\n\t\treconnectAll: () => Promise<void>;\n\t};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","LiveRequestedEntry"],"href":"/docs/kit/@sveltejs-kit#LiveRequestedEntry","content":"A single entry yielded by `requested`\nwhen called with a query.live. arg is the validated argument; query is a\nRemoteLiveQuery bound to the client's original cache key, so reconnect() targets\nthe correct client subscription.\ntype LiveRequestedEntry<Validated, Output> = {\n\targ: Validated;\n\tquery: RemoteLiveQuery<Output>;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Load"],"href":"/docs/kit/@sveltejs-kit#Load","content":"The generic form of PageLoad and LayoutLoad. You should import those from ./$types (see generated types)\nrather than using Load directly.\ntype Load<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tInputData extends Record<string, unknown> | null = Record<\n\t\tstring,\n\t\tany\n\t> | null,\n\tParentData extends Record<string, unknown> = Record<\n\t\tstring,\n\t\tany\n\t>,\n\tOutputData extends Record<string, unknown> | void =\n\t\tRecord<string, any> | void,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> = (\n\tevent: LoadEvent<Params, InputData, ParentData, RouteId>\n) => MaybePromise<OutputData>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","LoadEvent"],"href":"/docs/kit/@sveltejs-kit#LoadEvent","content":"The generic form of PageLoadEvent and LayoutLoadEvent. You should import those from ./$types (see generated types)\nrather than using LoadEvent directly.\ninterface LoadEvent<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tData extends Record<string, unknown> | null = Record<\n\t\tstring,\n\t\tany\n\t> | null,\n\tParentData extends Record<string, unknown> = Record<\n\t\tstring,\n\t\tany\n\t>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> extends NavigationEvent<Params, RouteId> {/*…*/}\nfetch: typeof fetch;\nfetch is equivalent to the native `fetch` web API, with a few additional features:It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.\nIt can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).\nInternal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.\nDuring server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](/docs/kit/hooks#Server-hooks-handle)\nDuring hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.You can learn more about making credentialed requests with cookies here\n\ndata: Data;\nContains the data returned by the route's server load function (in +layout.server.js or +page.server.js), if any.\n\nsetHeaders: (headers: Record<string, string>) => void;\nIf you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example: \n \nexport async function load({ fetch, setHeaders }) {\n\tconst url = `https://cms.example.com/articles.json`;\n\tconst response = await fetch(url);\n\n\tsetHeaders({\n\t\tage: response.headers.get('age'),\n\t\t'cache-control': response.headers.get('cache-control')\n\t});\n\n\treturn response.json();\n}Setting the same header multiple times (even in separate load functions) is an error — you can only set a given header once.You cannot add a set-cookie header with setHeaders — use the `cookies` API in a server-only load function instead.setHeaders has no effect when a load function runs in the browser.\n\nparent: () => Promise<ParentData>;\nawait parent() returns data from parent +layout.js load functions.\nImplicitly, a missing +layout.js is treated as a ({ data }) => data function, meaning that it will return and forward data from parent +layout.server.js files.Be careful not to introduce accidental waterfalls when using await parent(). If for example you only want to merge parent data into the returned output, call it after fetching your other data.\n\ndepends: (...deps: Array<`${string}:${string}`>) => void;\nThis function declares that the load function has a dependency on one or more URLs or custom identifiers, which can subsequently be used with `invalidate()` to cause load to rerun.Most of the time you won't need this, as fetch calls depends on your behalf — it's only necessary if you're using a custom API client that bypasses fetch.URLs can be absolute or relative to the page being loaded, and must be encoded.Custom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the URI specification.The following example shows how to use depends to register a dependency on a custom identifier, which is invalidated after a button click, making the load function rerun. \n \nlet count = 0;\nexport async function load({ depends }) {\n\tdepends('increase:count');\n\n\treturn { count: count++ };\n} \n<script>\n\timport { invalidate } from '$app/navigation';\n\n\tlet { data } = $props();\n\n\tconst increase = async () => {\n\t\tawait invalidate('increase:count');\n\t}\n</script>\n\n<p>{data.count}<p>\n<button on:click={increase}>Increase Count</button>\n\nuntrack: <T>(fn: () => T) => T;\nUse this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: \n \nexport async function load({ untrack, url }) {\n\t// Untrack url.pathname so that path changes don't trigger a rerun\n\tif (untrack(() => url.pathname === '/')) {\n\t\treturn { message: 'Welcome!' };\n\t}\n}\n\ntracing: {/*…*/}\n\n<span class=\"tag since\">available since</span> v2.31.0\nAccess to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.\nenabled: boolean;\nWhether tracing is enabled.\nroot: Span;\nThe root span for the request. This span is named sveltekit.handle.root.\ncurrent: Span;\nThe span associated with the current load function.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","LoadProperties"],"href":"/docs/kit/@sveltejs-kit#LoadProperties","content":"type LoadProperties<\n\tinput extends Record<string, any> | void\n> = input extends void\n\t? undefined // needs to be undefined, because void will break intellisense\n\t: input extends Record<string, any>\n\t\t? input\n\t\t: unknown;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Navigation"],"href":"/docs/kit/@sveltejs-kit#Navigation","content":"type Navigation =\n\t| NavigationExternal\n\t| NavigationFormSubmit\n\t| NavigationPopState\n\t| NavigationLink;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationBase"],"href":"/docs/kit/@sveltejs-kit#NavigationBase","content":"interface NavigationBase {/*…*/}\nfrom: NavigationTarget | null;\nWhere navigation was triggered from\n\nto: NavigationTarget | null;\nWhere navigation is going to/has gone to\n\nwillUnload: boolean;\nWhether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation).\n\ncomplete: Promise<void>;\nA promise that resolves once the navigation is complete, and rejects if the navigation\nfails or is aborted. In the case of a willUnload navigation, the promise will never resolve","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationEnter"],"href":"/docs/kit/@sveltejs-kit#NavigationEnter","content":"interface NavigationEnter extends NavigationBase {/*…*/}\ntype: 'enter';\nThe type of navigation:`enter`: The app has hydrated/started\n\ndelta?: undefined;\nIn case of a history back/forward navigation, the number of steps to go back/forward\n\nevent?: undefined;\nDispatched Event object when navigation occurred by popstate or link.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationEvent"],"href":"/docs/kit/@sveltejs-kit#NavigationEvent","content":"interface NavigationEvent<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> {/*…*/}\nparams: Params;\nThe parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object\n\nroute: {/*…*/}\nInfo about the current route\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]. It is null when no route is matched.\n\n\nurl: URL;\nThe URL of the current page","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationExternal"],"href":"/docs/kit/@sveltejs-kit#NavigationExternal","content":"type NavigationExternal = NavigationGoto | NavigationLeave;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationFormSubmit"],"href":"/docs/kit/@sveltejs-kit#NavigationFormSubmit","content":"interface NavigationFormSubmit extends NavigationBase {/*…*/}\ntype: 'form';\nThe type of navigation:`form`: The user submitted a `<form method=\"GET\">`\n\nevent: SubmitEvent;\nThe SubmitEvent that caused the navigation\n\ndelta?: undefined;\nIn case of a history back/forward navigation, the number of steps to go back/forward","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationGoto"],"href":"/docs/kit/@sveltejs-kit#NavigationGoto","content":"interface NavigationGoto extends NavigationBase {/*…*/}\ntype: 'goto';\nThe type of navigation:`goto`: Navigation was triggered by a `goto(...)` call or a redirect\n\ndelta?: undefined;\nIn case of a history back/forward navigation, the number of steps to go back/forward","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationLeave"],"href":"/docs/kit/@sveltejs-kit#NavigationLeave","content":"interface NavigationLeave extends NavigationBase {/*…*/}\ntype: 'leave';\nThe type of navigation:`leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring\n\ndelta?: undefined;\nIn case of a history back/forward navigation, the number of steps to go back/forward","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationLink"],"href":"/docs/kit/@sveltejs-kit#NavigationLink","content":"interface NavigationLink extends NavigationBase {/*…*/}\ntype: 'link';\nThe type of navigation:`link`: Navigation was triggered by a link click\n\nevent: PointerEvent;\nThe PointerEvent that caused the navigation\n\ndelta?: undefined;\nIn case of a history back/forward navigation, the number of steps to go back/forward","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationPopState"],"href":"/docs/kit/@sveltejs-kit#NavigationPopState","content":"interface NavigationPopState extends NavigationBase {/*…*/}\ntype: 'popstate';\nThe type of navigation:`popstate`: Navigation was triggered by back/forward navigation\n\ndelta: number;\nIn case of a history back/forward navigation, the number of steps to go back/forward\n\nevent: PopStateEvent;\nThe PopStateEvent that caused the navigation","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationTarget"],"href":"/docs/kit/@sveltejs-kit#NavigationTarget","content":"Information about the target of a specific navigation.\ninterface NavigationTarget<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> {/*…*/}\nparams: Params | null;\nParameters of the target page - e.g. for a route like /blog/[slug], a { slug: string } object.\nIs null if the target is not part of the SvelteKit app (could not be resolved to a route).\n\nroute: {/*…*/}\nInfo about the target route\nid: RouteId | null;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]. It is null when no route is matched.\n\n\nurl: URL;\nThe URL that is navigated to\n\nscroll: { x: number; y: number } | null;\nThe scroll position associated with this navigation.For the from target, this is the scroll position at the moment of navigation.For the to target, this represents the scroll position that will be or was restored:In `beforeNavigate` and `onNavigate`, this is only available for `popstate` navigations (back/forward button)\n  and will be `null` for other navigation types, since the final scroll position isn't known\n  ahead of time.\nIn `afterNavigate`, this is always the scroll position that was applied after the navigation\n  completed.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NavigationType"],"href":"/docs/kit/@sveltejs-kit#NavigationType","content":"`enter`: The app has hydrated/started\n`form`: The user submitted a `<form method=\"GET\">`\n`leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring\n`link`: Navigation was triggered by a link click\n`goto`: Navigation was triggered by a `goto(...)` call or a redirect\n`popstate`: Navigation was triggered by back/forward navigation\ntype NavigationType =\n\t| 'enter'\n\t| 'form'\n\t| 'leave'\n\t| 'link'\n\t| 'goto'\n\t| 'popstate';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","NumericRange"],"href":"/docs/kit/@sveltejs-kit#NumericRange","content":"type NumericRange<\n\tTStart extends number,\n\tTEnd extends number\n> = Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","OnNavigate"],"href":"/docs/kit/@sveltejs-kit#OnNavigate","content":"The argument passed to `onNavigate` callbacks.\ntype OnNavigate = Navigation & {\n\ttype: Exclude<NavigationType, 'enter' | 'leave'>;\n\t/**\n\t * Since `onNavigate` callbacks are called immediately before a client-side navigation, they will never be called with a navigation that unloads the page.\n\t */\n\twillUnload: false;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Page"],"href":"/docs/kit/@sveltejs-kit#Page","content":"The shape of the `page` reactive object and the `$page` store.\ninterface Page<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> {/*…*/}\nurl: URL & { pathname: ResolvedPathname };\nThe URL of the current page.\n\nparams: Params;\nThe parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object.\n\nroute: {/*…*/}\nInfo about the current route.\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]. It is null when no route is matched.\n\n\nstatus: number;\nHTTP status code of the current page.\n\nerror: App.Error | null;\nThe error object of the current page, if any. Filled from the handleError hooks.\n\ndata: App.PageData & Record<string, any>;\nThe merged result of all data from all load functions on the current page. You can type a common denominator through App.PageData.\n\nstate: App.PageState;\nThe page state, which can be manipulated using the `pushState` and `replaceState` functions from $app/navigation.\n\nform: any;\nFilled only after a form submission. See form actions for more info.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ParamMatcher"],"href":"/docs/kit/@sveltejs-kit#ParamMatcher","content":"The shape of a param matcher. See matching for more info.\ntype ParamMatcher = (param: string) => boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderOption"],"href":"/docs/kit/@sveltejs-kit#PrerenderOption","content":"type PrerenderOption = boolean | 'auto';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","QueryRequestedResult"],"href":"/docs/kit/@sveltejs-kit#QueryRequestedResult","content":"type QueryRequestedResult<Validated, Output> = Iterable<\n\tRequestedEntry<Validated, Output>\n> &\n\tAsyncIterable<RequestedEntry<Validated, Output>> & {\n\t\t/**\n\t\t * Call `refresh` on all queries selected by this `requested` invocation.\n\t\t * This is identical to:\n\t\t * ```ts\n\t\t * import { requested } from '$app/server';\n\t\t *\n\t\t * for await (const { query } of requested(getPost, ...)) {\n\t\t *   void query.refresh();\n\t\t * }\n\t\t * ```\n\t\t */\n\t\trefreshAll: () => Promise<void>;\n\t};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Redirect"],"href":"/docs/kit/@sveltejs-kit#Redirect","content":"The object returned by the `redirect` function.\ninterface Redirect {/*…*/}\nstatus: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;\nThe HTTP status code, in the range 300-308.\n\nlocation: string;\nThe location to redirect to.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteCommand"],"href":"/docs/kit/@sveltejs-kit#RemoteCommand","content":"The type of a remote command function. See Remote functions for full documentation.\ntype RemoteCommand<Input, Output> = {\n\t(\n\t\targ: undefined extends Input ? Input | void : Input\n\t): Promise<Output> & {\n\t\tupdates(\n\t\t\t...updates: RemoteQueryUpdate[]\n\t\t): Promise<Output>;\n\t};\n\t/** The number of pending command executions */\n\tget pending(): number;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteForm"],"href":"/docs/kit/@sveltejs-kit#RemoteForm","content":"The type of a remote form function. See Remote functions for full documentation.\ntype RemoteForm<\n\tInput extends RemoteFormInput | void,\n\tOutput\n> = {\n\t/** Attachment that sets up an event handler that intercepts the form submission on the client to prevent a full page reload */\n\t[attachment: symbol]: (node: HTMLFormElement) => void;\n\tmethod: 'POST';\n\t/** The URL to send the form to. */\n\taction: string;\n\t/** The `<form>` element this instance is currently attached to, if any. */\n\tget element(): HTMLFormElement | null;\n\t/** Submit the currently attached form programmatically. */\n\tsubmit(): Promise<boolean> & {\n\t\tupdates: (\n\t\t\t...updates: RemoteQueryUpdate[]\n\t\t) => Promise<boolean>;\n\t};\n\t/** Use the `enhance` method to influence what happens when the form is submitted. */\n\tenhance(\n\t\tcallback: (\n\t\t\tform: Omit<\n\t\t\t\tRemoteForm<Input, Output>,\n\t\t\t\t'enhance' | 'element'\n\t\t\t> & {\n\t\t\t\treadonly element: HTMLFormElement;\n\t\t\t}\n\t\t) => MaybePromise<void>\n\t): {\n\t\tmethod: 'POST';\n\t\taction: string;\n\t\t[attachment: symbol]: (node: HTMLFormElement) => void;\n\t};\n\t/**\n\t * Create an instance of the form for the given `id`.\n\t * The `id` is stringified and used for deduplication to potentially reuse existing instances.\n\t * Useful when you have multiple forms that use the same remote form action, for example in a loop.\n\t * ```svelte\n\t * {#each todos as todo}\n\t *\t{@const todoForm = updateTodo.for(todo.id)}\n\t *\t<form {...todoForm}>\n\t *\t\t{#if todoForm.result?.invalid}<p>Invalid data</p>{/if}\n\t *\t\t...\n\t *\t</form>\n\t *\t{/each}\n\t * ```\n\t */\n\tfor(\n\t\tid: ExtractId<Input>\n\t): Omit<RemoteForm<Input, Output>, 'for'>;\n\t/** Preflight checks */\n\tpreflight(\n\t\tschema: StandardSchemaV1<Input, any>\n\t): RemoteForm<Input, Output>;\n\t/** Validate the form contents programmatically */\n\tvalidate(options?: {\n\t\t/** Set this to `true` to also show validation issues of fields that haven't been touched yet. */\n\t\tincludeUntouched?: boolean;\n\t\t/** Set this to `true` to only run the `preflight` validation. */\n\t\tpreflightOnly?: boolean;\n\t}): Promise<void>;\n\t/** The result of the form submission */\n\tget result(): Output | undefined;\n\t/** The number of pending submissions */\n\tget pending(): number;\n\t/** Access form fields using object notation */\n\tfields: RemoteFormFieldsRoot<Input>;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormField"],"href":"/docs/kit/@sveltejs-kit#RemoteFormField","content":"Form field accessor type that provides name(), value(), and issues() methods\ntype RemoteFormField<Value extends RemoteFormFieldValue> =\n\tRemoteFormFieldMethods<Value> & {\n\t\t/**\n\t\t * Returns an object that can be spread onto an input element with the correct type attribute,\n\t\t * aria-invalid attribute if the field is invalid, and appropriate value/checked property getters/setters.\n\t\t * @example\n\t\t * ```svelte\n\t\t * <input {...myForm.fields.myString.as('text')} />\n\t\t * <input {...myForm.fields.myNumber.as('number')} />\n\t\t * <input {...myForm.fields.myBoolean.as('checkbox')} />\n\t\t * ```\n\t\t */\n\t\tas<T extends RemoteFormFieldType<Value>>(\n\t\t\t...args: AsArgs<T, Value>\n\t\t): InputElementProps<T>;\n\t};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormFieldType"],"href":"/docs/kit/@sveltejs-kit#RemoteFormFieldType","content":"type RemoteFormFieldType<T> = {\n\t[K in keyof InputTypeMap]: T extends InputTypeMap[K]\n\t\t? K\n\t\t: never;\n}[keyof InputTypeMap];","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormFieldValue"],"href":"/docs/kit/@sveltejs-kit#RemoteFormFieldValue","content":"type RemoteFormFieldValue =\n\t| string\n\t| string[]\n\t| number\n\t| boolean\n\t| File\n\t| File[];","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormFields"],"href":"/docs/kit/@sveltejs-kit#RemoteFormFields","content":"Recursive type to build form fields structure with proxy access\ntype RemoteFormFields<T> =\n\tWillRecurseIndefinitely<T> extends true\n\t\t? RecursiveFormFields\n\t\t: NonNullable<T> extends\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| boolean\n\t\t\t\t\t| File\n\t\t\t? RemoteFormField<NonNullable<T>>\n\t\t\t: // [NonNullable<T>] is used to prevent distributing over union while still allowing\n\t\t\t\t// nullable wrappers (e.g. `string[] | undefined` from a schema with `.default([])`)\n\t\t\t\t// to be treated as arrays; only the last condition should distribute over unions\n\t\t\t\t[NonNullable<T>] extends [string[] | File[]]\n\t\t\t\t? RemoteFormField<NonNullable<T>> & {\n\t\t\t\t\t\t[K in number]: RemoteFormField<\n\t\t\t\t\t\t\tNonNullable<T>[number]\n\t\t\t\t\t\t>;\n\t\t\t\t\t}\n\t\t\t\t: [NonNullable<T>] extends [Array<infer U>]\n\t\t\t\t\t? RemoteFormFieldContainer<NonNullable<T>> & {\n\t\t\t\t\t\t\t[K in number]: RemoteFormFields<U>;\n\t\t\t\t\t\t}\n\t\t\t\t\t: RemoteFormFieldContainer<T> & {\n\t\t\t\t\t\t\t[K in KeysOfUnion<T>]-?: RemoteFormFields<\n\t\t\t\t\t\t\t\tValueOfUnionKey<T, K>\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormInput"],"href":"/docs/kit/@sveltejs-kit#RemoteFormInput","content":"interface RemoteFormInput {/*…*/}\n[key: string]: MaybeArray<string | number | boolean | File | RemoteFormInput>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteFormIssue"],"href":"/docs/kit/@sveltejs-kit#RemoteFormIssue","content":"interface RemoteFormIssue {/*…*/}\nmessage: string;\n\npath: Array<string | number>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteLiveQuery"],"href":"/docs/kit/@sveltejs-kit#RemoteLiveQuery","content":"type RemoteLiveQuery<T> = RemoteResource<T> &\n\tAsyncIterable<T> & {\n\t\t/** `true` if the live stream is currently connected. */\n\t\treadonly connected: boolean;\n\t\t/** `true` once the current live stream iterator is done. */\n\t\treadonly done: boolean;\n\t\t/** Reconnects the live stream immediately. */\n\t\treconnect(): Promise<void>;\n\t};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteLiveQueryFunction"],"href":"/docs/kit/@sveltejs-kit#RemoteLiveQueryFunction","content":"The type of a remote query.live function. See Remote functions for full documentation.The optional Validated generic parameter represents the argument type after the\nquery's schema has validated and (optionally) transformed it, and matches the type\nyielded by `requested`.\ntype RemoteLiveQueryFunction<\n\tInput,\n\tOutput,\n\t_Validated = Input\n> = (\n\targ: undefined extends Input ? Input | void : Input\n) => RemoteLiveQuery<Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemotePrerenderFunction"],"href":"/docs/kit/@sveltejs-kit#RemotePrerenderFunction","content":"The type of a remote prerender function. See Remote functions for full documentation.\ntype RemotePrerenderFunction<Input, Output> = (\n\targ: undefined extends Input ? Input | void : Input\n) => RemoteResource<Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteQuery"],"href":"/docs/kit/@sveltejs-kit#RemoteQuery","content":"type RemoteQuery<T> = RemoteResource<T> & {\n\t/**\n\t * On the client, this function will update the value of the query without re-fetching it.\n\t *\n\t * On the server, this can be called in the context of a `command` or `form` and the specified data will accompany the action response back to the client.\n\t * This prevents SvelteKit needing to refresh all queries on the page in a second server round-trip.\n\t */\n\tset(value: T): void;\n\t/**\n\t * On the client, this function will re-fetch the query from the server.\n\t *\n\t * On the server, this can be called in the context of a `command` or `form` and the refreshed data will accompany the action response back to the client.\n\t * This prevents SvelteKit needing to refresh all queries on the page in a second server round-trip.\n\t */\n\trefresh(): Promise<void>;\n\t/**\n\t * Temporarily override a query's value during a [single-flight mutation](https://svelte.dev/docs/kit/remote-functions#Single-flight-mutations) to provide optimistic updates.\n\t *\n\t * ```svelte\n\t * <script>\n\t *   import { getTodos, addTodo } from './todos.remote.js';\n\t *   const todos = getTodos();\n\t * </script>\n\t *\n\t * <form {...addTodo.enhance(async (form) => {\n\t *   await form.submit().updates(\n\t *     todos.withOverride((todos) => [...todos, { text: form.fields.text.value() }])\n\t *   );\n\t * })}>\n\t *   <input type=\"text\" name=\"text\" />\n\t *   <button type=\"submit\">Add Todo</button>\n\t * </form>\n\t * ```\n\t */\n\twithOverride(\n\t\tupdate: (current: T) => T\n\t): RemoteQueryOverride;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteQueryFunction"],"href":"/docs/kit/@sveltejs-kit#RemoteQueryFunction","content":"The return value of a remote query function. See Remote functions for full documentation.The optional Validated generic parameter represents the argument type after the\nquery's schema has validated and (optionally) transformed it — this is the type the\nquery's implementation function receives on the server, and the type yielded by\n`requested`. For queries declared\nwith Standard Schema it differs from Input when the\nschema contains a transform (e.g. v.pipe(v.number(), v.transform(String)) has\nInput = number but Validated = string). For 'unchecked' validators and queries\nwithout arguments it defaults to Input.\ntype RemoteQueryFunction<\n\tInput,\n\tOutput,\n\t_Validated = Input\n> = (\n\targ: undefined extends Input ? Input | void : Input\n) => RemoteQuery<Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteQueryOverride"],"href":"/docs/kit/@sveltejs-kit#RemoteQueryOverride","content":"type RemoteQueryOverride = () => void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteQueryUpdate"],"href":"/docs/kit/@sveltejs-kit#RemoteQueryUpdate","content":"type RemoteQueryUpdate =\n\t| RemoteQuery<any>\n\t| RemoteLiveQuery<any>\n\t| RemoteQueryFunction<any, any>\n\t| RemoteLiveQueryFunction<any, any>\n\t| RemoteQueryOverride;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RemoteResource"],"href":"/docs/kit/@sveltejs-kit#RemoteResource","content":"type RemoteResource<T> = Promise<T> & {\n\t/** The error in case the query fails. Most often this is a [`HttpError`](https://svelte.dev/docs/kit/@sveltejs-kit#HttpError) but it isn't guaranteed to be. */\n\tget error(): any;\n\t/** `true` before the first result is available and during refreshes */\n\tget loading(): boolean;\n} & (\n\t\t| {\n\t\t\t\t/** The current value of the query. Undefined until `ready` is `true` */\n\t\t\t\tget current(): undefined;\n\t\t\t\tready: false;\n\t\t  }\n\t\t| {\n\t\t\t\t/** The current value of the query. Undefined until `ready` is `true` */\n\t\t\t\tget current(): T;\n\t\t\t\tready: true;\n\t\t  }\n\t);","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RequestEvent"],"href":"/docs/kit/@sveltejs-kit#RequestEvent","content":"interface RequestEvent<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> {/*…*/}\ncookies: Cookies;\nGet or set cookies related to the current request\n\nfetch: typeof fetch;\nfetch is equivalent to the native `fetch` web API, with a few additional features:It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.\nIt can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).\nInternal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.\nDuring server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](/docs/kit/hooks#Server-hooks-handle)\nDuring hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.You can learn more about making credentialed requests with cookies here.\n\ngetClientAddress: () => string;\nThe client's IP address, set by the adapter.\n\nlocals: App.Locals;\nContains custom data that was added to the request within the `server handle hook`.\n\nparams: Params;\nThe parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.\n\nplatform: Readonly<App.Platform> | undefined;\nAdditional data made available through the adapter.\n\nrequest: Request;\nThe original request object.\n\nroute: {/*…*/}\nInfo about the current route.\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]. It is null when no route is matched.\n\n\nsetHeaders: (headers: Record<string, string>) => void;\nIf you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example: \n \nexport async function load({ fetch, setHeaders }) {\n\tconst url = `https://cms.example.com/articles.json`;\n\tconst response = await fetch(url);\n\n\tsetHeaders({\n\t\tage: response.headers.get('age'),\n\t\t'cache-control': response.headers.get('cache-control')\n\t});\n\n\treturn response.json();\n}Setting the same header multiple times (even in separate load functions) is an error — you can only set a given header once.You cannot add a set-cookie header with setHeaders — use the `cookies` API instead.\n\nurl: URL;\nThe requested URL.\n\nisDataRequest: boolean;\ntrue if the request comes from the client asking for +page/layout.server.js data. The url property will be stripped of the internal information\nrelated to the data request in this case. Use this property instead if the distinction is important to you.\n\nisSubRequest: boolean;\ntrue for +server.js calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin fetch requests on the server.\n\ntracing: {/*…*/}\n\n<span class=\"tag since\">available since</span> v2.31.0\nAccess to spans for tracing. If tracing is not enabled, these spans will do nothing.\nenabled: boolean;\nWhether tracing is enabled.\nroot: Span;\nThe root span for the request. This span is named sveltekit.handle.root.\ncurrent: Span;\nThe span associated with the current handle hook, load function, or form action.\n\n\nisRemoteRequest: boolean;\ntrue if the request comes from the client via a remote function. The url property will be stripped of the internal information\nrelated to the data request in this case. Use this property instead if the distinction is important to you.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RequestHandler"],"href":"/docs/kit/@sveltejs-kit#RequestHandler","content":"A (event: RequestEvent) => Response function exported from a +server.js file that corresponds to an HTTP verb (GET, PUT, PATCH, etc) and handles requests with that method.It receives Params as the first generic argument, which you can skip by using generated types instead.\ntype RequestHandler<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> = (\n\tevent: RequestEvent<Params, RouteId>\n) => MaybePromise<Response>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RequestedEntry"],"href":"/docs/kit/@sveltejs-kit#RequestedEntry","content":"A single entry yielded by `requested`\nwhen called with a regular query. arg is the validated argument (the input after\nthe query's schema validated and transformed it, if applicable); query is a\nRemoteQuery bound to the client's original cache key, so refresh() / set() will\nupdate the correct client entry.\ntype RequestedEntry<Validated, Output> = {\n\targ: Validated;\n\tquery: RemoteQuery<Output>;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RequestedResult"],"href":"/docs/kit/@sveltejs-kit#RequestedResult","content":"type RequestedResult<Validated, Output> =\n\t| QueryRequestedResult<Validated, Output>\n\t| LiveQueryRequestedResult<Validated, Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Reroute"],"href":"/docs/kit/@sveltejs-kit#Reroute","content":"Available since 2.3.0\nThe `reroute` hook allows you to modify the URL before it is used to determine which route to render.\ntype Reroute = (event: {\n\turl: URL;\n\tfetch: typeof fetch;\n}) => MaybePromise<void | string>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ResolveOptions"],"href":"/docs/kit/@sveltejs-kit#ResolveOptions","content":"interface ResolveOptions {/*…*/}\ntransformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise<string | undefined>;\n\n`input` the html chunk and the info if this is the last chunk\nApplies custom transforms to HTML. If done is true, it's the final chunk. Chunks are not guaranteed to be well-formed HTML\n(they could include an element's opening tag but not its closing tag, for example)\nbut they will always be split at sensible boundaries such as %sveltekit.head% or layout/page components.\n\nfilterSerializedResponseHeaders?: (name: string, value: string) => boolean;\n\n`name` header name\n`value` header value\nDetermines which headers should be included in serialized responses when a load function loads a resource with fetch.\nBy default, none will be included.\n\npreload?: (input: { type: 'font' | 'css' | 'js' | 'asset'; path: string }) => boolean;\n\n`input` the type of the file and its path\nDetermines what should be added to the <head> tag to preload it.\nBy default, js and css files will be preloaded.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RouteDefinition"],"href":"/docs/kit/@sveltejs-kit#RouteDefinition","content":"interface RouteDefinition<Config = any> {/*…*/}\nid: string;\n\napi: {\n\tmethods: Array<HttpMethod | '*'>;\n};\n\npage: {\n\tmethods: Array<Extract<HttpMethod, 'GET' | 'POST'>>;\n};\n\npattern: RegExp;\n\nprerender: PrerenderOption;\n\nsegments: RouteSegment[];\n\nmethods: Array<HttpMethod | '*'>;\n\nconfig: Config;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","SSRManifest"],"href":"/docs/kit/@sveltejs-kit#SSRManifest","content":"interface SSRManifest {/*…*/}\nappDir: string;\n\nappPath: string;\n\nassets: Set<string>;\nStatic files from kit.config.files.assets and the service worker (if any).\n\nmimeTypes: Record<string, string>;\n\n_: {/*…*/}\nprivate fields\nclient: BuildData['client'];\nnodes: SSRNodeLoader[];\nremotes: Record<string, () => Promise<any>>;\nhashed filename -> import to that file\nroutes: SSRRoute[];\nprerendered_routes: Set<string>;\nmatchers: () => Promise<Record<string, ParamMatcher>>;\nserver_assets: Record<string, number>;\nA [file]: size map of all assets imported by server code.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ServerInit"],"href":"/docs/kit/@sveltejs-kit#ServerInit","content":"Available since 2.10.0\nThe `init` will be invoked before the server responds to its first request\ntype ServerInit = () => MaybePromise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ServerInitOptions"],"href":"/docs/kit/@sveltejs-kit#ServerInitOptions","content":"interface ServerInitOptions {/*…*/}\nenv: Record<string, string>;\nA map of environment variables.\n\nread?: (file: string) => MaybePromise<ReadableStream | null>;\nA function that turns an asset filename into a ReadableStream. Required for the read export from $app/server to work.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ServerLoad"],"href":"/docs/kit/@sveltejs-kit#ServerLoad","content":"The generic form of PageServerLoad and LayoutServerLoad. You should import those from ./$types (see generated types)\nrather than using ServerLoad directly.\ntype ServerLoad<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tParentData extends Record<string, any> = Record<\n\t\tstring,\n\t\tany\n\t>,\n\tOutputData extends Record<string, any> | void = Record<\n\t\tstring,\n\t\tany\n\t> | void,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> = (\n\tevent: ServerLoadEvent<Params, ParentData, RouteId>\n) => MaybePromise<OutputData>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ServerLoadEvent"],"href":"/docs/kit/@sveltejs-kit#ServerLoadEvent","content":"interface ServerLoadEvent<\n\tParams extends AppLayoutParams<'/'> =\n\t\tAppLayoutParams<'/'>,\n\tParentData extends Record<string, any> = Record<\n\t\tstring,\n\t\tany\n\t>,\n\tRouteId extends AppRouteId | null = AppRouteId | null\n> extends RequestEvent<Params, RouteId> {/*…*/}\nparent: () => Promise<ParentData>;\nawait parent() returns data from parent +layout.server.js load functions.Be careful not to introduce accidental waterfalls when using await parent(). If for example you only want to merge parent data into the returned output, call it after fetching your other data.\n\ndepends: (...deps: string[]) => void;\nThis function declares that the load function has a dependency on one or more URLs or custom identifiers, which can subsequently be used with `invalidate()` to cause load to rerun.Most of the time you won't need this, as fetch calls depends on your behalf — it's only necessary if you're using a custom API client that bypasses fetch.URLs can be absolute or relative to the page being loaded, and must be encoded.Custom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the URI specification.The following example shows how to use depends to register a dependency on a custom identifier, which is invalidated after a button click, making the load function rerun. \n \nlet count = 0;\nexport async function load({ depends }) {\n\tdepends('increase:count');\n\n\treturn { count: count++ };\n} \n<script>\n\timport { invalidate } from '$app/navigation';\n\n\tlet { data } = $props();\n\n\tconst increase = async () => {\n\t\tawait invalidate('increase:count');\n\t}\n</script>\n\n<p>{data.count}<p>\n<button on:click={increase}>Increase Count</button>\n\nuntrack: <T>(fn: () => T) => T;\nUse this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: \n \nexport async function load({ untrack, url }) {\n\t// Untrack url.pathname so that path changes don't trigger a rerun\n\tif (untrack(() => url.pathname === '/')) {\n\t\treturn { message: 'Welcome!' };\n\t}\n}\n\ntracing: {/*…*/}\n\n<span class=\"tag since\">available since</span> v2.31.0\nAccess to spans for tracing. If tracing is not enabled, these spans will do nothing.\nenabled: boolean;\nWhether tracing is enabled.\nroot: Span;\nThe root span for the request. This span is named sveltekit.handle.root.\ncurrent: Span;\nThe span associated with the current server load function.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Snapshot"],"href":"/docs/kit/@sveltejs-kit#Snapshot","content":"The type of export const snapshot exported from a page or layout component.\ninterface Snapshot<T = any> {/*…*/}\ncapture: () => T;\n\nrestore: (snapshot: T) => void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","SubmitFunction"],"href":"/docs/kit/@sveltejs-kit#SubmitFunction","content":"type SubmitFunction<\n\tSuccess extends Record<string, unknown> | undefined =\n\t\tRecord<string, any>,\n\tFailure extends Record<string, unknown> | undefined =\n\t\tRecord<string, any>\n> = (input: {\n\taction: URL;\n\tformData: FormData;\n\tformElement: HTMLFormElement;\n\tcontroller: AbortController;\n\tsubmitter: HTMLElement | null;\n\tcancel: () => void;\n}) => MaybePromise<\n\t| void\n\t| ((opts: {\n\t\t\tformData: FormData;\n\t\t\tformElement: HTMLFormElement;\n\t\t\taction: URL;\n\t\t\tresult: ActionResult<Success, Failure>;\n\t\t\t/**\n\t\t\t * Call this to get the default behavior of a form submission response.\n\t\t\t * @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission.\n\t\t\t * @param invalidateAll Set `invalidateAll: false` if you don't want the action to call `invalidateAll` after submission.\n\t\t\t */\n\t\t\tupdate: (options?: {\n\t\t\t\treset?: boolean;\n\t\t\t\tinvalidateAll?: boolean;\n\t\t\t}) => Promise<void>;\n\t  }) => MaybePromise<void>)\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Transport"],"href":"/docs/kit/@sveltejs-kit#Transport","content":"Available since 2.11.0\nThe `transport` hook allows you to transport custom types across the server/client boundary.Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).In the browser, decode turns the encoding back into an instance of the custom type.import type { Transport } from '@sveltejs/kit';\n\ndeclare class MyCustomType {\n\tdata: any\n}\n\n// hooks.js\nexport const transport: Transport = {\n\tMyCustomType: {\n\t\tencode: (value) => value instanceof MyCustomType && [value.data],\n\t\tdecode: ([data]) => new MyCustomType(data)\n\t}\n};\ntype Transport = Record<string, Transporter>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Transporter"],"href":"/docs/kit/@sveltejs-kit#Transporter","content":"A member of the `transport` hook.\ninterface Transporter<\n\tT = any,\n\tU = Exclude<\n\t\tany,\n\t\tfalse | 0 | '' | null | undefined | typeof NaN\n\t>\n> {/*…*/}\nencode: (value: T) => false | U;\n\ndecode: (data: U) => T;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","ValidationError"],"href":"/docs/kit/@sveltejs-kit#ValidationError","content":"A validation error thrown by invalid.\ninterface ValidationError {/*…*/}\nissues: StandardSchemaV1.Issue[];\nThe validation issues","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Private types"],"href":"/docs/kit/@sveltejs-kit#Private-types","content":"The following are referenced by the public types documented above, but cannot be imported directly:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","AdapterEntry"],"href":"/docs/kit/@sveltejs-kit#AdapterEntry","content":"interface AdapterEntry {/*…*/}\nid: string;\nA string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication.\nFor example, /foo/a-[b] and /foo/[c] are different routes, but would both\nbe represented in a Netlify _redirects file as /foo/:param, so they share an ID\n\nfilter(route: RouteDefinition): boolean;\nA function that compares the candidate route with the current route to determine\nif it should be grouped with the current route.Use cases:Fallback pages: `/foo/[c]` is a fallback for `/foo/a-[b]`, and `/[...catchall]` is a fallback for all routes\nGrouping routes that share a common `config`: `/foo` should be deployed to the edge, `/bar` and `/baz` should be deployed to a serverless function\n\ncomplete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise<void>;\nA function that is invoked once the entry has been created. This is where you\nshould write the function to the filesystem and generate redirect manifests.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Csp"],"href":"/docs/kit/@sveltejs-kit#Csp","content":"namespace Csp {\n\ttype ActionSource = 'strict-dynamic' | 'report-sample';\n\ttype BaseSource =\n\t\t| 'self'\n\t\t| 'unsafe-eval'\n\t\t| 'unsafe-hashes'\n\t\t| 'unsafe-inline'\n\t\t| 'wasm-unsafe-eval'\n\t\t| 'none';\n\ttype CryptoSource =\n\t\t`${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;\n\ttype FrameSource =\n\t\t| HostSource\n\t\t| SchemeSource\n\t\t| 'self'\n\t\t| 'none';\n\ttype HostNameScheme = `${string}.${string}` | 'localhost';\n\ttype HostSource =\n\t\t`${HostProtocolSchemes}${HostNameScheme}${PortScheme}`;\n\ttype HostProtocolSchemes = `${string}://` | '';\n\ttype HttpDelineator = '/' | '?' | '#' | '\\\\';\n\ttype PortScheme = `:${number}` | '' | ':*';\n\ttype SchemeSource =\n\t\t| 'http:'\n\t\t| 'https:'\n\t\t| 'data:'\n\t\t| 'mediastream:'\n\t\t| 'blob:'\n\t\t| 'filesystem:';\n\ttype Source =\n\t\t| HostSource\n\t\t| SchemeSource\n\t\t| CryptoSource\n\t\t| BaseSource;\n\ttype Sources = Source[];\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","CspDirectives"],"href":"/docs/kit/@sveltejs-kit#CspDirectives","content":"interface CspDirectives {/*…*/}\n'child-src'?: Csp.Sources;\n\n'default-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n'frame-src'?: Csp.Sources;\n\n'worker-src'?: Csp.Sources;\n\n'connect-src'?: Csp.Sources;\n\n'font-src'?: Csp.Sources;\n\n'img-src'?: Csp.Sources;\n\n'manifest-src'?: Csp.Sources;\n\n'media-src'?: Csp.Sources;\n\n'object-src'?: Csp.Sources;\n\n'prefetch-src'?: Csp.Sources;\n\n'script-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n'script-src-elem'?: Csp.Sources;\n\n'script-src-attr'?: Csp.Sources;\n\n'style-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n'style-src-elem'?: Csp.Sources;\n\n'style-src-attr'?: Csp.Sources;\n\n'base-uri'?: Array<Csp.Source | Csp.ActionSource>;\n\nsandbox?: Array<\n| 'allow-downloads-without-user-activation'\n| 'allow-forms'\n| 'allow-modals'\n| 'allow-orientation-lock'\n| 'allow-pointer-lock'\n| 'allow-popups'\n| 'allow-popups-to-escape-sandbox'\n| 'allow-presentation'\n| 'allow-same-origin'\n| 'allow-scripts'\n| 'allow-storage-access-by-user-activation'\n| 'allow-top-navigation'\n| 'allow-top-navigation-by-user-activation'\n>;\n\n'form-action'?: Array<Csp.Source | Csp.ActionSource>;\n\n'frame-ancestors'?: Array<Csp.HostSource | Csp.SchemeSource | Csp.FrameSource>;\n\n'navigate-to'?: Array<Csp.Source | Csp.ActionSource>;\n\n'report-uri'?: string[];\n\n'report-to'?: string[];\n\n'require-trusted-types-for'?: Array<'script'>;\n\n'trusted-types'?: Array<'none' | 'allow-duplicates' | '*' | string>;\n\n'upgrade-insecure-requests'?: boolean;\n\n'require-sri-for'?: Array<'script' | 'style' | 'script style'>;\n\n<span class=\"tag deprecated\">deprecated</span>\n\n\n'block-all-mixed-content'?: boolean;\n\n<span class=\"tag deprecated\">deprecated</span>\n\n\n'plugin-types'?: Array<`${string}/${string}` | 'none'>;\n\n<span class=\"tag deprecated\">deprecated</span>\n\n\nreferrer?: Array<\n| 'no-referrer'\n| 'no-referrer-when-downgrade'\n| 'origin'\n| 'origin-when-cross-origin'\n| 'same-origin'\n| 'strict-origin'\n| 'strict-origin-when-cross-origin'\n| 'unsafe-url'\n| 'none'\n>;\n\n<span class=\"tag deprecated\">deprecated</span>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","DeepPartial"],"href":"/docs/kit/@sveltejs-kit#DeepPartial","content":"type DeepPartial<T> = T extends\n\t| Record<PropertyKey, unknown>\n\t| unknown[]\n\t? {\n\t\t\t[K in keyof T]?: T[K] extends\n\t\t\t\t| Record<PropertyKey, unknown>\n\t\t\t\t| unknown[]\n\t\t\t\t? DeepPartial<T[K]>\n\t\t\t\t: T[K];\n\t\t}\n\t: T | undefined;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","HttpMethod"],"href":"/docs/kit/@sveltejs-kit#HttpMethod","content":"type HttpMethod =\n\t| 'GET'\n\t| 'HEAD'\n\t| 'POST'\n\t| 'PUT'\n\t| 'DELETE'\n\t| 'PATCH'\n\t| 'OPTIONS';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","IsAny"],"href":"/docs/kit/@sveltejs-kit#IsAny","content":"type IsAny<T> = 0 extends 1 & T ? true : false;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Logger"],"href":"/docs/kit/@sveltejs-kit#Logger","content":"interface Logger {/*…*/}\n(msg: string): void;\n\nsuccess(msg: string): void;\n\nerror(msg: string): void;\n\nwarn(msg: string): void;\n\nminor(msg: string): void;\n\ninfo(msg: string): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","MaybePromise"],"href":"/docs/kit/@sveltejs-kit#MaybePromise","content":"type MaybePromise<T> = T | Promise<T>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderEntryGeneratorMismatchHandler"],"href":"/docs/kit/@sveltejs-kit#PrerenderEntryGeneratorMismatchHandler","content":"interface PrerenderEntryGeneratorMismatchHandler {/*…*/}\n(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderEntryGeneratorMismatchHandlerValue"],"href":"/docs/kit/@sveltejs-kit#PrerenderEntryGeneratorMismatchHandlerValue","content":"type PrerenderEntryGeneratorMismatchHandlerValue =\n\t| 'fail'\n\t| 'warn'\n\t| 'ignore'\n\t| PrerenderEntryGeneratorMismatchHandler;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderHttpErrorHandler"],"href":"/docs/kit/@sveltejs-kit#PrerenderHttpErrorHandler","content":"interface PrerenderHttpErrorHandler {/*…*/}\n(details: {\nstatus: number;\npath: string;\nreferrer: string | null;\nreferenceType: 'linked' | 'fetched';\nmessage: string;\n}): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderHttpErrorHandlerValue"],"href":"/docs/kit/@sveltejs-kit#PrerenderHttpErrorHandlerValue","content":"type PrerenderHttpErrorHandlerValue =\n\t| 'fail'\n\t| 'warn'\n\t| 'ignore'\n\t| PrerenderHttpErrorHandler;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderMap"],"href":"/docs/kit/@sveltejs-kit#PrerenderMap","content":"type PrerenderMap = Map<string, PrerenderOption>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderMissingIdHandler"],"href":"/docs/kit/@sveltejs-kit#PrerenderMissingIdHandler","content":"interface PrerenderMissingIdHandler {/*…*/}\n(details: { path: string; id: string; referrers: string[]; message: string }): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderMissingIdHandlerValue"],"href":"/docs/kit/@sveltejs-kit#PrerenderMissingIdHandlerValue","content":"type PrerenderMissingIdHandlerValue =\n\t| 'fail'\n\t| 'warn'\n\t| 'ignore'\n\t| PrerenderMissingIdHandler;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderOption"],"href":"/docs/kit/@sveltejs-kit#PrerenderOption","content":"type PrerenderOption = boolean | 'auto';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderUnseenRoutesHandler"],"href":"/docs/kit/@sveltejs-kit#PrerenderUnseenRoutesHandler","content":"interface PrerenderUnseenRoutesHandler {/*…*/}\n(details: { routes: string[]; message: string }): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","PrerenderUnseenRoutesHandlerValue"],"href":"/docs/kit/@sveltejs-kit#PrerenderUnseenRoutesHandlerValue","content":"type PrerenderUnseenRoutesHandlerValue =\n\t| 'fail'\n\t| 'warn'\n\t| 'ignore'\n\t| PrerenderUnseenRoutesHandler;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","Prerendered"],"href":"/docs/kit/@sveltejs-kit#Prerendered","content":"interface Prerendered {/*…*/}\npages: Map<\nstring,\n{\n\t/** The location of the .html file relative to the output directory */\n\tfile: string;\n}\n>;\nA map of path to { file } objects, where a path like /foo corresponds to foo.html and a path like /bar/ corresponds to bar/index.html.\n\nassets: Map<\nstring,\n{\n\t/** The MIME type of the asset */\n\ttype: string;\n}\n>;\nA map of path to { type } objects.\n\nredirects: Map<\nstring,\n{\n\tstatus: number;\n\tlocation: string;\n}\n>;\nA map of redirects encountered during prerendering.\n\npaths: string[];\nAn array of prerendered paths (without trailing slashes, regardless of the trailingSlash config)","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RequestOptions"],"href":"/docs/kit/@sveltejs-kit#RequestOptions","content":"interface RequestOptions {/*…*/}\ngetClientAddress(): string;\n\nplatform?: App.Platform;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","RouteSegment"],"href":"/docs/kit/@sveltejs-kit#RouteSegment","content":"interface RouteSegment {/*…*/}\ncontent: string;\n\ndynamic: boolean;\n\nrest: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit","TrailingSlash"],"href":"/docs/kit/@sveltejs-kit#TrailingSlash","content":"type TrailingSlash = 'never' | 'always' | 'ignore';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/hooks"],"href":"/docs/kit/@sveltejs-kit-hooks","content":"import { defineEnvVars, sequence } from '@sveltejs/kit/hooks';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/hooks","defineEnvVars"],"href":"/docs/kit/@sveltejs-kit-hooks#defineEnvVars","content":"Utility for defining environment variables,\nwhich are made available via $app/env/public and $app/env/private.\nfunction defineEnvVars<\n\tT extends Record<string, EnvVarConfig<any>>\n>(variables: T): T;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/hooks","sequence"],"href":"/docs/kit/@sveltejs-kit-hooks#sequence","content":"A helper function for sequencing multiple handle calls in a middleware-like manner.\nThe behavior for the handle options is as follows:`transformPageChunk` is applied in reverse order and merged\n`preload` is applied in forward order, the first option \"wins\" and no `preload` options after it are called\n`filterSerializedResponseHeaders` behaves the same as `preload` \n \nimport { sequence } from '@sveltejs/kit/hooks';\n\n/** @type {import('@sveltejs/kit').Handle} */\nasync function first({ event, resolve }) {\n\tconsole.log('first pre-processing');\n\tconst result = await resolve(event, {\n\t\ttransformPageChunk: ({ html }) => {\n\t\t\t// transforms are applied in reverse order\n\t\t\tconsole.log('first transform');\n\t\t\treturn html;\n\t\t},\n\t\tpreload: () => {\n\t\t\t// this one wins as it's the first defined in the chain\n\t\t\tconsole.log('first preload');\n\t\t\treturn true;\n\t\t}\n\t});\n\tconsole.log('first post-processing');\n\treturn result;\n}\n\n/** @type {import('@sveltejs/kit').Handle} */\nasync function second({ event, resolve }) {\n\tconsole.log('second pre-processing');\n\tconst result = await resolve(event, {\n\t\ttransformPageChunk: ({ html }) => {\n\t\t\tconsole.log('second transform');\n\t\t\treturn html;\n\t\t},\n\t\tpreload: () => {\n\t\t\tconsole.log('second preload');\n\t\t\treturn true;\n\t\t},\n\t\tfilterSerializedResponseHeaders: () => {\n\t\t\t// this one wins as it's the first defined in the chain\n\t\t\tconsole.log('second filterSerializedResponseHeaders');\n\t\t\treturn true;\n\t\t}\n\t});\n\tconsole.log('second post-processing');\n\treturn result;\n}\n\nexport const handle = sequence(first, second);The example above would print:first pre-processing\nfirst preload\nsecond pre-processing\nsecond filterSerializedResponseHeaders\nsecond transform\nfirst transform\nsecond post-processing\nfirst post-processing\nfunction sequence(...handlers: Handle[]): Handle;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node/polyfills"],"href":"/docs/kit/@sveltejs-kit-node-polyfills","content":"import { installPolyfills } from '@sveltejs/kit/node/polyfills';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node/polyfills","installPolyfills"],"href":"/docs/kit/@sveltejs-kit-node-polyfills#installPolyfills","content":"Make various web APIs available as globals:`crypto`\n`File`\nfunction installPolyfills(): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node"],"href":"/docs/kit/@sveltejs-kit-node","content":"import {\n\tcreateReadableStream,\n\tgetRequest,\n\tsetResponse\n} from '@sveltejs/kit/node';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node","createReadableStream"],"href":"/docs/kit/@sveltejs-kit-node#createReadableStream","content":"Available since 2.4.0\nConverts a file on disk to a readable stream\nfunction createReadableStream(file: string): ReadableStream;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node","getRequest"],"href":"/docs/kit/@sveltejs-kit-node#getRequest","content":"function getRequest({\n\trequest,\n\tbase,\n\tbodySizeLimit\n}: {\n\trequest: import('http').IncomingMessage;\n\tbase: string;\n\tbodySizeLimit?: number;\n}): Promise<Request>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/node","setResponse"],"href":"/docs/kit/@sveltejs-kit-node#setResponse","content":"function setResponse(\n\tres: import('http').ServerResponse,\n\tresponse: Response\n): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/vite"],"href":"/docs/kit/@sveltejs-kit-vite","content":"import { sveltekit } from '@sveltejs/kit/vite';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","@sveltejs/kit/vite","sveltekit"],"href":"/docs/kit/@sveltejs-kit-vite#sveltekit","content":"Returns the SvelteKit Vite plugins.\nSince version 2.62.0 you can pass configuration directly, in which case svelte.config.js is ignored.\nfunction sveltekit(\n\tconfig?: KitConfig & Omit<SvelteConfig, 'onwarn'>\n): Promise<Plugin[]>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env"],"href":"/docs/kit/$app-env","content":"[!NOTE] This is an alias of [`$app/environment`]($app-environment), used when [explicit environment variables](environment-variables#Explicit-environment-variables) are enabled. \nimport { browser, building, dev, version } from '$app/env';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env","browser"],"href":"/docs/kit/$app-env#browser","content":"true if the app is running in the browser.\nconst browser: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env","building"],"href":"/docs/kit/$app-env#building","content":"SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.\nconst building: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env","dev"],"href":"/docs/kit/$app-env#dev","content":"Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.\nconst dev: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env","version"],"href":"/docs/kit/$app-env#version","content":"The value of config.kit.version.name.\nconst version: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env/private"],"href":"/docs/kit/$app-env-private","content":"Private environment variables defined in src/env.ts (or src/env.js).To use this module, you must enable the experimental.explicitEnvironmentVariables flag in your project configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/env/public"],"href":"/docs/kit/$app-env-public","content":"Public environment variables defined in src/env.ts (or src/env.js).To use this module, you must enable the experimental.explicitEnvironmentVariables flag in your project configuration.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/environment"],"href":"/docs/kit/$app-environment","content":"import { browser, building, dev, version } from '$app/environment';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/environment","browser"],"href":"/docs/kit/$app-environment#browser","content":"true if the app is running in the browser.\nconst browser: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/environment","building"],"href":"/docs/kit/$app-environment#building","content":"SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.\nconst building: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/environment","dev"],"href":"/docs/kit/$app-environment#dev","content":"Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.\nconst dev: boolean;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/environment","version"],"href":"/docs/kit/$app-environment#version","content":"The value of config.kit.version.name.\nconst version: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/forms"],"href":"/docs/kit/$app-forms","content":"import { applyAction, deserialize, enhance } from '$app/forms';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/forms","applyAction"],"href":"/docs/kit/$app-forms#applyAction","content":"This action updates the form property of the current page with the given data and updates page.status.\nIn case of an error, it redirects to the nearest error page.\nfunction applyAction<\n\tSuccess extends Record<string, unknown> | undefined,\n\tFailure extends Record<string, unknown> | undefined\n>(\n\tresult: import('@sveltejs/kit').ActionResult<\n\t\tSuccess,\n\t\tFailure\n\t>\n): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/forms","deserialize"],"href":"/docs/kit/$app-forms#deserialize","content":"Use this function to deserialize the response from a form submission.\nUsage: \nimport { deserialize } from '$app/forms';\n\nasync function handleSubmit(event) {\n\tconst response = await fetch('/form?/action', {\n\t\tmethod: 'POST',\n\t\tbody: new FormData(event.target)\n\t});\n\n\tconst result = deserialize(await response.text());\n\t// ...\n}\nfunction deserialize<\n\tSuccess extends Record<string, unknown> | undefined,\n\tFailure extends Record<string, unknown> | undefined\n>(\n\tresult: string\n): import('@sveltejs/kit').ActionResult<Success, Failure>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/forms","enhance"],"href":"/docs/kit/$app-forms#enhance","content":"This action enhances a <form> element that otherwise would work without JavaScript.The submit function is called upon submission with the given FormData and the action that should be triggered.\nIf cancel is called, the form will not be submitted.\nYou can use the abort controller to cancel the submission in case another one starts.\nIf a function is returned, that function is called with the response from the server.\nIf nothing is returned, the fallback will be used.If this function or its return value isn't set, itfalls back to updating the `form` prop with the returned data if the action is on the same page as the form\nupdates `page.status`\nresets the `<form>` element and invalidates all data in case of successful submission with no redirect response\nredirects in case of a redirect response\nredirects to the nearest error page in case of an unexpected errorIf you provide a custom function with a callback and want to use the default behavior, invoke update in your callback.\nIt accepts an options object`reset: false` if you don't want the `<form>` values to be reset after a successful submission\n`invalidateAll: false` if you don't want the action to call `invalidateAll` after submission\nfunction enhance<\n\tSuccess extends Record<string, unknown> | undefined,\n\tFailure extends Record<string, unknown> | undefined\n>(\n\tform_element: HTMLFormElement,\n\tsubmit?: import('@sveltejs/kit').SubmitFunction<\n\t\tSuccess,\n\t\tFailure\n\t>\n): {\n\tdestroy(): void;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation"],"href":"/docs/kit/$app-navigation","content":"import {\n\tafterNavigate,\n\tbeforeNavigate,\n\tdisableScrollHandling,\n\tgoto,\n\tinvalidate,\n\tinvalidateAll,\n\tonNavigate,\n\tpreloadCode,\n\tpreloadData,\n\tpushState,\n\trefreshAll,\n\treplaceState\n} from '$app/navigation';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","afterNavigate"],"href":"/docs/kit/$app-navigation#afterNavigate","content":"A lifecycle function that runs the supplied callback when the current component mounts, and also whenever we navigate to a URL.afterNavigate must be called during a component initialization. It remains active as long as the component is mounted.\nfunction afterNavigate(\n\tcallback: (\n\t\tnavigation: import('@sveltejs/kit').AfterNavigate\n\t) => void\n): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","beforeNavigate"],"href":"/docs/kit/$app-navigation#beforeNavigate","content":"A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling goto(...), or using the browser back/forward controls.Calling cancel() will prevent the navigation from completing. If navigation.type === 'leave' — meaning the user is navigating away from the app (or closing the tab) — calling cancel will trigger the native browser unload confirmation dialog. In this case, the navigation may or may not be cancelled depending on the user's response.When a navigation isn't to a SvelteKit-owned route (and therefore controlled by SvelteKit's client-side router), navigation.to.route.id will be null.If the navigation will (if not cancelled) cause the document to unload — in other words 'leave' navigations and 'link' navigations where navigation.to.route === null — navigation.willUnload is true.beforeNavigate must be called during a component initialization. It remains active as long as the component is mounted.\nfunction beforeNavigate(\n\tcallback: (\n\t\tnavigation: import('@sveltejs/kit').BeforeNavigate\n\t) => void\n): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","disableScrollHandling"],"href":"/docs/kit/$app-navigation#disableScrollHandling","content":"If called when the page is being updated following a navigation (in onMount or afterNavigate or an action, for example), this disables SvelteKit's built-in scroll handling.\nThis is generally discouraged, since it breaks user expectations.\nfunction disableScrollHandling(): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","goto"],"href":"/docs/kit/$app-navigation#goto","content":"Allows you to navigate programmatically to a given route, with options such as keeping the current element focused.\nReturns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified url.For external URLs, use window.location = url instead of calling goto(url).\nfunction goto(\n\turl: string | URL,\n\topts?: {\n\t\treplaceState?: boolean | undefined;\n\t\tnoScroll?: boolean | undefined;\n\t\tkeepFocus?: boolean | undefined;\n\t\tinvalidateAll?: boolean | undefined;\n\t\tinvalidate?:\n\t\t\t| (string | URL | ((url: URL) => boolean))[]\n\t\t\t| undefined;\n\t\tstate?: App.PageState | undefined;\n\t}\n): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","invalidate"],"href":"/docs/kit/$app-navigation#invalidate","content":"Causes any load functions belonging to the currently active page to re-run if they depend on the url in question, via fetch or depends. Returns a Promise that resolves when the page is subsequently updated.If the argument is given as a string or URL, it must resolve to the same URL that was passed to fetch or depends (including query parameters).\nTo create a custom identifier, use a string beginning with [a-z]+: (e.g. custom:state) — this is a valid URL.The function argument can be used define a custom predicate. It receives the full URL and causes load to rerun if true is returned.\nThis can be useful if you want to invalidate based on a pattern instead of a exact match.// Example: Match '/path' regardless of the query parameters\nimport { invalidate } from '$app/navigation';\n\ninvalidate((url) => url.pathname === '/path');\nfunction invalidate(\n\tresource: string | URL | ((url: URL) => boolean)\n): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","invalidateAll"],"href":"/docs/kit/$app-navigation#invalidateAll","content":"Causes all load and query functions belonging to the currently active page to re-run. Returns a Promise that resolves when the page is subsequently updated.\nfunction invalidateAll(): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","onNavigate"],"href":"/docs/kit/$app-navigation#onNavigate","content":"A lifecycle function that runs the supplied callback immediately before we navigate to a new URL except during full-page navigations.If you return a Promise, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use document.startViewTransition. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.If a function (or a Promise that resolves to a function) is returned from the callback, it will be called once the DOM has updated.onNavigate must be called during a component initialization. It remains active as long as the component is mounted.\nfunction onNavigate(\n\tcallback: (\n\t\tnavigation: import('@sveltejs/kit').OnNavigate\n\t) => MaybePromise<(() => void) | void>\n): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","preloadCode"],"href":"/docs/kit/$app-navigation#preloadCode","content":"Programmatically imports the code for routes that haven't yet been fetched.\nTypically, you might call this to speed up subsequent navigation.You can specify routes by any matching pathname such as /about (to match src/routes/about/+page.svelte) or /blog/* (to match src/routes/blog/[slug]/+page.svelte).Unlike preloadData, this won't call load functions.\nReturns a Promise that resolves when the modules have been imported.\nfunction preloadCode(pathname: string): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","preloadData"],"href":"/docs/kit/$app-navigation#preloadData","content":"Programmatically preloads the given page, which meansensuring that the code for the page is loaded, and\ncalling the page's load function with the appropriate options.This is the same behaviour that SvelteKit triggers when the user taps or mouses over an <a> element with data-sveltekit-preload-data.\nIf the next navigation is to href, the values returned from load will be used, making navigation instantaneous.\nReturns a Promise that resolves with the result of running the new route's load functions once the preload is complete.\nfunction preloadData(href: string): Promise<\n\t| {\n\t\t\ttype: 'loaded';\n\t\t\tstatus: number;\n\t\t\tdata: Record<string, any>;\n\t  }\n\t| {\n\t\t\ttype: 'redirect';\n\t\t\tlocation: string;\n\t  }\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","pushState"],"href":"/docs/kit/$app-navigation#pushState","content":"Programmatically create a new history entry with the given page.state. To use the current URL, you can pass '' as the first argument. Used for shallow routing.\nfunction pushState(\n\turl: string | URL,\n\tstate: App.PageState\n): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","refreshAll"],"href":"/docs/kit/$app-navigation#refreshAll","content":"Causes all currently active remote functions to refresh, and all load functions belonging to the currently active page to re-run (unless disabled via the option argument).\nReturns a Promise that resolves when the page is subsequently updated.\nfunction refreshAll({\n\tincludeLoadFunctions\n}?: {\n\tincludeLoadFunctions?: boolean;\n}): Promise<void>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/navigation","replaceState"],"href":"/docs/kit/$app-navigation#replaceState","content":"Programmatically replace the current history entry with the given page.state. To use the current URL, you can pass '' as the first argument. Used for shallow routing.\nfunction replaceState(\n\turl: string | URL,\n\tstate: App.PageState\n): void;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths"],"href":"/docs/kit/$app-paths","content":"import { asset, assets, base, match, resolve, resolveRoute } from '$app/paths';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","asset"],"href":"/docs/kit/$app-paths#asset","content":"Available since 2.26\nResolve the URL of an asset in your static directory, by prefixing it with `config.kit.paths.assets` if configured, or otherwise by prefixing it with the base path.During server rendering, the base path is relative and depends on the page currently being rendered.<script>\n\timport { asset } from '$app/paths';\n</script>\n\n<img alt=\"a potato\" src={asset('/potato.jpg')} />\nfunction asset(file: Asset): string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","assets"],"href":"/docs/kit/$app-paths#assets","content":"Use `asset(...)` instead\nAn absolute path that matches `config.kit.paths.assets`.[!NOTE] If a value for `config.kit.paths.assets` is specified, it will be replaced with `'/_svelte_kit_assets'` during `vite dev` or `vite preview`, since the assets don't yet live at their eventual URL.\nlet assets:\n\t| ''\n\t| `https://${string}`\n\t| `http://${string}`\n\t| '/_svelte_kit_assets';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","base"],"href":"/docs/kit/$app-paths#base","content":"Use `resolve(...)` instead\nA string that matches `config.kit.paths.base`.Example usage: <a href=\"{base}/your-page\">Link</a>\nlet base: '' | `/${string}`;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","match"],"href":"/docs/kit/$app-paths#match","content":"Available since 2.52.0\nMatch a path or URL to a route ID and extracts any parameters. \nimport { match } from '$app/paths';\n\nconst route = await match('/blog/hello-world');\n\nif (route?.id === '/blog/[slug]') {\n\tconst slug = route.params.slug;\n\tconst response = await fetch(`/api/posts/${slug}`);\n\tconst post = await response.json();\n}\nfunction match(\n\turl: Pathname_1 | URL | (string & {})\n): Promise<{\n\tid: RouteId;\n\tparams: Record<string, string>;\n} | null>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","resolve"],"href":"/docs/kit/$app-paths#resolve","content":"Available since 2.26\nResolve a pathname by prefixing it with the base path, if any, or resolve a route ID by populating dynamic segments with parameters.During server rendering, the base path is relative and depends on the page currently being rendered. \nimport { resolve } from '$app/paths';\n\n// using a pathname\nconst resolved = resolve(`/blog/hello-world`);\n\n// using a route ID plus parameters\nconst resolved = resolve('/blog/[slug]', {\n\tslug: 'hello-world'\n});\nfunction resolve<\n\tT extends\n\t\t| RouteIdWithSearchOrHash\n\t\t| PathnameWithSearchOrHash\n>(...args: ResolveArgs<T>): ResolvedPathname;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/paths","resolveRoute"],"href":"/docs/kit/$app-paths#resolveRoute","content":"Use `resolve(...)` instead\n\nfunction resolveRoute<\n\tT extends\n\t\t| RouteIdWithSearchOrHash\n\t\t| PathnameWithSearchOrHash\n>(...args: ResolveArgs<T>): ResolvedPathname;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server"],"href":"/docs/kit/$app-server","content":"import {\n\tcommand,\n\tform,\n\tgetRequestEvent,\n\tprerender,\n\tquery,\n\tread,\n\trequested\n} from '$app/server';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","command"],"href":"/docs/kit/$app-server#command","content":"Available since 2.27\nCreates a remote command. When called from the browser, the function will be invoked on the server via a fetch call.See Remote functions for full documentation.\nfunction command<Output>(\n\tfn: () => MaybePromise<Output>\n): RemoteCommand<void, Output>;\n\nfunction command<Input, Output>(\n\tvalidate: 'unchecked',\n\tfn: (arg: Input) => MaybePromise<Output>\n): RemoteCommand<Input, Output>;\n\nfunction command<Schema extends StandardSchemaV1, Output>(\n\tvalidate: Schema,\n\tfn: (\n\t\targ: StandardSchemaV1.InferOutput<Schema>\n\t) => MaybePromise<Output>\n): RemoteCommand<\n\tStandardSchemaV1.InferInput<Schema>,\n\tOutput\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","form"],"href":"/docs/kit/$app-server#form","content":"Available since 2.27\nCreates a form object that can be spread onto a <form> element.See Remote functions for full documentation.\nfunction form<Output>(\n\tfn: () => MaybePromise<Output>\n): RemoteForm<void, Output>;\n\nfunction form<Input extends RemoteFormInput, Output>(\n\tvalidate: 'unchecked',\n\tfn: (\n\t\tdata: Input,\n\t\tissue: InvalidField<Input>\n\t) => MaybePromise<Output>\n): RemoteForm<Input, Output>;\n\nfunction form<\n\tSchema extends StandardSchemaV1<\n\t\tRemoteFormInput,\n\t\tRecord<string, any>\n\t>,\n\tOutput\n>(\n\tvalidate: Schema,\n\tfn: (\n\t\tdata: StandardSchemaV1.InferOutput<Schema>,\n\t\tissue: InvalidField<StandardSchemaV1.InferInput<Schema>>\n\t) => MaybePromise<Output>\n): RemoteForm<StandardSchemaV1.InferInput<Schema>, Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","getRequestEvent"],"href":"/docs/kit/$app-server#getRequestEvent","content":"Available since 2.20.0\nReturns the current RequestEvent. Can be used inside server hooks, server load functions, actions, and endpoints (and functions called by them).In environments without `AsyncLocalStorage`, this must be called synchronously (i.e. not after an await).\nfunction getRequestEvent(): RequestEvent;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","prerender"],"href":"/docs/kit/$app-server#prerender","content":"Available since 2.27\nCreates a remote prerender function. When called from the browser, the function will be invoked on the server via a fetch call.See Remote functions for full documentation.\nfunction prerender<Output>(\n\tfn: () => MaybePromise<Output>,\n\toptions?:\n\t\t| {\n\t\t\t\tinputs?: RemotePrerenderInputsGenerator<void>;\n\t\t\t\tdynamic?: boolean;\n\t\t  }\n\t\t| undefined\n): RemotePrerenderFunction<void, Output>;\n\nfunction prerender<Input, Output>(\n\tvalidate: 'unchecked',\n\tfn: (arg: Input) => MaybePromise<Output>,\n\toptions?:\n\t\t| {\n\t\t\t\tinputs?: RemotePrerenderInputsGenerator<Input>;\n\t\t\t\tdynamic?: boolean;\n\t\t  }\n\t\t| undefined\n): RemotePrerenderFunction<Input, Output>;\n\nfunction prerender<Schema extends StandardSchemaV1, Output>(\n\tschema: Schema,\n\tfn: (\n\t\targ: StandardSchemaV1.InferOutput<Schema>\n\t) => MaybePromise<Output>,\n\toptions?:\n\t\t| {\n\t\t\t\tinputs?: RemotePrerenderInputsGenerator<\n\t\t\t\t\tStandardSchemaV1.InferInput<Schema>\n\t\t\t\t>;\n\t\t\t\tdynamic?: boolean;\n\t\t  }\n\t\t| undefined\n): RemotePrerenderFunction<\n\tStandardSchemaV1.InferInput<Schema>,\n\tOutput\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","query"],"href":"/docs/kit/$app-server#query","content":"Available since 2.27\nCreates a remote query. When called from the browser, the function will be invoked on the server via a fetch call.See Remote functions for full documentation.\nfunction query<Output>(\n\tfn: () => MaybePromise<Output>\n): RemoteQueryFunction<void, Output>;\n\nfunction query<Input, Output>(\n\tvalidate: 'unchecked',\n\tfn: (arg: Input) => MaybePromise<Output>\n): RemoteQueryFunction<Input, Output>;\n\nfunction query<Schema extends StandardSchemaV1, Output>(\n\tschema: Schema,\n\tfn: (\n\t\targ: StandardSchemaV1.InferOutput<Schema>\n\t) => MaybePromise<Output>\n): RemoteQueryFunction<\n\tStandardSchemaV1.InferInput<Schema>,\n\tOutput,\n\tStandardSchemaV1.InferOutput<Schema>\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","read"],"href":"/docs/kit/$app-server#read","content":"Available since 2.4.0\nRead the contents of an imported asset from the filesystem \nimport { read } from '$app/server';\nimport somefile from './somefile.txt';\n\nconst asset = read(somefile);\nconst text = await asset.text();\nfunction read(asset: string): Response;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","requested"],"href":"/docs/kit/$app-server#requested","content":"In the context of a remote command or form request, returns an iterable\nof { arg, query } entries for the refreshes requested by the client, up to\nthe supplied limit. Each query is a RemoteQuery bound to the original\nclient-side cache key, so refresh() / set() propagate correctly even when\nthe query's schema transforms the input. arg is the validated argument,\ni.e. the value after the schema has run (so InferOutput<Schema> for queries\ndeclared with a Standard Schema).Arguments that fail validation or exceed limit are recorded as failures in\nthe response to the client.import { requested } from '$app/server';\n\nfor (const { arg, query } of requested(getPost, 5)) {\n\t// `arg` is the validated argument; `query` is bound to the client's\n\t// cache key. It's safe to throw away this promise -- SvelteKit will\n\t// await it and forward any errors to the client.\n\tvoid query.refresh();\n}As a shorthand for the above, you can also call refreshAll on the result:import { requested } from '$app/server';\n\nawait requested(getPost, 5).refreshAll();Works with query.batch as well — refreshes for individual entries are\ncollected into a single batched call.For live queries, the same applies, but with reconnect and reconnectAll.\nfunction requested<Input, Output, Validated = Input>(\n\tquery: RemoteQueryFunction<Input, Output, Validated>,\n\tlimit: number\n): QueryRequestedResult<Validated, Output>;\n\nfunction requested<Input, Output, Validated = Input>(\n\tquery: RemoteLiveQueryFunction<Input, Output, Validated>,\n\tlimit: number\n): LiveQueryRequestedResult<Validated, Output>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/server","query"],"href":"/docs/kit/$app-server#query","content":"namespace query {\n\t/**\n\t * Creates a batch query function that collects multiple calls and executes them in a single request\n\t *\n\t * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#query.batch) for full documentation.\n\t *\n\t * @since 2.35\n\t */\n\tfunction batch<Input, Output>(\n\t\tvalidate: 'unchecked',\n\t\tfn: (\n\t\t\targs: Input[]\n\t\t) => MaybePromise<(arg: Input, idx: number) => Output>\n\t): RemoteQueryFunction<Input, Output>;\n\t/**\n\t * Creates a batch query function that collects multiple calls and executes them in a single request\n\t *\n\t * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#query.batch) for full documentation.\n\t *\n\t * @since 2.35\n\t */\n\tfunction batch<Schema extends StandardSchemaV1, Output>(\n\t\tschema: Schema,\n\t\tfn: (\n\t\t\targs: StandardSchemaV1.InferOutput<Schema>[]\n\t\t) => MaybePromise<\n\t\t\t(\n\t\t\t\targ: StandardSchemaV1.InferOutput<Schema>,\n\t\t\t\tidx: number\n\t\t\t) => Output\n\t\t>\n\t): RemoteQueryFunction<\n\t\tStandardSchemaV1.InferInput<Schema>,\n\t\tOutput,\n\t\tStandardSchemaV1.InferOutput<Schema>\n\t>;\n\t/**\n\t * Creates a live remote query. When called from the browser, the function will be invoked on the server via a streaming `fetch` call.\n\t *\n\t * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#query.live) for full documentation.\n\t *\n\t * */\n\tfunction live<Output>(\n\t\tfn: (\n\t\t\targ: void\n\t\t) => RemoteLiveQueryUserFunctionReturnType<Output>\n\t): RemoteLiveQueryFunction<void, Output>;\n\n\tfunction live<Input, Output>(\n\t\tvalidate: 'unchecked',\n\t\tfn: (\n\t\t\targ: Input\n\t\t) => RemoteLiveQueryUserFunctionReturnType<Output>\n\t): RemoteLiveQueryFunction<Input, Output>;\n\n\tfunction live<Schema extends StandardSchemaV1, Output>(\n\t\tschema: Schema,\n\t\tfn: (\n\t\t\targ: StandardSchemaV1.InferOutput<Schema>\n\t\t) => RemoteLiveQueryUserFunctionReturnType<Output>\n\t): RemoteLiveQueryFunction<\n\t\tStandardSchemaV1.InferInput<Schema>,\n\t\tOutput,\n\t\tStandardSchemaV1.InferOutput<Schema>\n\t>;\n}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/state"],"href":"/docs/kit/$app-state","content":"SvelteKit makes three read-only state objects available via the $app/state module — page, navigating and updated.[!NOTE]\nThis module was added in 2.12. If you're using an earlier version of SvelteKit, use [`$app/stores`]($app-stores) instead. \nimport { navigating, page, updated } from '$app/state';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/state","navigating"],"href":"/docs/kit/$app-state#navigating","content":"A read-only object representing an in-progress navigation, with from, to, type and (if type === 'popstate') delta properties.\nValues are null when no navigation is occurring, or during server rendering.\nconst navigating:\n\t| import('@sveltejs/kit').Navigation\n\t| {\n\t\t\tfrom: null;\n\t\t\tto: null;\n\t\t\ttype: null;\n\t\t\twillUnload: null;\n\t\t\tdelta: null;\n\t\t\tcomplete: null;\n\t  };","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/state","page"],"href":"/docs/kit/$app-state#page","content":"A read-only reactive object with information about the current page, serving several use cases:retrieving the combined `data` of all pages/layouts anywhere in your component tree (also see [loading data](/docs/kit/load))\nretrieving the current value of the `form` prop anywhere in your component tree (also see [form actions](/docs/kit/form-actions))\nretrieving the page state that was set through `goto`, `pushState` or `replaceState` (also see [goto](/docs/kit/$app-navigation#goto) and [shallow routing](/docs/kit/shallow-routing))\nretrieving metadata such as the URL you're on, the current route and its parameters, and whether or not there was an error<!--- file: +layout.svelte --->\n<script>\n\timport { page } from '$app/state';\n</script>\n\n<p>Currently at {page.url.pathname}</p>\n\n{#if page.error}\n\t<span class=\"red\">Problem detected</span>\n{:else}\n\t<span class=\"small\">All systems operational</span>\n{/if}Changes to page are available exclusively with runes. (The legacy reactivity syntax will not reflect any changes)<!--- file: +page.svelte --->\n<script>\n\timport { page } from '$app/state';\n\tconst id = $derived(page.params.id); // This will correctly update id for usage on this page\n\t$: badId = page.params.id; // Do not use; will never update after initial load\n</script>On the server, values can only be read during rendering (in other words not in e.g. load functions). In the browser, the values can be read at any time.\nconst page: import('@sveltejs/kit').Page;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/state","updated"],"href":"/docs/kit/$app-state#updated","content":"A read-only reactive value that's initially false. If `version.pollInterval` is a non-zero value, SvelteKit will poll for new versions of the app and update current to true when it detects one. updated.check() will force an immediate check, regardless of polling.\nconst updated: {\n\tget current(): boolean;\n\tcheck(): Promise<boolean>;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/stores"],"href":"/docs/kit/$app-stores","content":"This module contains store-based equivalents of the exports from `$app/state`. If you're using SvelteKit 2.12 or later, use that module instead. \nimport { getStores, navigating, page, updated } from '$app/stores';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/stores","getStores"],"href":"/docs/kit/$app-stores#getStores","content":"function getStores(): {\n\tpage: typeof page;\n\n\tnavigating: typeof navigating;\n\n\tupdated: typeof updated;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/stores","navigating"],"href":"/docs/kit/$app-stores#navigating","content":"Use navigating from $app/state instead (requires Svelte 5, see docs for more info)\nA readable store.\nWhen navigating starts, its value is a Navigation object with from, to, type and (if type === 'popstate') delta properties.\nWhen navigating finishes, its value reverts to null.On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\nconst navigating: import('svelte/store').Readable<\n\timport('@sveltejs/kit').Navigation | null\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/stores","page"],"href":"/docs/kit/$app-stores#page","content":"Use page from $app/state instead (requires Svelte 5, see docs for more info)\nA readable store whose value contains page data.On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\nconst page: import('svelte/store').Readable<\n\timport('@sveltejs/kit').Page\n>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/stores","updated"],"href":"/docs/kit/$app-stores#updated","content":"Use updated from $app/state instead (requires Svelte 5, see docs for more info)\nA readable store whose initial value is false. If `version.pollInterval` is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to true when it detects one. updated.check() will force an immediate check, regardless of polling.On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\nconst updated: import('svelte/store').Readable<boolean> & {\n\tcheck(): Promise<boolean>;\n};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types"],"href":"/docs/kit/$app-types","content":"This module contains generated types for the routes in your app.\n \nimport type { RouteId, RouteParams, LayoutParams } from '$app/types';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","Asset"],"href":"/docs/kit/$app-types#Asset","content":"A union of all the filenames of assets contained in your static directory, plus a string wildcard for asset paths generated from import declarations.\ntype Asset = '/favicon.png' | '/robots.txt' | (string & {});","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","RouteId"],"href":"/docs/kit/$app-types#RouteId","content":"A union of all the route IDs in your app. Used for page.route.id and event.route.id.\ntype RouteId = '/' | '/my-route' | '/my-other-route/[param]';","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","Pathname"],"href":"/docs/kit/$app-types#Pathname","content":"A union of all valid pathnames in your app.\ntype Pathname = '/' | '/my-route' | `/my-other-route/${string}` & {};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","ResolvedPathname"],"href":"/docs/kit/$app-types#ResolvedPathname","content":"Similar to Pathname, but possibly prefixed with a base path. Used for page.url.pathname.\ntype ResolvedPathname = `${'' | `/${string}`}/` | `${'' | `/${string}`}/my-route` | `${'' | `/${string}`}/my-other-route/${string}` | {};","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","RouteParams"],"href":"/docs/kit/$app-types#RouteParams","content":"A utility for getting the parameters associated with a given route. \ntype BlogParams = RouteParams<'/blog/[slug]'>; // { slug: string }\ntype RouteParams<T extends RouteId> = { /* generated */ } | Record<string, never>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$app/types","LayoutParams"],"href":"/docs/kit/$app-types#LayoutParams","content":"A utility for getting the parameters associated with a given layout, which is similar to RouteParams but also includes optional parameters for any child route.\ntype RouteParams<T extends RouteId> = { /* generated */ } | Record<string, never>;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$env/dynamic/private"],"href":"/docs/kit/$env-dynamic-private","content":"This module provides access to environment variables set dynamically at runtime and that are limited to private access. ,Runtime ,Build time \nPrivate ,[`$env/dynamic/private`](/docs/kit/$env-dynamic-private) ,[`$env/static/private`](/docs/kit/$env-static-private) \nPublic ,[`$env/dynamic/public`](/docs/kit/$env-dynamic-public) ,[`$env/static/public`](/docs/kit/$env-static-public) Dynamic environment variables are defined by the platform you're running on. For example if you're using `adapter-node` (or running `vite preview`), this is equivalent to process.env._Private_ access:This module cannot be imported into client-side code\nThis module includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](/docs/kit/configuration#env) (if configured)[!NOTE] In `dev`, `$env/dynamic` includes environment variables from `.env`. In `prod`, this behavior will depend on your adapter.[!NOTE] To get correct types, environment variables referenced in your code should be declared (for example in an `.env` file), even if they don't have a value until the app is deployed:\n\n```env\nMY_FEATURE_FLAG=\n```\n\nYou can override `.env` values from the command line like so:\n\n```sh\nMY_FEATURE_FLAG=\"enabled\" npm run dev\n```For example, given the following runtime environment:ENVIRONMENT=production\nPUBLIC_BASE_URL=http://site.comWith the default publicPrefix and privatePrefix:import { env } from '$env/dynamic/private';\n\nconsole.log(env.ENVIRONMENT); // => \"production\"\nconsole.log(env.PUBLIC_BASE_URL); // => undefined","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$env/dynamic/public"],"href":"/docs/kit/$env-dynamic-public","content":"This module provides access to environment variables set dynamically at runtime and that are publicly accessible. ,Runtime ,Build time \nPrivate ,[`$env/dynamic/private`](/docs/kit/$env-dynamic-private) ,[`$env/static/private`](/docs/kit/$env-static-private) \nPublic ,[`$env/dynamic/public`](/docs/kit/$env-dynamic-public) ,[`$env/static/public`](/docs/kit/$env-static-public) Dynamic environment variables are defined by the platform you're running on. For example if you're using `adapter-node` (or running `vite preview`), this is equivalent to process.env._Public_ access:This module _can_ be imported into client-side code\n**Only** variables that begin with [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are included[!NOTE] In `dev`, `$env/dynamic` includes environment variables from `.env`. In `prod`, this behavior will depend on your adapter.[!NOTE] To get correct types, environment variables referenced in your code should be declared (for example in an `.env` file), even if they don't have a value until the app is deployed:\n\n```env\nMY_FEATURE_FLAG=\n```\n\nYou can override `.env` values from the command line like so:\n\n```sh\nMY_FEATURE_FLAG=\"enabled\" npm run dev\n```For example, given the following runtime environment:ENVIRONMENT=production\nPUBLIC_BASE_URL=http://example.comWith the default publicPrefix and privatePrefix:import { env } from '$env/dynamic/public';\nconsole.log(env.ENVIRONMENT); // => undefined, not public\nconsole.log(env.PUBLIC_BASE_URL); // => \"http://example.com\"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$env/static/private"],"href":"/docs/kit/$env-static-private","content":"This module provides access to environment variables that are injected statically into your bundle at build time and are limited to private access. ,Runtime ,Build time \nPrivate ,[`$env/dynamic/private`](/docs/kit/$env-dynamic-private) ,[`$env/static/private`](/docs/kit/$env-static-private) \nPublic ,[`$env/dynamic/public`](/docs/kit/$env-dynamic-public) ,[`$env/static/public`](/docs/kit/$env-static-public) Static environment variables are loaded by Vite from .env files and process.env at build time and then statically injected into your bundle at build time, enabling optimisations like dead code elimination._Private_ access:This module cannot be imported into client-side code\nThis module only includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](/docs/kit/configuration#env) (if configured)For example, given the following build time environment:ENVIRONMENT=production\nPUBLIC_BASE_URL=http://site.comWith the default publicPrefix and privatePrefix:import { ENVIRONMENT, PUBLIC_BASE_URL } from '$env/static/private';\n\nconsole.log(ENVIRONMENT); // => \"production\"\nconsole.log(PUBLIC_BASE_URL); // => throws error during buildThe above values will be the same even if different values for ENVIRONMENT or PUBLIC_BASE_URL are set at runtime, as they are statically replaced in your code with their build time values.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$env/static/public"],"href":"/docs/kit/$env-static-public","content":"This module provides access to environment variables that are injected statically into your bundle at build time and are publicly accessible. ,Runtime ,Build time \nPrivate ,[`$env/dynamic/private`](/docs/kit/$env-dynamic-private) ,[`$env/static/private`](/docs/kit/$env-static-private) \nPublic ,[`$env/dynamic/public`](/docs/kit/$env-dynamic-public) ,[`$env/static/public`](/docs/kit/$env-static-public) Static environment variables are loaded by Vite from .env files and process.env at build time and then statically injected into your bundle at build time, enabling optimisations like dead code elimination._Public_ access:This module _can_ be imported into client-side code\n**Only** variables that begin with [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are includedFor example, given the following build time environment:ENVIRONMENT=production\nPUBLIC_BASE_URL=http://site.comWith the default publicPrefix and privatePrefix:import { ENVIRONMENT, PUBLIC_BASE_URL } from '$env/static/public';\n\nconsole.log(ENVIRONMENT); // => throws error during build\nconsole.log(PUBLIC_BASE_URL); // => \"http://site.com\"The above values will be the same even if different values for ENVIRONMENT or PUBLIC_BASE_URL are set at runtime, as they are statically replaced in your code with their build time values.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$lib"],"href":"/docs/kit/$lib","content":"SvelteKit automatically makes files under src/lib available using the $lib import alias.<!--- file: src/lib/Component.svelte --->\nA reusable component<!--- file: src/routes/+page.svelte --->\n<script>\n\timport Component from '$lib/Component.svelte';\n</script>\n\n<Component />","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker"],"href":"/docs/kit/$service-worker","content":"import { base, build, files, prerendered, version } from '$service-worker';This module is only available to service workers.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker","base"],"href":"/docs/kit/$service-worker#base","content":"The base path of the deployment. Typically this is equivalent to config.kit.paths.base, but it is calculated from location.pathname meaning that it will continue to work correctly if the site is deployed to a subdirectory.\nNote that there is a base but no assets, since service workers cannot be used if config.kit.paths.assets is specified.\nconst base: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker","build"],"href":"/docs/kit/$service-worker#build","content":"An array of URL strings representing the files generated by Vite, suitable for caching with cache.addAll(build).\nDuring development, this is an empty array.\nconst build: string[];","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker","files"],"href":"/docs/kit/$service-worker#files","content":"An array of URL strings representing the files in your static directory, or whatever directory is specified by config.kit.files.assets. You can customize which files are included from static directory using `config.kit.serviceWorker.files`\nconst files: string[];","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker","prerendered"],"href":"/docs/kit/$service-worker#prerendered","content":"An array of pathnames corresponding to prerendered pages and endpoints.\nDuring development, this is an empty array.\nconst prerendered: string[];","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","$service-worker","version"],"href":"/docs/kit/$service-worker#version","content":"See `config.kit.version`. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.\nconst version: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration"],"href":"/docs/kit/configuration","content":"Your project's configuration lives in a svelte.config.js file at the root of your project. As well as SvelteKit, this config object is used by other tooling that integrates with Svelte such as editor extensions.import adapter from '@sveltejs/adapter-auto';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;Since version 2.62.0 you can also pass your configuration to the sveltekit plugin in your Vite config, along with the Svelte compiler options:import adapter from '@sveltejs/adapter-auto';\nimport { sveltekit } from '@sveltejs/kit/vite';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n\tplugins: [\n\t\tsveltekit({\n\t\t\tcompilerOptions: {\n\t\t\t\texperimental: {\n\t\t\t\t\tasync: true\n\t\t\t\t}\n\t\t\t},\n\t\t\tadapter: adapter(),\n\t\t\texperimental: {\n\t\t\t\tremoteFunctions: true\n\t\t\t}\n\t\t})\n\t]\n});[!NOTE] The `kit` namespace is at the same level as the other top level entries; this is the only difference to the `svelte.config.js` layout.If the config is defined via the plugin, the svelte.config.js file is ignored.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","Config"],"href":"/docs/kit/configuration#Config","content":"An extension of `vite-plugin-svelte`'s options.\ninterface Config extends SvelteConfig {/*…*/}\nkit?: KitConfig;\nSvelteKit options.\n\n[key: string]: any;\nAny additional options required by tooling that integrates with Svelte.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","KitConfig"],"href":"/docs/kit/configuration#KitConfig","content":"The kit property configures SvelteKit, and can have the following properties:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","adapter"],"href":"/docs/kit/configuration#adapter","content":"<span class=\"tag\">default</span> `undefined`\nYour adapter is run when executing vite build. It determines how the output is converted for different platforms.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","alias"],"href":"/docs/kit/configuration#alias","content":"<span class=\"tag\">default</span> `{}`\nAn object containing zero or more aliases used to replace values in import statements. These aliases are automatically passed to Vite and TypeScript. \n \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\talias: {\n\t\t\t// this will match a file\n\t\t\t'my-file': 'path/to/my-file.js',\n\n\t\t\t// this will match a directory and its contents\n\t\t\t// (`my-directory/x` resolves to `path/to/my-directory/x`)\n\t\t\t'my-directory': 'path/to/my-directory',\n\n\t\t\t// an alias ending /* will only match\n\t\t\t// the contents of a directory, not the directory itself\n\t\t\t'my-directory/*': 'path/to/my-directory/*'\n\t\t}\n\t}\n};[!NOTE] You will need to run `npm run dev` to have SvelteKit automatically generate the required alias configuration in `jsconfig.json` or `tsconfig.json`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","appDir"],"href":"/docs/kit/configuration#appDir","content":"<span class=\"tag\">default</span> `\"_app\"`\nThe directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes.If paths.assets is specified, there will be two app directories — ${paths.assets}/${appDir} and ${paths.base}/${appDir}.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","csp"],"href":"/docs/kit/configuration#csp","content":"Content Security Policy configuration. CSP helps to protect your users against cross-site scripting (XSS) attacks, by limiting the places resources can be loaded from. For example, a configuration like this... \n \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tcsp: {\n\t\t\tdirectives: {\n\t\t\t\t'script-src': ['self']\n\t\t\t},\n\t\t\t// must be specified with either the `report-uri` or `report-to` directives, or both\n\t\t\treportOnly: {\n\t\t\t\t'script-src': ['self'],\n\t\t\t\t'report-uri': ['/']\n\t\t\t}\n\t\t}\n\t}\n};\n\nexport default config;...would prevent scripts loading from external sites. SvelteKit will augment the specified directives with nonces or hashes (depending on mode) for any inline styles and scripts it generates.To add a nonce for scripts and links manually included in src/app.html, you may use the placeholder %sveltekit.nonce% (for example <script nonce=\"%sveltekit.nonce%\">).When pages are prerendered, the CSP header is added via a <meta http-equiv> tag (note that in this case, frame-ancestors, report-uri and sandbox directives will be ignored).[!NOTE] When `mode` is `'auto'`, SvelteKit will use nonces for dynamically rendered pages and hashes for prerendered pages. Using nonces with prerendered pages is insecure and therefore forbidden.[!NOTE] Note that most [Svelte transitions](/tutorial/svelte/transition) work by creating an inline `<style>` element. If you use these in your app, you must either leave the `style-src` directive unspecified or add `unsafe-inline`.If this level of configuration is insufficient and you have more dynamic requirements, you can use the `handle` hook to roll your own CSP.\n\n \nmode?: 'hash' | 'nonce' | 'auto';\nWhether to use hashes or nonces to restrict <script> and <style> elements. 'auto' will use hashes for prerendered pages, and nonces for dynamically rendered pages.\n \ndirectives?: CspDirectives;\nDirectives that will be added to Content-Security-Policy headers.\n \nreportOnly?: CspDirectives;\nDirectives that will be added to Content-Security-Policy-Report-Only headers.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","csrf"],"href":"/docs/kit/configuration#csrf","content":"Protection against cross-site request forgery (CSRF) attacks.\n\n \ncheckOrigin?: boolean;\n\n<span class=\"tag\">default</span> `true`\n<span class=\"tag deprecated\">deprecated</span> Use `trustedOrigins: ['*']` instead\nWhether to check the incoming origin header for POST, PUT, PATCH, or DELETE form submissions and verify that it matches the server's origin.To allow people to make POST, PUT, PATCH, or DELETE requests with a Content-Type of application/x-www-form-urlencoded, multipart/form-data, or text/plain to your app from other origins, you will need to disable this option. Be careful!\n \ntrustedOrigins?: string[];\n\n<span class=\"tag\">default</span> `[]`\nAn array of origins that are allowed to make cross-origin form submissions to your app.Each origin should be a complete origin including protocol (e.g., https://payment-gateway.com).\nThis is useful for allowing trusted third-party services like payment gateways or authentication providers to submit forms to your app.If the array contains '*', all origins will be trusted. This is generally not recommended![!NOTE] Only add origins you completely trust, as this bypasses CSRF protection for those origins.CSRF checks only apply in production, not in local development.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","embedded"],"href":"/docs/kit/configuration#embedded","content":"<span class=\"tag\">default</span> `false`\nWhether or not the app is embedded inside a larger app. If true, SvelteKit will add its event listeners related to navigation etc on the parent of %sveltekit.body% instead of window, and will pass params from the server rather than inferring them from location.pathname.\nNote that it is generally not supported to embed multiple SvelteKit apps on the same page and use client-side SvelteKit features within them (things such as pushing to the history state assume a single instance).","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","env"],"href":"/docs/kit/configuration#env","content":"Environment variable configuration\n\n \ndir?: string;\n\n<span class=\"tag\">default</span> `\".\"`\nThe directory to search for .env files.\n \npublicPrefix?: string;\n\n<span class=\"tag\">default</span> `\"PUBLIC_\"`\nA prefix that signals that an environment variable is safe to expose to client-side code. See `$env/static/public` and `$env/dynamic/public`. Note that Vite's `envPrefix` must be set separately if you are using Vite's environment variable handling - though use of that feature should generally be unnecessary.\n \nprivatePrefix?: string;\n\n<span class=\"tag\">default</span> `\"\"`\n<span class=\"tag since\">available since</span> v1.21.0\nA prefix that signals that an environment variable is unsafe to expose to client-side code. Environment variables matching neither the public nor the private prefix will be discarded completely. See `$env/static/private` and `$env/dynamic/private`.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","experimental"],"href":"/docs/kit/configuration#experimental","content":"Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release.\n\n \nexplicitEnvironmentVariables?: boolean;\n\n<span class=\"tag since\">available since</span> v2.63.0\n<span class=\"tag\">default</span> `false`\nWhether to enable explicit environment variables using src/env.js or src/env.ts.\n \ntracing?: {/*…*/}\n\n<span class=\"tag\">default</span> `{ server: false, serverFile: false }`\n<span class=\"tag since\">available since</span> v2.31.0\nOptions for enabling server-side OpenTelemetry tracing for SvelteKit operations including the `handle` hook, `load` functions, form actions, and remote functions.\n \nserver?: boolean;\n\n<span class=\"tag\">default</span> `false`\n<span class=\"tag since\">available since</span> v2.31.0\nEnables server-side OpenTelemetry span emission for SvelteKit operations including the `handle` hook, `load` functions, form actions, and remote functions.\n\n \ninstrumentation?: {/*…*/}\n\n<span class=\"tag since\">available since</span> v2.31.0\n\n \nserver?: boolean;\n\n<span class=\"tag\">default</span> `false`\n<span class=\"tag since\">available since</span> v2.31.0\nEnables instrumentation.server.js for tracing and observability instrumentation.\n\n \nremoteFunctions?: boolean;\n\n<span class=\"tag\">default</span> `false`\nWhether to enable the experimental remote functions feature. This feature is not yet stable and may be changed or removed at any time.\n \nforkPreloads?: boolean;\n\n<span class=\"tag\">default</span> `false`\nWhether to enable the experimental forked preloading feature using Svelte's fork API.\n \nhandleRenderingErrors?: boolean;\n\n<span class=\"tag\">default</span> `false`\nWhether to enable the experimental handling of rendering errors.\nWhen enabled, <svelte:boundary> is used to wrap components at each level\nwhere there's an +error.svelte, rendering the error page if the component fails.\nIn addition, error boundaries also work on the server and the error object goes through handleError.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","files"],"href":"/docs/kit/configuration#files","content":"<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\nWhere to find various files within your project.\n\n \nsrc?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src\"`\n<span class=\"tag since\">available since</span> v2.28\nThe location of your source code.\n \nassets?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"static\"`\nA place to put static files that should have stable URLs and undergo no processing, such as favicon.ico or manifest.json.\n \nhooks?: {/*…*/}\n\n \nclient?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/hooks.client\"`\nThe location of your client hooks.\n \nserver?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/hooks.server\"`\nThe location of your server hooks.\n \nuniversal?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/hooks\"`\n<span class=\"tag since\">available since</span> v2.3.0\nThe location of your universal hooks.\n\n \nlib?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/lib\"`\nYour app's internal library, accessible throughout the codebase as $lib.\n \nparams?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/params\"`\nA directory containing parameter matchers.\n \nroutes?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/routes\"`\nThe files that define the structure of your app (see Routing).\n \nserviceWorker?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/service-worker\"`\nThe location of your service worker's entry point (see Service workers).\n \nappTemplate?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/app.html\"`\nThe location of the template for HTML responses.\n \nerrorTemplate?: string;\n\n<span class=\"tag deprecated\">deprecated</span> this feature is still supported, but it's generally recommended to use [monorepos](https://levelup.video/tutorials/monorepos-with-pnpm) instead\n<span class=\"tag\">default</span> `\"src/error.html\"`\nThe location of the template for fallback error responses.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","inlineStyleThreshold"],"href":"/docs/kit/configuration#inlineStyleThreshold","content":"<span class=\"tag\">default</span> `0`\nInline CSS inside a <style> block at the head of the HTML. This option is a number that specifies the maximum length of a CSS file in UTF-16 code units, as specified by the String.length property, to be inlined. All CSS files needed for the page that are smaller than this value are merged and inlined in a <style> block.[!NOTE] This results in fewer initial requests and can improve your [First Contentful Paint](https://web.dev/first-contentful-paint) score. However, it generates larger HTML output and reduces the effectiveness of browser caches. Use it advisedly.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","moduleExtensions"],"href":"/docs/kit/configuration#moduleExtensions","content":"<span class=\"tag\">default</span> `[\".js\", \".ts\"]`\nAn array of file extensions that SvelteKit will treat as modules. Files with extensions that match neither config.extensions nor config.kit.moduleExtensions will be ignored by the router.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","outDir"],"href":"/docs/kit/configuration#outDir","content":"<span class=\"tag\">default</span> `\".svelte-kit\"`\nThe directory that SvelteKit writes files to during dev and build. You should exclude this directory from version control.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","output"],"href":"/docs/kit/configuration#output","content":"Options related to the build output format\n\n \npreloadStrategy?: 'modulepreload' | 'preload-js' | 'preload-mjs';\n\n<span class=\"tag\">default</span> `\"modulepreload\"`\n<span class=\"tag since\">available since</span> v1.8.4\nSvelteKit will preload the JavaScript modules needed for the initial page to avoid import 'waterfalls', resulting in faster application startup. There\nare three strategies with different trade-offs:`modulepreload` - uses `<link rel=\"modulepreload\">`. This delivers the best results in Chromium-based browsers, in Firefox 115+, and Safari 17+. It is ignored in older browsers.\n`preload-js` - uses `<link rel=\"preload\">`. Prevents waterfalls in Chromium and Safari, but Chromium will parse each module twice (once as a script, once as a module). Causes modules to be requested twice in Firefox. This is a good setting if you want to maximise performance for users on iOS devices at the cost of a very slight degradation for Chromium users.\n`preload-mjs` - uses `<link rel=\"preload\">` but with the `.mjs` extension which prevents double-parsing in Chromium. Some static webservers will fail to serve .mjs files with a `Content-Type: application/javascript` header, which will cause your application to break. If that doesn't apply to you, this is the option that will deliver the best performance for the largest number of users, until `modulepreload` is more widely supported.\n \nbundleStrategy?: 'split' | 'single' | 'inline';\n\n<span class=\"tag\">default</span> `'split'`\n<span class=\"tag since\">available since</span> v2.13.0\nThe bundle strategy option affects how your app's JavaScript and CSS files are loaded.If `'split'`, splits the app up into multiple .js/.css files so that they are loaded lazily as the user navigates around the app. This is the default, and is recommended for most scenarios.\nIf `'single'`, creates just one .js bundle and one .css file containing code for the entire app.\nIf `'inline'`, inlines all JavaScript and CSS of the entire app into the HTML. The result is usable without a server (i.e. you can just open the file in your browser).When using 'split', you can also adjust the bundling behaviour by setting `output.experimentalMinChunkSize` and `output.manualChunks` inside your Vite config's `build.rollupOptions`.If you want to inline your assets, you'll need to set Vite's `build.assetsInlineLimit` option to an appropriate size then import your assets through Vite. \n \nimport { sveltekit } from '@sveltejs/kit/vite';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n\tplugins: [sveltekit()],\n\tbuild: {\n\t\t// inline all imported assets\n\t\tassetsInlineLimit: Infinity\n\t}\n}); \n<script>\n\t// import the asset through Vite\n\timport favicon from './favicon.png';\n</script>\n\n<svelte:head>\n\t<!-- this asset will be inlined as a base64 URL -->\n\t<link rel=\"icon\" href={favicon} />\n</svelte:head>","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","paths"],"href":"/docs/kit/configuration#paths","content":"assets?: '' | `http://${string}` | `https://${string}`;\n\n<span class=\"tag\">default</span> `\"\"`\nAn absolute path that your app's files are served from. This is useful if your files are served from a storage bucket of some kind.\n \nbase?: '' | `/${string}`;\n\n<span class=\"tag\">default</span> `\"\"`\nA root-relative path that must start, but not end with / (e.g. /base-path), unless it is the empty string. This specifies where your app is served from and allows the app to live on a non-root path. Note that you need to prepend all your root-relative links with the base value or they will point to the root of your domain, not your base (this is how the browser works). You can use `base` from `$app/paths` for that: <a href=\"{base}/your-page\">Link</a>. If you find yourself writing this often, it may make sense to extract this into a reusable component.\n \nrelative?: boolean;\n\n<span class=\"tag\">default</span> `true`\n<span class=\"tag since\">available since</span> v1.9.0\nWhether to use relative asset paths.If true, base and assets imported from $app/paths will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML.\nIf false, %sveltekit.assets% and references to build artifacts will always be root-relative paths, unless paths.assets is an external URLSingle-page app fallback pages will always use absolute paths, regardless of this setting.If your app uses a <base> element, you should set this to false, otherwise asset URLs will incorrectly be resolved against the <base> URL rather than the current page.In 1.0, undefined was a valid value, which was set by default. In that case, if paths.assets was not external, SvelteKit would replace %sveltekit.assets% with a relative path and use relative paths to reference build artifacts, but base and assets imported from $app/paths would be as specified in your config.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","prerender"],"href":"/docs/kit/configuration#prerender","content":"See Prerendering.\n\n \nconcurrency?: number;\n\n<span class=\"tag\">default</span> `1`\nHow many pages can be prerendered simultaneously. JS is single-threaded, but in cases where prerendering performance is network-bound (for example loading content from a remote CMS) this can speed things up by processing other tasks while waiting on the network response.\n \ncrawl?: boolean;\n\n<span class=\"tag\">default</span> `true`\nWhether SvelteKit should find pages to prerender by following links from entries.\n \nentries?: Array<'*' | `/${string}`>;\n\n<span class=\"tag\">default</span> `[\"*\"]`\nAn array of pages to prerender, or start crawling from (if crawl: true). The * string includes all routes containing no required [parameters]  with optional parameters included as being empty (since SvelteKit doesn't know what value any parameters should have).\n \nhandleHttpError?: PrerenderHttpErrorHandlerValue;\n\n<span class=\"tag\">default</span> `\"fail\"`\n<span class=\"tag since\">available since</span> v1.15.7\nHow to respond to HTTP errors encountered while prerendering the app.`'fail'` — fail the build\n`'ignore'` - silently ignore the failure and continue\n`'warn'` — continue, but print a warning\n`(details) => void` — a custom error handler that takes a `details` object with `status`, `path`, `referrer`, `referenceType` and `message` properties. If you `throw` from this function, the build will fail \n \n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tkit: {\n\t\tprerender: {\n\t\t\thandleHttpError: ({ path, referrer, message }) => {\n\t\t\t\t// ignore deliberate link to shiny 404 page\n\t\t\t\tif (path === '/not-found' && referrer === '/blog/how-we-built-our-404-page') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// otherwise fail the build\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\t}\n};\n \nhandleMissingId?: PrerenderMissingIdHandlerValue;\n\n<span class=\"tag\">default</span> `\"fail\"`\n<span class=\"tag since\">available since</span> v1.15.7\nHow to respond when hash links from one prerendered page to another don't correspond to an id on the destination page.`'fail'` — fail the build\n`'ignore'` - silently ignore the failure and continue\n`'warn'` — continue, but print a warning\n`(details) => void` — a custom error handler that takes a `details` object with `path`, `id`, `referrers` and `message` properties. If you `throw` from this function, the build will fail\n \nhandleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;\n\n<span class=\"tag\">default</span> `\"fail\"`\n<span class=\"tag since\">available since</span> v1.16.0\nHow to respond when an entry generated by the entries export doesn't match the route it was generated from.`'fail'` — fail the build\n`'ignore'` - silently ignore the failure and continue\n`'warn'` — continue, but print a warning\n`(details) => void` — a custom error handler that takes a `details` object with `generatedFromId`, `entry`, `matchedId` and `message` properties. If you `throw` from this function, the build will fail\n \nhandleUnseenRoutes?: PrerenderUnseenRoutesHandlerValue;\n\n<span class=\"tag\">default</span> `\"fail\"`\n<span class=\"tag since\">available since</span> v2.16.0\nHow to respond when a route is marked as prerenderable but has not been prerendered.`'fail'` — fail the build\n`'ignore'` - silently ignore the failure and continue\n`'warn'` — continue, but print a warning\n`(details) => void` — a custom error handler that takes a `details` object with a `routes` property which contains all routes that haven't been prerendered. If you `throw` from this function, the build will failThe default behavior is to fail the build. This may be undesirable when you know that some of your routes may never be reached under certain\ncircumstances such as a CMS not returning data for a specific area, resulting in certain routes never being reached.\n \norigin?: string;\n\n<span class=\"tag\">default</span> `\"http://sveltekit-prerender\"`\nThe value of url.origin during prerendering; useful if it is included in rendered content.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","router"],"href":"/docs/kit/configuration#router","content":"type?: 'pathname' | 'hash';\n\n<span class=\"tag\">default</span> `\"pathname\"`\n<span class=\"tag since\">available since</span> v2.14.0\nWhat type of client-side router to use.`'pathname'` is the default and means the current URL pathname determines the route\n`'hash'` means the route is determined by `location.hash`. In this case, SSR and prerendering are disabled. This is only recommended if `pathname` is not an option, for example because you don't control the webserver where your app is deployed.\n  It comes with some caveats: you can't use server-side rendering (or indeed any server logic), and you have to make sure that the links in your app all start with #/, or they won't work. Beyond that, everything works exactly like a normal SvelteKit app.\n \nresolution?: 'client' | 'server';\n\n<span class=\"tag\">default</span> `\"client\"`\n<span class=\"tag since\">available since</span> v2.17.0\nHow to determine which route to load when navigating to a new page.By default, SvelteKit will serve a route manifest to the browser.\nWhen navigating, this manifest is used (along with the reroute hook, if it exists) to determine which components to load and which load functions to run.\nBecause everything happens on the client, this decision can be made immediately. The drawback is that the manifest needs to be\nloaded and parsed before the first navigation can happen, which may have an impact if your app contains many routes.Alternatively, SvelteKit can determine the route on the server. This means that for every navigation to a path that has not yet been visited, the server will be asked to determine the route.\nThis has several advantages:The client does not need to load the routing manifest upfront, which can lead to faster initial page loads\nThe list of routes is hidden from public view\nThe server has an opportunity to intercept each navigation (for example through a middleware), enabling (for example) A/B testing opaque to SvelteKitThe drawback is that for unvisited paths, resolution will take slightly longer (though this is mitigated by preloading).[!NOTE] When using server-side route resolution and prerendering, the resolution is prerendered along with the route itself.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","serviceWorker"],"href":"/docs/kit/configuration#serviceWorker","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","typescript"],"href":"/docs/kit/configuration#typescript","content":"config?: (config: Record<string, any>) => Record<string, any> | void;\n\n<span class=\"tag\">default</span> `(config) => config`\n<span class=\"tag since\">available since</span> v1.3.0\nA function that allows you to edit the generated tsconfig.json. You can mutate the config (recommended) or return a new one.\nThis is useful for extending a shared tsconfig.json in a monorepo root, for example.Note that any paths configured here should be relative to the generated config file, which is written to .svelte-kit/tsconfig.json.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Configuration","version"],"href":"/docs/kit/configuration#version","content":"Client-side navigation can be buggy if you deploy a new version of your app while people are using it. If the code for the new page is already loaded, it may have stale content; if it isn't, the app's route manifest may point to a JavaScript file that no longer exists.\nSvelteKit helps you solve this problem through version management.\nIf SvelteKit encounters an error while loading the page and detects that a new version has been deployed (using the name specified here, which defaults to a timestamp of the build) it will fall back to traditional full-page navigation.\nNot all navigations will result in an error though, for example if the JavaScript for the next page is already loaded. If you still want to force a full-page navigation in these cases, use techniques such as setting the pollInterval and then using beforeNavigate: \n<script>\n\timport { beforeNavigate } from '$app/navigation';\n\timport { updated } from '$app/state';\n\n\tbeforeNavigate(({ willUnload, to }) => {\n\t\tif (updated.current && !willUnload && to?.url) {\n\t\t\tlocation.href = to.url.href;\n\t\t}\n\t});\n</script>If you set pollInterval to a non-zero value, SvelteKit will poll for new versions in the background and set the value of `updated.current` true when it detects one.\n\n \nname?: string;\nThe current app version string. If specified, this must be deterministic (e.g. a commit ref rather than Math.random() or Date.now().toString()), otherwise defaults to a timestamp of the build.For example, to use the current commit hash, you could do use git rev-parse HEAD: \n \nimport * as child_process from 'node:child_process';\n\nexport default {\n\tkit: {\n\t\tversion: {\n\t\t\tname: child_process.execSync('git rev-parse HEAD').toString().trim()\n\t\t}\n\t}\n};\n \npollInterval?: number;\n\n<span class=\"tag\">default</span> `0`\nThe interval in milliseconds to poll for version changes. If this is 0, no polling occurs.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Command Line Interface"],"href":"/docs/kit/cli","content":"SvelteKit projects use Vite, meaning you'll mostly use its CLI (albeit via npm run dev/build/preview scripts):`vite dev` — start a development server\n`vite build` — build a production version of your app\n`vite preview` — run the production version locallyHowever SvelteKit includes its own CLI for initialising your project:","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Command Line Interface","svelte-kit sync"],"href":"/docs/kit/cli#svelte-kit-sync","content":"svelte-kit sync creates the tsconfig.json and all generated types (which you can import as ./$types inside routing files) for your project. When you create a new project, it is listed as the prepare script and will be run automatically as part of the npm lifecycle, so you should not ordinarily have to run this command.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types"],"href":"/docs/kit/types","content":"","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","Generated types"],"href":"/docs/kit/types#Generated-types","content":"The RequestHandler and Load types both accept a Params argument allowing you to type the params object. For example this endpoint expects foo, bar and baz params: \n \n/**\n * @type {import('@sveltejs/kit').RequestHandler<{\n *   foo: string;\n *   bar: string;\n *   baz: string\n * }>}\n */\nexport async function GET({ params }) {\n\t// ...\n}Needless to say, this is cumbersome to write out, and less portable (if you were to rename the [foo] directory to [qux], the type would no longer reflect reality).To solve this problem, SvelteKit generates .d.ts files for each of your endpoints and pages: \n/// link: true\nimport type * as Kit from '@sveltejs/kit';\n\ntype RouteParams = {\n\tfoo: string;\n\tbar: string;\n\tbaz: string;\n};\n\nexport type RequestHandler = Kit.RequestHandler<RouteParams>;\nexport type PageLoad = Kit.Load<RouteParams>;These files can be imported into your endpoints and pages as siblings, thanks to the `rootDirs` option in your TypeScript configuration:/** @type {import('./$types').RequestHandler} */\nexport async function GET({ params }) {\n\t// ...\n}/** @type {import('./$types').PageLoad} */\nexport async function load({ params, fetch }) {\n\t// ...\n}The return types of the load functions are then available through the $types module as PageData and LayoutData respectively, while the union of the return values of all Actions is available as ActionData.Starting with version 2.16.0, two additional helper types are provided: PageProps defines data: PageData, as well as form: ActionData, when there are actions defined, while LayoutProps defines data: LayoutData, as well as children: Snippet.<!--- file: src/routes/+page.svelte --->\n<script>\n\t/** @type {import('./$types').PageProps} */\n\tlet { data, form } = $props();\n</script>[!LEGACY]\nBefore 2.16.0:\n```svelte\n<!--- file: src/routes/+page.svelte --->\n<script>\n\t/** @type {{ data: import('./$types').PageData, form: import('./$types').ActionData }} */\n\tlet { data, form } = $props();\n</script>\n```\n\nUsing Svelte 4:\n```svelte\n<!--- file: src/routes/+page.svelte --->\n<script>\n  /** @type {import('./$types').PageData} */\n  export let data;\n  /** @type {import('./$types').ActionData} */\n  export let form;\n</script>\n```[!NOTE] For this to work, your own `tsconfig.json` or `jsconfig.json` should extend from the generated `.svelte-kit/tsconfig.json` (where `.svelte-kit` is your [`outDir`](configuration#outDir)):\n\n`{ \"extends\": \"./.svelte-kit/tsconfig.json\" }`","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","Generated types","Default tsconfig.json"],"href":"/docs/kit/types#Generated-types-Default-tsconfig.json","content":"The generated .svelte-kit/tsconfig.json file contains a mixture of options. Some are generated programmatically based on your project configuration, and should generally not be overridden without good reason: \n{\n\t\"compilerOptions\": {\n\t\t\"paths\": {\n\t\t\t\"$lib\": [\"../src/lib\"],\n\t\t\t\"$lib/*\": [\"../src/lib/*\"]\n\t\t},\n\t\t\"rootDirs\": [\"..\", \"./types\"]\n\t},\n\t\"include\": [\n\t\t\"ambient.d.ts\",\n\t\t\"non-ambient.d.ts\",\n\t\t\"./types/**/$types.d.ts\",\n\t\t\"../vite.config.js\",\n\t\t\"../vite.config.ts\",\n\t\t\"../src/**/*.js\",\n\t\t\"../src/**/*.ts\",\n\t\t\"../src/**/*.svelte\",\n\t\t\"../tests/**/*.js\",\n\t\t\"../tests/**/*.ts\",\n\t\t\"../tests/**/*.svelte\"\n\t],\n\t\"exclude\": [\n\t\t\"../node_modules/**\",\n\t\t\"../src/service-worker.js\",\n\t\t\"../src/service-worker/**/*.js\",\n\t\t\"../src/service-worker.ts\",\n\t\t\"../src/service-worker/**/*.ts\",\n\t\t\"../src/service-worker.d.ts\",\n\t\t\"../src/service-worker/**/*.d.ts\"\n\t]\n}Others are required for SvelteKit to work properly, and should also be left untouched unless you know what you're doing: \n{\n\t\"compilerOptions\": {\n\t\t// this ensures that types are explicitly\n\t\t// imported with `import type`, which is\n\t\t// necessary as Svelte/Vite cannot\n\t\t// otherwise compile components correctly\n\t\t\"verbatimModuleSyntax\": true,\n\n\t\t// Vite compiles one TypeScript module\n\t\t// at a time, rather than compiling\n\t\t// the entire module graph\n\t\t\"isolatedModules\": true,\n\n\t\t// Tell TS it's used only for type-checking\n\t\t\"noEmit\": true,\n\n\t\t// This ensures both `vite build`\n\t\t// and `svelte-package` work correctly\n\t\t\"lib\": [\"esnext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"module\": \"esnext\",\n\t\t\"target\": \"esnext\"\n\t}\n}Use the `typescript.config` setting in svelte.config.js to extend or modify the generated tsconfig.json.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","$lib"],"href":"/docs/kit/types#$lib","content":"This is a simple alias to src/lib. It allows you to access common components and utility modules without ../../../../ nonsense.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","$lib","$lib/server"],"href":"/docs/kit/types#$lib-$lib-server","content":"A subdirectory of $lib. SvelteKit will prevent you from importing any modules in $lib/server into client-side code. See server-only modules.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","app.d.ts"],"href":"/docs/kit/types#app.d.ts","content":"The app.d.ts file is home to the ambient types of your apps, i.e. types that are available without explicitly importing them.Always part of this file is the App namespace. This namespace contains several types that influence the shape of certain SvelteKit features you interact with.","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","Error"],"href":"/docs/kit/types#Error","content":"Defines the common shape of expected and unexpected errors. Expected errors are thrown using the error function. Unexpected errors are handled by the handleError hooks which should return this shape.\ninterface Error {/*…*/}\nmessage: string;","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","Locals"],"href":"/docs/kit/types#Locals","content":"The interface that defines event.locals, which can be accessed in server hooks (handle, and handleError), server-only load functions, and +server.js files.\ninterface Locals {}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","PageData"],"href":"/docs/kit/types#PageData","content":"Defines the common shape of the page.data state and $page.data store - that is, the data that is shared between all pages.\nThe Load and ServerLoad functions in ./$types will be narrowed accordingly.\nUse optional properties for data that is only present on specific pages. Do not add an index signature ([key: string]: any).\ninterface PageData {}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","PageState"],"href":"/docs/kit/types#PageState","content":"The shape of the page.state object, which can be manipulated using the `pushState` and `replaceState` functions from $app/navigation.\ninterface PageState {}","rank":null},{"breadcrumbs":["Docs","SvelteKit","Reference","Types","Platform"],"href":"/docs/kit/types#Platform","content":"If your adapter provides platform-specific context via event.platform, you can specify it here.\ninterface Platform {}","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction","Overview"],"href":"/docs/svelte/overview","content":"Svelte is a framework for building user interfaces on the web. It uses a compiler to turn declarative components written in HTML, CSS and JavaScript...<!--- file: App.svelte --->\n<script>\n\tfunction greet() {\n\t\talert('Welcome to Svelte!');\n\t}\n</script>\n\n<button onclick={greet}>click me</button>\n\n<style>\n\tbutton {\n\t\tfont-size: 2em;\n\t}\n</style>...into lean, tightly optimized JavaScript.You can use it to build anything on the web, from standalone components to ambitious full stack apps (using Svelte's companion application framework, SvelteKit) and everything in between.These pages serve as reference documentation. If you're new to Svelte, we recommend starting with the interactive tutorial and coming back here when you have questions.You can also try Svelte online in the playground or, if you need a more fully-featured environment, on StackBlitz.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction","Getting started"],"href":"/docs/svelte/getting-started","content":"We recommend using SvelteKit, which lets you build almost anything. It's the official application framework from the Svelte team and powered by Vite. Create a new project with:npx sv create myapp\ncd myapp\nnpm install\nnpm run devDon't worry if you don't know Svelte yet! You can ignore all the nice features SvelteKit brings on top for now and dive into it later.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction","Getting started","Alternatives to SvelteKit"],"href":"/docs/svelte/getting-started#Alternatives-to-SvelteKit","content":"You can also use Svelte directly with Vite via vite-plugin-svelte by running npm create vite@latest and selecting the svelte option (or, if working with an existing project, adding the plugin to your vite.config.js file). With this, npm run build will generate HTML, JS, and CSS files inside the dist directory. In most cases, you will probably need to choose a routing library as well.[!NOTE] Vite is often used in standalone mode to build [single page apps (SPAs)](../kit/glossary#SPA), which you can also [build with SvelteKit](../kit/single-page-apps).There are also plugins for other bundlers, but we recommend Vite.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction","Getting started","Editor tooling"],"href":"/docs/svelte/getting-started#Editor-tooling","content":"The Svelte team maintains a VS Code extension, and there are integrations with various other editors and tools as well.You can also check your code from the command line using `npx sv check`.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction","Getting started","Getting help"],"href":"/docs/svelte/getting-started#Getting-help","content":"Don't be shy about asking for help in the Discord chatroom! You can also find answers on Stack Overflow.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction",".svelte files"],"href":"/docs/svelte/svelte-files","content":"Components are the building blocks of Svelte applications. They are written into .svelte files, using a superset of HTML.All three sections — script, styles and markup — are optional.\n \n<script module>\n\t// module-level logic goes here\n\t// (you will rarely use this)\n</script>\n\n<script>\n\t// instance-level logic goes here\n</script>\n\n<!-- markup (zero or more items) goes here -->\n\n<style>\n\t/* styles go here */\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction",".svelte files","<script>"],"href":"/docs/svelte/svelte-files#script","content":"A <script> block contains JavaScript (or TypeScript, when adding the lang=\"ts\" attribute) that runs when a component instance is created. Variables declared (or imported) at the top level can be referenced in the component's markup.In addition to normal JavaScript, you can use runes to declare component props and add reactivity to your component. Runes are covered in the next section.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction",".svelte files","<script module>"],"href":"/docs/svelte/svelte-files#script-module","content":"A <script> tag with a module attribute runs once when the module first evaluates, rather than for each component instance. Variables declared in this block can be referenced elsewhere in the component, but not vice versa.<script module>\n\tlet total = 0;\n</script>\n\n<script>\n\ttotal += 1;\n\tconsole.log(`instantiated ${total} times`);\n</script>You can export bindings from this block, and they will become exports of the compiled module. You cannot export default, since the default export is the component itself.[!NOTE] If you are using TypeScript and import such exports from a `module` block into a `.ts` file, make sure to have your editor setup so that TypeScript knows about them. This is the case for our VS Code extension and the IntelliJ plugin, but in other cases you might need to setup our [TypeScript editor plugin](https://www.npmjs.com/package/typescript-svelte-plugin).[!LEGACY]\nIn Svelte 4, this script tag was created using `<script context=\"module\">`","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction",".svelte files","<style>"],"href":"/docs/svelte/svelte-files#style","content":"CSS inside a <style> block will be scoped to that component.<style>\n\tp {\n\t\t/* this will only affect <p> elements in this component */\n\t\tcolor: burlywood;\n\t}\n</style>For more information, head to the section on styling.","rank":null},{"breadcrumbs":["Docs","Svelte","Introduction",".svelte.js and .svelte.ts files"],"href":"/docs/svelte/svelte-js-files","content":"Besides .svelte files, Svelte also operates on .svelte.js and .svelte.ts files.These behave like any other .js or .ts module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app (though note that you cannot export reassigned state).[!LEGACY]\nThis is a concept that didn't exist prior to Svelte 5","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","What are runes?"],"href":"/docs/svelte/what-are-runes","content":"[!NOTE] **rune** /ruːn/ _noun_\n\nA letter or mark used as a mystical or magic symbol.Runes are symbols that you use in .svelte and .svelte.js/.svelte.ts files to control the Svelte compiler. If you think of Svelte as a language, runes are part of the syntax — they are keywords.Runes have a $ prefix and look like functions:let message = $state('hello');They differ from normal JavaScript functions in important ways, however:You don't need to import them — they are part of the language\nThey're not values — you can't assign them to a variable or pass them as arguments to a function\nJust like JavaScript keywords, they are only valid in certain positions (the compiler will help you if you put them in the wrong place)[!LEGACY]\nRunes didn't exist prior to Svelte 5.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state"],"href":"/docs/svelte/$state","content":"The $state rune allows you to create reactive state, which means that your UI reacts when it changes.<script>\n\tlet count = $state(0);\n</script>\n\n<button onclick={() => count++}>\n\tclicks: {count}\n</button>Unlike other frameworks you may have encountered, there is no API for interacting with state — count is just a number, rather than an object or a function, and you can update it like you would update any other variable.Deep state\nIf $state is used with an array or a simple object, the result is a deeply reactive state proxy. Proxies allow Svelte to run code when you read or write properties, including via methods like array.push(...), triggering granular updates.State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with Object.create). In a case like this...let todos = $state([\n\t{\n\t\tdone: false,\n\t\ttext: 'add more todos'\n\t}\n]);...modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:todos[0].done = !todos[0].done;If you push a new object to the array, it will also be proxified:todos.push({\n\tdone: false,\n\ttext: 'eat lunch'\n});[!NOTE] When you update properties of proxies, the original object is _not_ mutated. If you need to use your own proxy handlers in a state proxy, [you should wrap the object _after_ wrapping it in `$state`](https://svelte.dev/playground/hello-world?version=latest#H4sIAAAAAAAACpWR3WoDIRCFX2UqhWyIJL3erAulL9C7XnQLMe5ksbUqOpsfln33YuyGFNJC8UKdc2bOhw7Myk9kJXsJ0nttO9jcR5KEG9AWJDwHdzwxznbaYGTl68Do5JM_FRifuh-9X8Y9Gkq1rYx4q66cJbQUWcmqqIL2VDe2IYMEbvuOikBADi-GJDSkXG-phId0G-frye2DO2psQYDFQ0Ys8gQO350dUkEydEg82T0GOs0nsSG9g2IqgxACZueo2ZUlpdvoDC6N64qsg1QKY8T2bpZp8gpIfbCQ85Zn50Ud82HkeY83uDjspenxv3jXcSDyjPWf9L1vJf0GH666J-jLu1ery4dV257IWXBWGa0-xFDMQdTTn2ScxWKsn86ROsLwQxqrVR5QM84Ij8TKFD2-cUZSm4O2LSt30kQcvwCgCmfZnAIAAA==).Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:let { done, text } = todos[0];\n\n// this will not affect the value of `done`\ntodos[0].done = !todos[0].done;Classes\nClass instances are not proxied. Instead, you can use $state in class fields (whether public or private), or as the first assignment to a property immediately inside the constructor: \nclass Todo {\n\tdone = $state(false);\n\n\tconstructor(text) {\n\t\tthis.text = $state(text);\n\t}\n\n\treset() {\n\t\tthis.text = '';\n\t\tthis.done = false;\n\t}\n}[!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.When calling methods in JavaScript, the value of `this` matters. This won't work, because this inside the reset method will be the <button> rather than the Todo:<button onclick={todo.reset}>\n\treset\n</button>You can either use an inline function...<button onclick=+++{() => todo.reset()}>+++\n\treset\n</button>...or use an arrow function in the class definition: \nclass Todo {\n\tdone = $state(false);\n\n\tconstructor(text) {\n\t\tthis.text = $state(text);\n\t}\n\n\t+++reset = () => {+++\n\t\tthis.text = '';\n\t\tthis.done = false;\n\t}\n}Built-in classes\nSvelte provides reactive implementations of built-in classes like Set, Map, Date and URL that can be imported from `svelte/reactivity`.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state","$state.raw"],"href":"/docs/svelte/$state#$state.raw","content":"In cases where you don't want objects and arrays to be deeply reactive you can use $state.raw.State declared with $state.raw cannot be mutated; it can only be reassigned. In other words, rather than assigning to a property of an object, or using an array method like push, replace the object or array altogether if you'd like to update it:let person = $state.raw({\n\tname: 'Heraclitus',\n\tage: 49\n});\n\n// this will have no effect\nperson.age += 1;\n\n// this will work, because we're creating a new person\nperson = {\n\tname: 'Heraclitus',\n\tage: 50\n};This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can contain reactive state (for example, a raw array of reactive objects).As with $state, you can declare class fields using $state.raw.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state","$state.snapshot"],"href":"/docs/svelte/$state#$state.snapshot","content":"To take a static snapshot of a deeply reactive $state proxy, use $state.snapshot:<script>\n\tlet counter = $state({ count: 0 });\n\n\tfunction onclick() {\n\t\t// Will log `{ count: ... }` rather than `Proxy { ... }`\n\t\tconsole.log($state.snapshot(counter));\n\t}\n</script>This is handy when you want to pass some state to an external library or API that doesn't expect a proxy, such as structuredClone.If a value has a toJSON method, the snapshot will clone the value returned from toJSON instead of the original object.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state","$state.eager"],"href":"/docs/svelte/$state#$state.eager","content":"When state changes, it may not be reflected in the UI immediately if it is used by an await expression, because updates are synchronized.In some cases, you may want to update the UI as soon as the state changes. For example, you might want to update a navigation bar when the user clicks on a link, so that they get visual feedback while waiting for the new page to load. To do this, use $state.eager(value):<nav>\n\t<a href=\"/\" aria-current={$state.eager(pathname) === '/' ? 'page' : null}>home</a>\n\t<a href=\"/about\" aria-current={$state.eager(pathname) === '/about' ? 'page' : null}>about</a>\n</nav>Use this feature sparingly, and only to provide feedback in response to user action — in general, allowing Svelte to coordinate updates will provide a better user experience.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state","Passing state into functions"],"href":"/docs/svelte/$state#Passing-state-into-functions","content":"JavaScript is a pass-by-value language — when you call a function, the arguments are the values rather than the variables. In other words:/**\n * @param {number} a\n * @param {number} b\n */\nfunction add(a, b) {\n\treturn a + b;\n}\n\nlet a = 1;\nlet b = 2;\nlet total = add(a, b);\nconsole.log(total); // 3\n\na = 3;\nb = 4;\nconsole.log(total); // still 3!If add wanted to have access to the current values of a and b, and to return the current total value, you would need to use functions instead:/**\n * @param {() => number} getA\n * @param {() => number} getB\n */\nfunction add(+++getA, getB+++) {\n\treturn +++() => getA() + getB()+++;\n}\n\nlet a = 1;\nlet b = 2;\nlet total = add+++(() => a, () => b)+++;\nconsole.log(+++total()+++); // 3\n\na = 3;\nb = 4;\nconsole.log(+++total()+++); // 7State in Svelte is no different — when you reference something declared with the $state rune...let a = +++$state(1)+++;\nlet b = +++$state(2)+++;...you're accessing its current value.Note that 'functions' is broad — it encompasses properties of proxies and `get`/`set` properties.../**\n * @param {{ a: number, b: number }} input\n */\nfunction add(input) {\n\treturn {\n\t\tget value() {\n\t\t\treturn input.a + input.b;\n\t\t}\n\t};\n}\n\nlet input = $state({ a: 1, b: 2 });\nlet total = add(input);\nconsole.log(total.value); // 3\n\ninput.a = 3;\ninput.b = 4;\nconsole.log(total.value); // 7...though if you find yourself writing code like that, consider using classes instead.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$state","Passing state across modules"],"href":"/docs/svelte/$state#Passing-state-across-modules","content":"You can declare state in .svelte.js and .svelte.ts files, but you can only export that state if it's not directly reassigned. In other words you can't do this: \nexport let count = $state(0);\n\nexport function increment() {\n\tcount += 1;\n}That's because every reference to count is transformed by the Svelte compiler — the code above is roughly equivalent to this:export let count = $.state(0);\n\nexport function increment() {\n\t$.set(count, $.get(count) + 1);\n}[!NOTE] You can see the code Svelte generates by clicking the 'JS Output' tab in the [playground](/playground).Since the compiler only operates on one file at a time, if another file imports count Svelte doesn't know that it needs to wrap each reference in $.get and $.set:import { count } from './state.svelte.js';\n\nconsole.log(typeof count); // 'object', not 'number'This leaves you with two options for sharing state between modules — either don't reassign it...// This is allowed — since we're updating\n// `counter.count` rather than `counter`,\n// Svelte doesn't wrap it in `$.state`\nexport const counter = $state({\n\tcount: 0\n});\n\nexport function increment() {\n\tcounter.count += 1;\n}...or don't directly export it:let count = $state(0);\n\nexport function getCount() {\n\treturn count;\n}\n\nexport function increment() {\n\tcount += 1;\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived"],"href":"/docs/svelte/$derived","content":"Derived state is declared with the $derived rune:<script>\n\tlet count = $state(0);\n\tlet doubled = $derived(count * 2);\n</script>\n\n<button onclick={() => count++}>\n\t{doubled}\n</button>\n\n<p>{count} doubled is {doubled}</p>The expression inside $derived(...) should be free of side-effects. Svelte will disallow state changes (e.g. count++) inside derived expressions.As with $state, you can mark class fields as $derived.[!NOTE] Code in Svelte components is only executed once at creation. Without the `$derived` rune, `doubled` would maintain its original value even when `count` changes.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","$derived.by"],"href":"/docs/svelte/$derived#$derived.by","content":"Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use $derived.by which accepts a function as its argument.<script>\n\tlet numbers = $state([1, 2, 3]);\n\tlet total = $derived.by(() => {\n\t\tlet total = 0;\n\t\tfor (const n of numbers) {\n\t\t\ttotal += n;\n\t\t}\n\t\treturn total;\n\t});\n</script>\n\n<button onclick={() => numbers.push(numbers.length + 1)}>\n\t{numbers.join(' + ')} = {total}\n</button>In essence, $derived(expression) is equivalent to $derived.by(() => expression).","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","Understanding dependencies"],"href":"/docs/svelte/$derived#Understanding-dependencies","content":"Anything read synchronously inside the $derived expression (or $derived.by function body) is considered a dependency of the derived state. When the state changes, the derived will be marked as dirty and recalculated when it is next read.In addition, if an expression contains an `await`, Svelte transforms it such that any state after the await is also tracked — in other words, in a case like this...let total = $derived(await a + b);...both a and b are tracked, even though b is only read once a has resolved, after the initial execution. (This does not apply to await in functions that are called by the expression, only the expression itself.)To exempt a piece of state from being treated as a dependency, use `untrack`.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","Overriding derived values"],"href":"/docs/svelte/$derived#Overriding-derived-values","content":"Derived expressions are recalculated when their dependencies change, but you can temporarily override their values by reassigning them (unless they are declared with const). This can be useful for things like optimistic UI, where a value is derived from the 'source of truth' (such as data from your server) but you'd like to show immediate feedback to the user:<script>\n\tlet { post, like } = $props();\n\n\tlet likes = $derived(post.likes);\n\n\tasync function onclick() {\n\t\t// increment the `likes` count immediately...\n\t\tlikes += 1;\n\n\t\t// and tell the server, which will eventually update `post`\n\t\ttry {\n\t\t\tawait like();\n\t\t} catch {\n\t\t\t// failed! roll back the change\n\t\t\tlikes -= 1;\n\t\t}\n\t}\n</script>\n\n<button {onclick}>🧡 {likes}</button>[!NOTE] Prior to Svelte 5.25, deriveds were read-only.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","Deriveds and reactivity"],"href":"/docs/svelte/$derived#Deriveds-and-reactivity","content":"Unlike $state, which converts objects and arrays to deeply reactive proxies, $derived values are left as-is. For example, in a case like this... \nlet items = $state([ /*...*/ ]);\n\nlet index = $state(0);\nlet selected = $derived(items[index]);...you can change (or bind: to) properties of selected and it will affect the underlying items array. If items was not deeply reactive, mutating selected would have no effect.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","Destructuring"],"href":"/docs/svelte/$derived#Destructuring","content":"If you use destructuring with a $derived declaration, the resulting variables will all be reactive — this...let { a, b, c } = $derived(stuff());...is roughly equivalent to this:let _stuff = $derived(stuff());\nlet a = $derived(_stuff.a);\nlet b = $derived(_stuff.b);\nlet c = $derived(_stuff.c);","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$derived","Update propagation"],"href":"/docs/svelte/$derived#Update-propagation","content":"Svelte uses something called push-pull reactivity — when state is updated, everything that depends on the state (whether directly or indirectly) is immediately notified of the change (the 'push'), but derived values are not re-evaluated until they are actually read (the 'pull').If the new value of a derived is referentially identical to its previous value, downstream updates will be skipped. In other words, Svelte will only update the text inside the button when large changes, not when count changes, even though large depends on count:<script>\n\tlet count = $state(0);\n\tlet large = $derived(count > 10);\n</script>\n\n<button onclick={() => count++}>\n\t{large}\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect"],"href":"/docs/svelte/$effect","content":"Effects are functions that run when state updates, and can be used for things like calling third-party libraries, drawing on <canvas> elements, or making network requests. They only run in the browser, not during server-side rendering.Generally speaking, you should not update state inside effects, as it will make code more convoluted and will often lead to never-ending update cycles. If you find yourself doing so, see when not to use `$effect` to learn about alternative approaches.You can create an effect with the $effect rune (demo):<script>\n\tlet size = $state(50);\n\tlet color = $state('#ff3e00');\n\n\tlet canvas;\n\n\t$effect(() => {\n\t\tconst context = canvas.getContext('2d');\n\t\tcontext.clearRect(0, 0, canvas.width, canvas.height);\n\n\t\t// this will re-run whenever `color` or `size` change\n\t\tcontext.fillStyle = color;\n\t\tcontext.fillRect(0, 0, size, size);\n\t});\n</script>\n\n<canvas bind:this={canvas} width=\"100\" height=\"100\"></canvas>When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed (unless accessed inside `untrack`), and re-runs the function when that state later changes.[!NOTE] If you're having difficulty understanding why your `$effect` is rerunning or is not running see [understanding dependencies](#Understanding-dependencies). Effects are triggered differently than the `$:` blocks you may be used to if coming from Svelte 4.Understanding lifecycle\nYour effects run after the component has been mounted to the DOM, and in a microtask after state changes. Re-runs are batched (i.e. changing color and size in the same moment won't cause two separate runs), and happen after any DOM updates have been applied.You can use $effect anywhere, not just at the top level of a component, as long as it is called while a parent effect is running.[!NOTE] Svelte uses effects internally to represent logic and expressions in your template — this is how `<h1>hello {name}!</h1>` updates when `name` changes.An effect can return a teardown function which will run immediately before the effect re-runs:\n<!--- file: App.svelte --->\n<script>\n\tlet count = $state(0);\n\tlet milliseconds = $state(1000);\n\n\t$effect(() => {\n\t\t// This will be recreated whenever `milliseconds` changes\n\t\tconst interval = setInterval(() => {\n\t\t\tcount += 1;\n\t\t}, milliseconds);\n\n\t\treturn () => {\n\t\t\t// if a teardown function is provided, it will run\n\t\t\t// a) immediately before the effect re-runs\n\t\t\t// b) when the component is destroyed\n\t\t\tclearInterval(interval);\n\t\t};\n\t});\n</script>\n\n<h1>{count}</h1>\n\n<button onclick={() => (milliseconds *= 2)}>slower</button>\n<button onclick={() => (milliseconds /= 2)}>faster</button>\nTeardown functions also run when the effect is destroyed, which happens when its parent is destroyed (for example, a component is unmounted) or the parent effect re-runs.Understanding dependencies\n$effect automatically picks up any reactive values ($state, $derived, $props) that are synchronously read inside its function body (including indirectly, via function calls) and registers them as dependencies. When those dependencies change, the $effect schedules a re-run.If $state and $derived are used directly inside the $effect (for example, during creation of a reactive class), those values will not be treated as dependencies.Values that are read asynchronously — after an await or inside a setTimeout, for example — will not be tracked. Here, the canvas will be repainted when color changes, but not when size changes (demo):$effect(() => {\n\tconst context = canvas.getContext('2d');\n\tcontext.clearRect(0, 0, canvas.width, canvas.height);\n\n\t// this will re-run whenever `color` changes...\n\tcontext.fillStyle = color;\n\n\tsetTimeout(() => {\n\t\t// ...but not when `size` changes\n\t\tcontext.fillRect(0, 0, size, size);\n\t}, 0);\n});An effect only reruns when the object it reads changes, not when a property inside it changes. (If you want to observe changes inside an object at dev time, you can use `$inspect`.)<script>\n\tlet state = $state({ value: 0 });\n\tlet derived = $derived({ value: state.value * 2 });\n\n\t// this will run once, because `state` is never reassigned (only mutated)\n\t$effect(() => {\n\t\tstate;\n\t});\n\n\t// this will run whenever `state.value` changes...\n\t$effect(() => {\n\t\tstate.value;\n\t});\n\n\t// ...and so will this, because `derived` is a new object each time\n\t$effect(() => {\n\t\tderived;\n\t});\n</script>\n\n<button onclick={() => (state.value += 1)}>\n\t{state.value}\n</button>\n\n<p>{state.value} doubled is {derived.value}</p>An effect only depends on the values that it read the last time it ran. This has interesting implications for effects that have conditional code.For instance, if condition is true in the code snippet below, the code inside the if block will run and color will be evaluated. This means that changes to either condition or color will cause the effect to re-run.Conversely, if condition is false, color will not be evaluated, and the effect will only re-run again when condition changes.import confetti from 'canvas-confetti';\n\nlet condition = $state(true);\nlet color = $state('#ff3e00');\n\n$effect(() => {\n\tif (condition) {\n\t\tconfetti({ colors: [color] });\n\t} else {\n\t\tconfetti();\n\t}\n});","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect","$effect.pre"],"href":"/docs/svelte/$effect#$effect.pre","content":"In rare cases, you may need to run code before the DOM updates. For this we can use the $effect.pre rune:<script>\n\timport { tick } from 'svelte';\n\n\tlet div = $state();\n\tlet messages = $state([]);\n\n\t// ...\n\n\t$effect.pre(() => {\n\t\tif (!div) return; // not yet mounted\n\n\t\t// reference `messages` array length so that this code re-runs whenever it changes\n\t\tmessages.length;\n\n\t\t// autoscroll when new messages are added\n\t\tif (div.offsetHeight + div.scrollTop > div.scrollHeight - 20) {\n\t\t\ttick().then(() => {\n\t\t\t\tdiv.scrollTo(0, div.scrollHeight);\n\t\t\t});\n\t\t}\n\t});\n</script>\n\n<div bind:this={div}>\n\t{#each messages as message}\n\t\t<p>{message}</p>\n\t{/each}\n</div>Apart from the timing, $effect.pre works exactly like $effect.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect","$effect.tracking"],"href":"/docs/svelte/$effect#$effect.tracking","content":"The $effect.tracking rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template:\n<!--- file: App.svelte --->\n<script>\n\tconsole.log('in component setup:', $effect.tracking()); // false\n\n\t$effect(() => {\n\t\tconsole.log('in effect:', $effect.tracking()); // true\n\t});\n</script>\n\n<p>in template: {$effect.tracking()}</p> <!-- true -->\nIt is used to implement abstractions like `createSubscriber`, which will create listeners to update reactive values but only if those values are being tracked (rather than, for example, read inside an event handler).","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect","$effect.pending"],"href":"/docs/svelte/$effect#$effect.pending","content":"When using `await` in components, the $effect.pending() rune tells you how many promises are pending in the current boundary, not including child boundaries:\n<!--- file: App.svelte --->\n<script>\n\tlet a = $state(1);\n\tlet b = $state(2);\n\n\tasync function add(a, b) {\n\t\tawait new Promise((f) => setTimeout(f, 500)); // artificial delay\n\t\treturn a + b;\n\t}\n</script>\n\n<button onclick={() => a++}>a++</button>\n<button onclick={() => b++}>b++</button>\n\n<p>{a} + {b} = {await add(a, b)}</p>\n\n{#if $effect.pending()}\n\t<p>pending promises: {$effect.pending()}</p>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect","$effect.root"],"href":"/docs/svelte/$effect#$effect.root","content":"The $effect.root rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for nested effects that you want to manually control. This rune also allows for the creation of effects outside of the component initialisation phase.const destroy = $effect.root(() => {\n\t$effect(() => {\n\t\t// setup\n\t});\n\n\treturn () => {\n\t\t// cleanup\n\t};\n});\n\n// later...\ndestroy();","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$effect","When not to use `$effect`"],"href":"/docs/svelte/$effect#When-not-to-use-$effect","content":"In general, $effect is best considered something of an escape hatch — useful for things like analytics and direct DOM manipulation — rather than a tool you should use frequently. In particular, avoid using it to synchronise state. Instead of this...<script>\n\tlet count = $state(0);\n\tlet doubled = $state();\n\n\t// don't do this!\n\t$effect(() => {\n\t\tdoubled = count * 2;\n\t});\n</script>...do this:<script>\n\tlet count = $state(0);\n\tlet doubled = $derived(count * 2);\n</script>[!NOTE] For things that are more complicated than a simple expression like `count * 2`, you can also use `$derived.by`.If you're using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that deriveds can be directly overridden as of Svelte 5.25.You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for \"money spent\" and \"money left\" that are connected to each other. If you update one, the other should update accordingly. Instead of using effects for this...\n<!--- file: App.svelte --->\n<script>\n\tconst total = 100;\n\tlet spent = $state(0);\n\tlet left = $state(total);\n\n\t$effect(() => {\n\t\tleft = total - spent;\n\t});\n\n\t$effect(() => {\n\t\tspent = total - left;\n\t});\n</script>\n\n<label>\n\t<input type=\"range\" bind:value={spent} max={total} />\n\t{spent}/{total} spent\n</label>\n\n<label>\n\t<input type=\"range\" bind:value={left} max={total} />\n\t{left}/{total} left\n</label>\n\n<style>\n\tlabel {\n\t\tdisplay: flex;\n\t\tgap: 0.5em;\n\t}\n</style>\n...use oninput callbacks or — better still — function bindings where possible:\n<!--- file: App.svelte --->\n<script>\n\tconst total = 100;\n\tlet spent = $state(0);\n\tlet left = $derived(total - spent);\n\n+++\tfunction updateLeft(left) {\n\t\tspent = total - left;\n\t}+++\n</script>\n\n<label>\n\t<input type=\"range\" bind:value={spent} max={total} />\n\t{spent}/{total} spent\n</label>\n\n<label>\n\t<input type=\"range\" +++bind:value={() => left, updateLeft}+++ max={total} />\n\t{left}/{total} left\n</label>\n\n<style>\n\tlabel {\n\t\tdisplay: flex;\n\t\tgap: 0.5em;\n\t}\n</style>\nIf you absolutely have to update $state within an effect and run into an infinite loop because you read and write to the same $state, use untrack.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props"],"href":"/docs/svelte/$props","content":"The inputs to a component are referred to as props, which is short for properties. You pass props to components just like you pass attributes to elements:<!--- file: App.svelte --->\n<script>\n\timport MyComponent from './MyComponent.svelte';\n</script>\n\n<MyComponent adjective=\"cool\" />On the other side, inside MyComponent.svelte, we can receive props with the $props rune...<!--- file: MyComponent.svelte --->\n<script>\n\tlet props = $props();\n</script>\n\n<p>this component is {props.adjective}</p>...though more commonly, you'll _destructure_ your props:<!--- file: MyComponent.svelte --->\n<script>\n\tlet +++{ adjective }+++ = $props();\n</script>\n\n<p>this component is {+++adjective+++}</p>","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","Fallback values"],"href":"/docs/svelte/$props#Fallback-values","content":"Destructuring allows us to declare fallback values, which are used if the parent component does not set a given prop (or the value is undefined):let { adjective = 'happy' } = $props();[!NOTE] Fallback values are not turned into reactive state proxies (see [Updating props](#Updating-props) for more info)","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","Renaming props"],"href":"/docs/svelte/$props#Renaming-props","content":"We can also use the destructuring assignment to rename props, which is necessary if they're invalid identifiers, or a JavaScript keyword like super:let { super: trouper = 'lights are gonna find me' } = $props();","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","Rest props"],"href":"/docs/svelte/$props#Rest-props","content":"Finally, we can use a rest property to get, well, the rest of the props:let { a, b, c, ...others } = $props();","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","Updating props"],"href":"/docs/svelte/$props#Updating-props","content":"References to a prop inside a component update when the prop itself updates — when count changes in App.svelte, it will also change inside Child.svelte. But the child component is able to temporarily override the prop value, which can be useful for unsaved ephemeral state:\n<!--- file: App.svelte --->\n<script>\n\timport Child from './Child.svelte';\n\n\tlet count = $state(0);\n</script>\n\n<button onclick={() => (count += 1)}>\n\tclicks (parent): {count}\n</button>\n\n<Child {count} /><!--- file: Child.svelte --->\n<script>\n\tlet { count } = $props();\n</script>\n\n<button onclick={() => (count += 1)}>\n\tclicks (child): {count}\n</button>\nWhile you can temporarily reassign props, you should not mutate props unless they are bindable.If the prop is a regular object, the mutation will have no effect:\n<!--- file: App.svelte --->\n<script>\n\timport Child from './Child.svelte';\n</script>\n\n<Child object={{ count: 0 }} /><!--- file: Child.svelte --->\n<script>\n\tlet { object } = $props();\n</script>\n\n<button onclick={() => {\n\t// has no effect\n\tobject.count += 1\n}}>\n\tclicks: {object.count}\n</button>\nIf the prop is a reactive state proxy, however, then mutations will have an effect but you will see an `ownership_invalid_mutation` warning, because the component is mutating state that does not 'belong' to it:\n<!--- file: App.svelte --->\n<script>\n\timport Child from './Child.svelte';\n\n\tlet object = $state({count: 0});\n</script>\n\n<Child {object} /><!--- file: Child.svelte --->\n<script>\n\tlet { object } = $props();\n</script>\n\n<button onclick={() => {\n\t// will cause the count below to update,\n\t// but with a warning. Don't mutate\n\t// objects you don't own!\n\tobject.count += 1\n}}>\n\tclicks: {object.count}\n</button>\nThe fallback value of a prop not declared with $bindable is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates:\n<!--- file: App.svelte --->\n<script>\n\timport Child from './Child.svelte';\n</script>\n\n<Child /><!--- file: Child.svelte --->\n<script>\n\tlet { object = { count: 0 } } = $props();\n</script>\n\n<button onclick={() => {\n\t// has no effect if the fallback value is used\n\tobject.count += 1\n}}>\n\tclicks: {object.count}\n</button>\nIn summary: don't mutate props. Either use callback props to communicate changes, or — if parent and child should share the same object — use the `$bindable` rune.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","Type safety"],"href":"/docs/svelte/$props#Type-safety","content":"You can add type safety to your components by annotating your props, as you would with any other variable declaration. In TypeScript that might look like this...<script lang=\"ts\">\n\tlet { adjective }: { adjective: string } = $props();\n</script>...while in JSDoc you can do this:<script>\n\t/** @type {{ adjective: string }} */\n\tlet { adjective } = $props();\n</script>You can, of course, separate the type declaration from the annotation:<script lang=\"ts\">\n\tinterface Props {\n\t\tadjective: string;\n\t}\n\n\tlet { adjective }: Props = $props();\n</script>[!NOTE] Interfaces for native DOM elements are provided in the `svelte/elements` module (see [Typing wrapper components](typescript#Typing-wrapper-components))If your component exposes snippet props like children, these should be typed using the Snippet interface imported from 'svelte' — see Typing snippets for examples.Adding types is recommended, as it ensures that people using your component can easily discover which props they should provide.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$props","$props.id()"],"href":"/docs/svelte/$props#$props.id()","content":"This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered component, the value will be consistent between server and client.This is useful for linking elements via attributes like for and aria-labelledby.<script>\n\tconst uid = $props.id();\n</script>\n\n<form>\n\t<label for=\"{uid}-firstname\">First Name: </label>\n\t<input id=\"{uid}-firstname\" type=\"text\" />\n\n\t<label for=\"{uid}-lastname\">Last Name: </label>\n\t<input id=\"{uid}-lastname\" type=\"text\" />\n</form>","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$bindable"],"href":"/docs/svelte/$bindable","content":"Ordinarily, props go one way, from parent to child. This makes it easy to understand how data flows around your app.In Svelte, component props can be bound, which means that data can also flow up from child to parent. This isn't something you should do often — overuse can make your data flow unpredictable and your components harder to maintain — but it can simplify your code if used sparingly and carefully.It also means that a state proxy can be mutated in the child.[!NOTE] Mutation is also possible with normal props, but is strongly discouraged — Svelte will warn you if it detects that a component is mutating state it does not 'own'.To mark a prop as bindable, we use the $bindable rune:\n \n<script>\n\tlet { value = $bindable(), ...props } = $props();\n</script>\n\n<input bind:value={value} {...props} />\n\n<style>\n\tinput {\n\t\tfont-family: 'Comic Sans MS';\n\t\tcolor: deeppink;\n\t}\n</style>Now, a component that uses <FancyInput> can add the `bind:` directive (demo):\n \n<script>\n\timport FancyInput from './FancyInput.svelte';\n\n\tlet message = $state('hello');\n</script>\n\n<FancyInput bind:value={message} />\n<p>{message}</p>The parent component doesn't have to use bind: — it can just pass a normal prop. Some parents don't want to listen to what their children have to say.In this case, you can specify a fallback value for when no prop is passed at all: \nlet { value = $bindable('fallback'), ...props } = $props();","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$inspect"],"href":"/docs/svelte/$inspect","content":"[!NOTE] `$inspect` only works during development. In a production build it becomes a noop.The $inspect rune is roughly equivalent to console.log, with the exception that it will re-run whenever its argument changes. $inspect tracks reactive state deeply, meaning that updating something inside an object or array using fine-grained reactivity will cause it to re-fire:\n<!--- file: App.svelte --->\n<script>\n\tlet count = $state(0);\n\tlet message = $state('hello');\n\n\t$inspect(count, message); // will console.log when `count` or `message` change\n</script>\n\n<button onclick={() => count++}>Increment</button>\n<input bind:value={message} />\nOn updates, a stack trace will be printed, making it easy to find the origin of a state change (unless you're in the playground, due to technical limitations).","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$inspect","$inspect(...).with"],"href":"/docs/svelte/$inspect#$inspect().with","content":"$inspect(...) returns an object with a with method, which you can invoke with a callback that will then be invoked instead of console.log. The first argument to the callback is either \"init\" or \"update\"; subsequent arguments are the values passed to $inspect:\n<!--- file: App.svelte --->\n<script>\n\tlet count = $state(0);\n\n\t$inspect(count).with((type, count) => {\n\t\tif (type === 'update') {\n\t\t\tdebugger; // or `console.trace`, or whatever you want\n\t\t}\n\t});\n</script>\n\n<button onclick={() => count++}>Increment</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$inspect","$inspect.trace(...)"],"href":"/docs/svelte/$inspect#$inspect.trace()","content":"This rune, added in 5.14, causes the surrounding function to be traced in development. Any time the function re-runs as part of an effect or a derived, information will be printed to the console about which pieces of reactive state caused the effect to fire.<script>\n\timport { doSomeWork } from './elsewhere';\n\n\t$effect(() => {\n\t\t+++// $inspect.trace must be the first statement of a function body+++\n\t\t+++$inspect.trace();+++\n\t\tdoSomeWork();\n\t});\n</script>$inspect.trace takes an optional first argument which will be used as the label.","rank":null},{"breadcrumbs":["Docs","Svelte","Runes","$host"],"href":"/docs/svelte/$host","content":"When compiling a component as a custom element, the $host rune provides access to the host element, allowing you to (for example) dispatch custom events (demo):\n \n<svelte:options customElement=\"my-stepper\" />\n\n<script>\n\tfunction dispatch(type) {\n\t\t+++$host()+++.dispatchEvent(new CustomEvent(type));\n\t}\n</script>\n\n<button onclick={() => dispatch('decrement')}>decrement</button>\n<button onclick={() => dispatch('increment')}>increment</button>\n \n<script>\n\timport './Stepper.svelte';\n\n\tlet count = $state(0);\n</script>\n\n<my-stepper\n\tondecrement={() => count -= 1}\n\tonincrement={() => count += 1}\n></my-stepper>\n\n<p>count: {count}</p>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup"],"href":"/docs/svelte/basic-markup","content":"Markup inside a Svelte component can be thought of as HTML++.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Tags"],"href":"/docs/svelte/basic-markup#Tags","content":"A lowercase tag, like <div>, denotes a regular HTML element. A capitalised tag or a tag that uses dot notation, such as <Widget> or <my.stuff>, indicates a component.<script>\n\timport Widget from './Widget.svelte';\n</script>\n\n<div>\n\t<Widget />\n</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Element attributes"],"href":"/docs/svelte/basic-markup#Element-attributes","content":"By default, attributes work exactly like their HTML counterparts.<div class=\"foo\">\n\t<button disabled>can't touch this</button>\n</div>As in HTML, values may be unquoted.\n<input type=checkbox />Attribute values can contain JavaScript expressions.<a href=\"page/{p}\">page {p}</a>Or they can be JavaScript expressions.<button disabled={!clickable}>...</button>Boolean attributes are included on the element if their value is truthy and excluded if it's falsy.All other attributes are included unless their value is nullish (null or undefined).<input required={false} placeholder=\"This input field is not required\" />\n<div title={null}>This div has no title attribute</div>[!NOTE] Quoting a singular expression does not affect how the value is parsed, but in Svelte 6 it will cause the value to be coerced to a string:\n\n<!-- prettier-ignore -->\n```svelte\n<button disabled=\"{number !== 42}\">...</button>\n```When the attribute name and value match (name={name}), they can be replaced with {name}.<button {disabled}>...</button>\n<!-- equivalent to\n<button disabled={disabled}>...</button>\n-->","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Component props"],"href":"/docs/svelte/basic-markup#Component-props","content":"By convention, values passed to components are referred to as properties or props rather than attributes, which are a feature of the DOM.As with elements, name={name} can be replaced with the {name} shorthand.<Widget foo={bar} answer={42} text=\"hello\" />","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Spread attributes"],"href":"/docs/svelte/basic-markup#Spread-attributes","content":"Spread attributes allow many attributes or properties to be passed to an element or component at once.An element or component can have multiple spread attributes, interspersed with regular ones. Order matters — if things.a exists it will take precedence over a=\"b\", while c=\"d\" would take precedence over things.c:<Widget a=\"b\" {...things} c=\"d\" />","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Events"],"href":"/docs/svelte/basic-markup#Events","content":"Listening to DOM events is possible by adding attributes to the element that start with on. For example, to listen to the click event, add the onclick attribute to a button:<button onclick={() => console.log('clicked')}>click me</button>Event attributes are case sensitive. onclick listens to the click event, onClick listens to the Click event, which is different. This ensures you can listen to custom events that have uppercase characters in them.Because events are just attributes, the same rules as for attributes apply:you can use the shorthand form: `<button {onclick}>click me</button>`\nyou can spread them: `<button {...thisSpreadContainsEventAttributes}>click me</button>`Timing-wise, event attributes always fire after events from bindings (e.g. oninput always fires after an update to bind:value). Under the hood, some event handlers are attached directly with addEventListener, while others are delegated.When using ontouchstart and ontouchmove event attributes, the handlers are passive for better performance. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls event.preventDefault().In the very rare cases that you need to prevent these event defaults, you should use `on` instead (for example inside an action).","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Events","Event delegation"],"href":"/docs/svelte/basic-markup#Events-Event-delegation","content":"To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event's path.There are a few gotchas to be aware of:when you manually dispatch an event with a delegated listener, make sure to set the `{ bubbles: true }` option or it won't reach the application root\nwhen using `addEventListener` directly, avoid calling `stopPropagation` or the event won't reach the application root and handlers won't be invoked. Similarly, handlers added manually inside the application root will run _before_ handlers added declaratively deeper in the DOM (with e.g. `onclick={...}`), in both capturing and bubbling phases. For these reasons it's better to use the `on` function imported from `svelte/events` rather than `addEventListener`, as it will ensure that order is preserved and `stopPropagation` is handled correctly.The following event handlers are delegated:`beforeinput`\n`click`\n`change`\n`dblclick`\n`contextmenu`\n`focusin`\n`focusout`\n`input`\n`keydown`\n`keyup`\n`mousedown`\n`mousemove`\n`mouseout`\n`mouseover`\n`mouseup`\n`pointerdown`\n`pointermove`\n`pointerout`\n`pointerover`\n`pointerup`\n`touchend`\n`touchmove`\n`touchstart`","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Text expressions"],"href":"/docs/svelte/basic-markup#Text-expressions","content":"A JavaScript expression can be included as text by surrounding it with curly braces.{expression}Expressions that are null or undefined will be omitted; all others are coerced to strings.Curly braces can be included in a Svelte template by using their HTML entity strings: &lbrace;, &lcub;, or { for { and &rbrace;, &rcub;, or } for }.If you're using a regular expression (RegExp) literal notation, you'll need to wrap it in parentheses.\n<h1>Hello {name}!</h1>\n<p>{a} + {b} = {a + b}.</p>\n\n<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>The expression will be stringified and escaped to prevent code injections. If you want to render HTML, use the {@html} tag instead.{@html potentiallyUnsafeHtmlString}[!NOTE] Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/)","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","Basic markup","Comments"],"href":"/docs/svelte/basic-markup#Comments","content":"You can use HTML comments inside components.<!-- this is a comment! --><h1>Hello world</h1>Comments beginning with svelte-ignore disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.<!-- svelte-ignore a11y_autofocus -->\n<input bind:value={name} autofocus />You can add a special comment starting with @component that will show up when hovering over the component name in other files.<!--\n@component\n- You can use markdown here.\n- You can also use code blocks here.\n- Usage:\n  ```html\n  <Main name=\"Arethra\">\n  ```\n-->\n<script>\n\tlet { name } = $props();\n</script>\n\n<main>\n\t<h1>\n\t\tHello, {name}\n\t</h1>\n</main>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#if ...}"],"href":"/docs/svelte/if","content":"<!--- copy: false  --->\n{#if expression}...{/if}<!--- copy: false  --->\n{#if expression}...{:else if expression}...{/if}<!--- copy: false  --->\n{#if expression}...{:else}...{/if}Content that is conditionally rendered can be wrapped in an if block.{#if answer === 42}\n\t<p>what was the question?</p>\n{/if}Additional conditions can be added with {:else if expression}, optionally ending in an {:else} clause.{#if porridge.temperature > 100}\n\t<p>too hot!</p>\n{:else if 80 > porridge.temperature}\n\t<p>too cold!</p>\n{:else}\n\t<p>just right!</p>\n{/if}(Blocks don't have to wrap elements, they can also wrap text within elements.)","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#each ...}"],"href":"/docs/svelte/each","content":"<!--- copy: false  --->\n{#each expression as name}...{/each}<!--- copy: false  --->\n{#each expression as name, index}...{/each}Iterating over values can be done with an each block. The values in question can be arrays, array-like objects (i.e. anything with a length property), or iterables like Map and Set. (Internally, they are converted to arrays with `Array.from`.)If the value is null or undefined, it is treated the same as an empty array (which will cause else blocks to be rendered, where applicable).<h1>Shopping list</h1>\n<ul>\n\t{#each items as item}\n\t\t<li>{item.name} x {item.qty}</li>\n\t{/each}\n</ul>An each block can also specify an index, equivalent to the second argument in an array.map(...) callback:{#each items as item, i}\n\t<li>{i + 1}: {item.name} x {item.qty}</li>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#each ...}","Keyed each blocks"],"href":"/docs/svelte/each#Keyed-each-blocks","content":"<!--- copy: false  --->\n{#each expression as name (key)}...{/each}<!--- copy: false  --->\n{#each expression as name, index (key)}...{/each}If a key expression is provided — which must uniquely identify each list item — Svelte will use it to intelligently update the list when data changes by inserting, moving and deleting items, rather than adding or removing items at the end and updating the state in the middle.The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.{#each items as item (item.id)}\n\t<li>{item.name} x {item.qty}</li>\n{/each}\n\n<!-- or with additional index value -->\n{#each items as item, i (item.id)}\n\t<li>{i + 1}: {item.name} x {item.qty}</li>\n{/each}You can freely use destructuring and rest patterns in each blocks.{#each items as { id, name, qty }, i (id)}\n\t<li>{i + 1}: {name} x {qty}</li>\n{/each}\n\n{#each objects as { id, ...rest }}\n\t<li><span>{id}</span><MyComponent {...rest} /></li>\n{/each}\n\n{#each items as [id, ...rest]}\n\t<li><span>{id}</span><MyComponent values={rest} /></li>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#each ...}","Each blocks without an item"],"href":"/docs/svelte/each#Each-blocks-without-an-item","content":"<!--- copy: false  --->\n{#each expression}...{/each}<!--- copy: false  --->\n{#each expression, index}...{/each}In case you just want to render something n times, you can omit the as part:\n<!--- file: App.svelte --->\n<div class=\"chess-board\">\n\t{#each { length: 8 }, rank}\n\t\t{#each { length: 8 }, file}\n\t\t\t<div class:black={(rank + file) % 2 === 1}></div>\n\t\t{/each}\n\t{/each}\n</div>\n\n<style>\n\t.chess-board {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(8, 1fr);\n\t\tgrid-template-rows: repeat(8, 1fr);\n\t\tborder: 1px solid black;\n\t\taspect-ratio: 1;\n\n\t\t.black {\n\t\t\tbackground: black;\n\t\t}\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#each ...}","Else blocks"],"href":"/docs/svelte/each#Else-blocks","content":"<!--- copy: false  --->\n{#each expression as name}...{:else}...{/each}An each block can also have an {:else} clause, which is rendered if the list is empty.{#each todos as todo}\n\t<p>{todo.text}</p>\n{:else}\n\t<p>No tasks today!</p>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#key ...}"],"href":"/docs/svelte/key","content":"<!--- copy: false  --->\n{#key expression}...{/key}Key blocks destroy and recreate their contents when the value of an expression changes. When used around components, this will cause them to be reinstantiated and reinitialised:{#key value}\n\t<Component />\n{/key}It's also useful if you want a transition to play whenever a value changes:{#key value}\n\t<div transition:fade>{value}</div>\n{/key}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#await ...}"],"href":"/docs/svelte/await","content":"<!--- copy: false  --->\n{#await expression}...{:then name}...{:catch name}...{/await}<!--- copy: false  --->\n{#await expression}...{:then name}...{/await}<!--- copy: false  --->\n{#await expression then name}...{/await}<!--- copy: false  --->\n{#await expression catch name}...{/await}Await blocks allow you to branch on the three possible states of a `Promise` — pending, fulfilled or rejected.{#await promise}\n\t<!-- promise is pending -->\n\t<p>waiting for the promise to resolve...</p>\n{:then value}\n\t<!-- promise was fulfilled or not a Promise -->\n\t<p>The value is {value}</p>\n{:catch error}\n\t<!-- promise was rejected -->\n\t<p>Something went wrong: {error.message}</p>\n{/await}[!NOTE] During server-side rendering, only the pending branch will be rendered.\n\nIf the provided expression is not a `Promise`, only the `:then` branch will be rendered, including during server-side rendering.The catch block can be omitted if you don't need to render anything when the promise rejects (or no error is possible).{#await promise}\n\t<!-- promise is pending -->\n\t<p>waiting for the promise to resolve...</p>\n{:then value}\n\t<!-- promise was fulfilled -->\n\t<p>The value is {value}</p>\n{/await}If you don't care about the pending state, you can also omit the initial block.{#await promise then value}\n\t<p>The value is {value}</p>\n{/await}Similarly, if you only want to show the error state, you can omit the then block.{#await promise catch error}\n\t<p>The error is {error}</p>\n{/await}[!NOTE] You can use `#await` with [`import(...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) to render components lazily:\n\n```svelte\n{#await import('./Component.svelte') then { default: Component }}\n\t<Component />\n{/await}\n```","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}"],"href":"/docs/svelte/snippet","content":"<!--- copy: false  --->\n{#snippet name()}...{/snippet}<!--- copy: false  --->\n{#snippet name(param1, param2, paramN)}...{/snippet}Snippets, and render tags, are a way to create reusable chunks of markup inside your components. Instead of writing duplicative code like this...{#each images as image}\n\t{#if image.href}\n\t\t<a href={image.href}>\n\t\t\t<figure>\n\t\t\t\t<img src={image.src} alt={image.caption} width={image.width} height={image.height} />\n\t\t\t\t<figcaption>{image.caption}</figcaption>\n\t\t\t</figure>\n\t\t</a>\n\t{:else}\n\t\t<figure>\n\t\t\t<img src={image.src} alt={image.caption} width={image.width} height={image.height} />\n\t\t\t<figcaption>{image.caption}</figcaption>\n\t\t</figure>\n\t{/if}\n{/each}...you can write this:{#snippet figure(image)}\n\t<figure>\n\t\t<img src={image.src} alt={image.caption} width={image.width} height={image.height} />\n\t\t<figcaption>{image.caption}</figcaption>\n\t</figure>\n{/snippet}\n\n{#each images as image}\n\t{#if image.href}\n\t\t<a href={image.href}>\n\t\t\t{@render figure(image)}\n\t\t</a>\n\t{:else}\n\t\t{@render figure(image)}\n\t{/if}\n{/each}Like function declarations, snippets can have an arbitrary number of parameters, which can have default values, and you can destructure each parameter. You cannot use rest parameters, however.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Snippet scope"],"href":"/docs/svelte/snippet#Snippet-scope","content":"Snippets can be declared anywhere inside your component. They can reference values declared outside themselves, for example in the <script> tag or in {#each ...} blocks...\n<!--- file: App.svelte --->\n<script>\n\tlet { message = `it's great to see you!` } = $props();\n</script>\n\n{#snippet hello(name)}\n\t<p>hello {name}! {message}!</p>\n{/snippet}\n\n{@render hello('alice')}\n{@render hello('bob')}\n...and they are 'visible' to everything in the same lexical scope (i.e. siblings, and children of those siblings):<div>\n\t{#snippet x()}\n\t\t{#snippet y()}...{/snippet}\n\n\t\t<!-- this is fine -->\n\t\t{@render y()}\n\t{/snippet}\n\n\t<!-- this will error, as `y` is not in scope -->\n\t{@render y()}\n</div>\n\n<!-- this will also error, as `x` is not in scope -->\n{@render x()}Snippets can reference themselves and each other:\n<!--- file: App.svelte --->\n{#snippet blastoff()}\n\t<span>🚀</span>\n{/snippet}\n\n{#snippet countdown(n)}\n\t{#if n > 0}\n\t\t<span>{n}...</span>\n\t\t{@render countdown(n - 1)}\n\t{:else}\n\t\t{@render blastoff()}\n\t{/if}\n{/snippet}\n\n{@render countdown(10)}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Passing snippets to components"],"href":"/docs/svelte/snippet#Passing-snippets-to-components","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Passing snippets to components","Explicit props"],"href":"/docs/svelte/snippet#Passing-snippets-to-components-Explicit-props","content":"Within the template, snippets are values just like any other. As such, they can be passed to components as props:\n<!--- file: App.svelte --->\n<script>\n\timport Table from './Table.svelte';\n\n\tconst fruits = [\n\t\t{ name: 'apples', qty: 5, price: 2 },\n\t\t{ name: 'bananas', qty: 10, price: 1 },\n\t\t{ name: 'cherries', qty: 20, price: 0.5 }\n\t];\n</script>\n\n{#snippet header()}\n\t<th>fruit</th>\n\t<th>qty</th>\n\t<th>price</th>\n\t<th>total</th>\n{/snippet}\n\n{#snippet row(d)}\n\t<td>{d.name}</td>\n\t<td>{d.qty}</td>\n\t<td>{d.price}</td>\n\t<td>{d.qty * d.price}</td>\n{/snippet}\n\n<Table data={fruits} +++{header} {row}+++ /><!--- file: Table.svelte --->\n<script>\n\tlet { data, header, row } = $props();\n</script>\n\n<table>\n\t{#if header}\n\t\t<thead>\n\t\t\t<tr>{@render header()}</tr>\n\t\t</thead>\n\t{/if}\n\n\t<tbody>\n\t\t{#each data as d}\n\t\t\t<tr>{@render row(d)}</tr>\n\t\t{/each}\n\t</tbody>\n</table>\n\n<style>\n\ttable {\n\t\ttext-align: left;\n\t\tborder-spacing: 0;\n\t}\n\n\ttbody tr:nth-child(2n+1) {\n\t\tbackground: ButtonFace;\n\t}\n\n\ttable :global(th), table :global(td) {\n\t\tpadding: 0.5em;\n\t}\n</style>\nThink about it like passing content instead of data to a component. The concept is similar to slots in web components.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Passing snippets to components","Implicit props"],"href":"/docs/svelte/snippet#Passing-snippets-to-components-Implicit-props","content":"As an authoring convenience, snippets declared directly inside a component implicitly become props on the component:\n<!--- file: App.svelte --->\n<script>\n\timport Table from './Table.svelte';\n\n\tconst fruits = [\n\t\t{ name: 'apples', qty: 5, price: 2 },\n\t\t{ name: 'bananas', qty: 10, price: 1 },\n\t\t{ name: 'cherries', qty: 20, price: 0.5 }\n\t];\n</script>\n\n<Table data={fruits}>\n\t{#snippet header()}\n\t\t<th>fruit</th>\n\t\t<th>qty</th>\n\t\t<th>price</th>\n\t\t<th>total</th>\n\t{/snippet}\n\n\t{#snippet row(d)}\n\t\t<td>{d.name}</td>\n\t\t<td>{d.qty}</td>\n\t\t<td>{d.price}</td>\n\t\t<td>{d.qty * d.price}</td>\n\t{/snippet}\n</Table><!--- file: Table.svelte --->\n<script>\n\tlet { data, header, row } = $props();\n</script>\n\n<table>\n\t{#if header}\n\t\t<thead>\n\t\t\t<tr>{@render header()}</tr>\n\t\t</thead>\n\t{/if}\n\n\t<tbody>\n\t\t{#each data as d}\n\t\t\t<tr>{@render row(d)}</tr>\n\t\t{/each}\n\t</tbody>\n</table>\n\n<style>\n\ttable {\n\t\ttext-align: left;\n\t\tborder-spacing: 0;\n\t}\n\n\ttbody tr:nth-child(2n+1) {\n\t\tbackground: ButtonFace;\n\t}\n\n\ttable :global(th), table :global(td) {\n\t\tpadding: 0.5em;\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Passing snippets to components","Implicit `children` snippet"],"href":"/docs/svelte/snippet#Passing-snippets-to-components-Implicit-children-snippet","content":"Any content inside the component tags that is not a snippet declaration implicitly becomes part of the children snippet:\n<!--- file: App.svelte --->\n<script>\n\timport Button from './Button.svelte';\n</script>\n\n<Button>click me</Button><!--- file: Button.svelte --->\n<script>\n\tlet { children } = $props();\n</script>\n\n<!-- result will be <button>click me</button> -->\n<button>{@render children()}</button>\n[!NOTE] Note that you cannot have a prop called `children` if you also have content inside the component — for this reason, you should avoid having props with that name","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Passing snippets to components","Optional snippet props"],"href":"/docs/svelte/snippet#Passing-snippets-to-components-Optional-snippet-props","content":"You can declare snippet props as being optional. You can either use optional chaining to not render anything if the snippet isn't set...<script>\n    let { children } = $props();\n</script>\n\n{@render children?.()}...or use an #if block to render fallback content:<script>\n    let { children } = $props();\n</script>\n\n{#if children}\n    {@render children()}\n{:else}\n    fallback content\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Typing snippets"],"href":"/docs/svelte/snippet#Typing-snippets","content":"Snippets implement the Snippet interface imported from 'svelte':<script lang=\"ts\">\n\timport type { Snippet } from 'svelte';\n\n\tinterface Props {\n\t\tdata: any[];\n\t\tchildren: Snippet;\n\t\trow: Snippet<[any]>;\n\t}\n\n\tlet { data, children, row }: Props = $props();\n</script>With this change, red squigglies will appear if you try and use the component without providing a data prop and a row snippet. Notice that the type argument provided to Snippet is a tuple, since snippets can have multiple parameters.We can tighten things up further by declaring a generic, so that data and row refer to the same type:<script lang=\"ts\" generics=\"T\">\n\timport type { Snippet } from 'svelte';\n\n\tlet {\n\t\tdata,\n\t\tchildren,\n\t\trow\n\t}: {\n\t\tdata: T[];\n\t\tchildren: Snippet;\n\t\trow: Snippet<[T]>;\n\t} = $props();\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Exporting snippets"],"href":"/docs/svelte/snippet#Exporting-snippets","content":"Snippets declared at the top level of a .svelte file can be exported from a <script module> for use in other components, provided they don't reference any declarations in a non-module <script> (whether directly or indirectly, via other snippets):\n<!--- file: App.svelte --->\n<script>\n\timport { add } from './snippets.svelte';\n</script>\n\n{@render add(1, 2)}\n<!--- file: snippets.svelte --->\n<script module>\n\texport { add };\n</script>\n\n{#snippet add(a, b)}\n\t{a} + {b} = {a + b}\n{/snippet}\n[!NOTE]\nThis requires Svelte 5.5.0 or newer","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Programmatic snippets"],"href":"/docs/svelte/snippet#Programmatic-snippets","content":"Snippets can be created programmatically with the `createRawSnippet` API. This is intended for advanced use cases.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{#snippet ...}","Snippets and slots"],"href":"/docs/svelte/snippet#Snippets-and-slots","content":"In Svelte 4, content can be passed to components using slots. Snippets are more powerful and flexible, and so slots have been deprecated in Svelte 5.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@render ...}"],"href":"/docs/svelte/@render","content":"To render a snippet, use a {@render ...} tag.{#snippet sum(a, b)}\n\t<p>{a} + {b} = {a + b}</p>\n{/snippet}\n\n{@render sum(1, 2)}\n{@render sum(3, 4)}\n{@render sum(5, 6)}The expression can be an identifier like sum, or an arbitrary JavaScript expression:{@render (cool ? coolSnippet : lameSnippet)()}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@render ...}","Optional snippets"],"href":"/docs/svelte/@render#Optional-snippets","content":"If the snippet is potentially undefined — for example, because it's an incoming prop — then you can use optional chaining to only render it when it is defined:{@render children?.()}Alternatively, use an `{#if ...}` block with an :else clause to render fallback content:{#if children}\n\t{@render children()}\n{:else}\n\t<p>fallback content</p>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@html ...}"],"href":"/docs/svelte/@html","content":"To inject raw HTML into your component, use the {@html ...} tag:<article>\n\t{@html content}\n</article>[!NOTE] Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/). Never render unsanitized content.The expression should be valid standalone HTML — this will not work, because </div> is not valid HTML:{@html '<div>'}content{@html '</div>'}It also will not compile Svelte code.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@html ...}","Styling"],"href":"/docs/svelte/@html#Styling","content":"Content rendered this way is 'invisible' to Svelte and as such will not receive scoped styles. In other words, this will not work, and the a and img styles will be regarded as unused:\n<article>\n\t{@html content}\n</article>\n\n<style>\n\tarticle {\n\t\ta { color: hotpink }\n\t\timg { width: 100% }\n\t}\n</style>Instead, use the :global modifier to target everything inside the <article>:\n<style>\n\tarticle +++:global+++ {\n\t\ta { color: hotpink }\n\t\timg { width: 100% }\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}"],"href":"/docs/svelte/@attach","content":"Attachments are functions that run in an effect when an element is mounted to the DOM or when state read inside the function updates.Optionally, they can return a function that is called before the attachment re-runs, or after the element is later removed from the DOM.[!NOTE]\nAttachments are available in Svelte 5.29 and newer.<!--- file: App.svelte --->\n<script>\n\t/** @type {import('svelte/attachments').Attachment} */\n\tfunction myAttachment(element) {\n\t\tconsole.log(element.nodeName); // 'DIV'\n\n\t\treturn () => {\n\t\t\tconsole.log('cleaning up');\n\t\t};\n\t}\n</script>\n\n<div {@attach myAttachment}>...</div>An element can have any number of attachments.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Attachment factories"],"href":"/docs/svelte/@attach#Attachment-factories","content":"A useful pattern is for a function, such as tooltip in this example, to return an attachment (demo):<!--- file: App.svelte --->\n<script>\n\timport tippy from 'tippy.js';\n\n\tlet content = $state('Hello!');\n\n\t/**\n\t * @param {string} content\n\t * @returns {import('svelte/attachments').Attachment}\n\t */\n\tfunction tooltip(content) {\n\t\treturn (element) => {\n\t\t\tconst tooltip = tippy(element, { content });\n\t\t\treturn tooltip.destroy;\n\t\t};\n\t}\n</script>\n\n<input bind:value={content} />\n\n<button {@attach tooltip(content)}>\n\tHover me\n</button>Since the tooltip(content) expression runs inside an effect, the attachment will be destroyed and recreated whenever content changes. The same thing would happen for any state read inside the attachment function when it first runs. (If this isn't what you want, see Controlling when attachments re-run.)","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Inline attachments"],"href":"/docs/svelte/@attach#Inline-attachments","content":"Attachments can also be created inline (demo):<!--- file: App.svelte --->\n<canvas\n\twidth={32}\n\theight={32}\n\t{@attach (canvas) => {\n\t\tconst context = canvas.getContext('2d');\n\n\t\t$effect(() => {\n\t\t\tcontext.fillStyle = color;\n\t\t\tcontext.fillRect(0, 0, canvas.width, canvas.height);\n\t\t});\n\t}}\n></canvas>[!NOTE]\nThe nested effect runs whenever `color` changes, while the outer effect (where `canvas.getContext(...)` is called) only runs once, since it doesn't read any reactive state.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Conditional attachments"],"href":"/docs/svelte/@attach#Conditional-attachments","content":"Falsy values like false or undefined are treated as no attachment, enabling conditional usage:<div {@attach enabled && myAttachment}>...</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Passing attachments to components"],"href":"/docs/svelte/@attach#Passing-attachments-to-components","content":"When used on a component, {@attach ...} will create a prop whose key is a `Symbol`. If the component then spreads props onto an element, the element will receive those attachments.This allows you to create wrapper components that augment elements (demo):<!--- file: Button.svelte --->\n<script>\n\t/** @type {import('svelte/elements').HTMLButtonAttributes} */\n\tlet { children, ...props } = $props();\n</script>\n\n<!-- `props` includes attachments -->\n<button {...props}>\n\t{@render children?.()}\n</button><!--- file: App.svelte --->\n<script>\n\timport tippy from 'tippy.js';\n\timport Button from './Button.svelte';\n\n\tlet content = $state('Hello!');\n\n\t/**\n\t * @param {string} content\n\t * @returns {import('svelte/attachments').Attachment}\n\t */\n\tfunction tooltip(content) {\n\t\treturn (element) => {\n\t\t\tconst tooltip = tippy(element, { content });\n\t\t\treturn tooltip.destroy;\n\t\t};\n\t}\n</script>\n\n<input bind:value={content} />\n\n<Button {@attach tooltip(content)}>\n\tHover me\n</Button>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Controlling when attachments re-run"],"href":"/docs/svelte/@attach#Controlling-when-attachments-re-run","content":"Attachments, unlike actions, are fully reactive: {@attach foo(bar)} will re-run on changes to foo or bar (or any state read inside foo): \nfunction foo(bar) {\n\treturn (node) => {\n\t\tveryExpensiveSetupWork(node);\n\t\tupdate(node, bar);\n\t};\n}In the rare case that this is a problem (for example, if foo does expensive and unavoidable setup work) consider passing the data inside a function and reading it in a child effect: \nfunction foo(+++getBar+++) {\n\treturn (node) => {\n\t\tveryExpensiveSetupWork(node);\n\n+++\t\t$effect(() => {\n\t\t\tupdate(node, getBar());\n\t\t});+++\n\t}\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Creating attachments programmatically"],"href":"/docs/svelte/@attach#Creating-attachments-programmatically","content":"To add attachments to an object that will be spread onto a component or element, use `createAttachmentKey`.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@attach ...}","Converting actions to attachments"],"href":"/docs/svelte/@attach#Converting-actions-to-attachments","content":"If you're using a library that only provides actions, you can convert them to attachments with `fromAction`, allowing you to (for example) use them with components.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@const ...}"],"href":"/docs/svelte/@const","content":"[!NOTE] `{@const x = y}` is legacy syntax — use [`{const x = $derived(y)}`](declaration-tags) insteadThe {@const ...} tag defines a local constant.{#each boxes as box}\n\t{@const area = box.width * box.height}\n\t{box.width} * {box.height} = {area}\n{/each}{@const} is only allowed as an immediate child of a block — {#if ...}, {#each ...}, {#snippet ...} and so on — a <Component /> or a <svelte:boundary>.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{@debug ...}"],"href":"/docs/svelte/@debug","content":"The {@debug ...} tag offers an alternative to console.log(...). It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.<script>\n\tlet user = {\n\t\tfirstname: 'Ada',\n\t\tlastname: 'Lovelace'\n\t};\n</script>\n\n{@debug user}\n\n<h1>Hello {user.firstname}!</h1>{@debug ...} accepts a comma-separated list of variable names (not arbitrary expressions).<!-- Compiles -->\n{@debug user}\n{@debug user1, user2, user3}\n\n<!-- WON'T compile -->\n{@debug user.firstname}\n{@debug myArray[0]}\n{@debug !isReady}\n{@debug typeof user === 'object'}The {@debug} tag without any arguments will insert a debugger statement that gets triggered when any state changes, as opposed to the specified variables.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","{let/const ...}"],"href":"/docs/svelte/declaration-tags","content":"Declaration tags define local variables inside markup with const or let:\n<!--- file: App.svelte --->\n<script>\n\tlet boxes = [{ width: 10, height: 10 }, { width: 15, height: 15 }];\n</script>\n\n{#each boxes as box}\n\t{const area = box.width * box.height}\n\t{const label = `${box.width} ⨉ ${box.height} = ${area}`}\n\n\t<p>{label}</p>\n{/each}\n[!NOTE] Declaration tags are available since Svelte 5.56.[!NOTE] The [`{@const ...}`](@const) syntax is considered legacy — use declaration tags instead.When values should be reactive, you can use $state and $derived:\n<!--- file: App.svelte --->\n<script>\n\tlet user = $state({ name: 'Svelte' });\n\tlet editing = $state(false);\n</script>\n\n<p>Hello {user.name}</p>\n<button onclick={() => editing = true}>edit name</button>\n\n{#if editing}\n\t{let name = $state(user.name)}\n\t{const greeting = $derived(`Hello ${name}`)}\n\n\t<hr>\n\t<input bind:value={name} />\n\t<p>{greeting}</p>\n\n\t<button onclick={() => {\n\t\tuser.name = name;\n\t\tediting = false;\n\t}}>save</button>\n{/if}\nDeclaration tags can be used anywhere inside the component. They can reference values declared outside themselves (for example in the <script> tag or in {#each ...} blocks) and are 'visible' to everything in the same lexical scope (i.e. siblings, and children of those siblings):\n<!--- file: App.svelte --->\n{const hello = 'hello'}\n{hello} <!-- 'hello' -->\n<div>\n\t{const hello = 'hi'}\n\t{hello} <!-- 'hi' -->\n\t<div>\n\t\t{hello} <!-- 'hi' -->\n\t</div>\n</div>\n{hello} <!-- 'hello' -->","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:"],"href":"/docs/svelte/bind","content":"Data ordinarily flows down, from parent to child. The bind: directive allows data to flow the other way, from child to parent.The general syntax is bind:property={expression}, where expression is an _lvalue_ (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:\n<input bind:value={value} />\n<input bind:value />Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.Most bindings are two-way, meaning that changes to the value will affect the element and vice versa. A few bindings are readonly, meaning that changing their value will have no effect on the element.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","Function bindings"],"href":"/docs/svelte/bind#Function-bindings","content":"You can also use bind:property={get, set}, where get and set are functions, allowing you to perform validation and transformation:<input bind:value={\n\t() => value,\n\t(v) => value = v.toLowerCase()}\n/>In the case of readonly bindings like dimension bindings, the get value should be null:<div\n\tbind:clientWidth={null, redraw}\n\tbind:clientHeight={null, redraw}\n>...</div>[!NOTE]\nFunction bindings are available in Svelte 5.9.0 and newer.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<input bind:value>"],"href":"/docs/svelte/bind#input-bind:value","content":"A bind:value directive on an <input> element binds the input's value property:\n<script>\n\tlet message = $state('hello');\n</script>\n\n<input bind:value={message} />\n<p>{message}</p>In the case of a numeric input (type=\"number\" or type=\"range\"), the value will be coerced to a number:\n<!--- file: App.svelte --->\n<script>\n\tlet a = $state(1);\n\tlet b = $state(2);\n</script>\n\n<label>\n\t<input type=\"number\" bind:value={a} min=\"0\" max=\"10\" />\n\t<input type=\"range\" bind:value={a} min=\"0\" max=\"10\" />\n</label>\n\n<label>\n\t<input type=\"number\" bind:value={b} min=\"0\" max=\"10\" />\n\t<input type=\"range\" bind:value={b} min=\"0\" max=\"10\" />\n</label>\n\n<p>{a} + {b} = {a + b}</p>\nIf the input is empty or invalid (in the case of type=\"number\"), the value is undefined.Since 5.6.0, if an <input> has a defaultValue and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is null or undefined.<script>\n\tlet value = $state('');\n</script>\n\n<form>\n\t<input bind:value defaultValue=\"not the empty string\">\n\t<input type=\"reset\" value=\"Reset\">\n</form>[!NOTE]\nUse reset buttons sparingly, and ensure that users won't accidentally click them while trying to submit the form.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<input bind:checked>"],"href":"/docs/svelte/bind#input-bind:checked","content":"Checkbox inputs can be bound with bind:checked:<label>\n\t<input type=\"checkbox\" bind:checked={accepted} />\n\tAccept terms and conditions\n</label>Since 5.6.0, if an <input> has a defaultChecked attribute and is part of a form, it will revert to that value instead of false when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is null or undefined.<script>\n\tlet checked = $state(true);\n</script>\n\n<form>\n\t<input type=\"checkbox\" bind:checked defaultChecked={true}>\n\t<input type=\"reset\" value=\"Reset\">\n</form>[!NOTE] Use `bind:group` for radio inputs instead of `bind:checked`.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<input bind:indeterminate>"],"href":"/docs/svelte/bind#input-bind:indeterminate","content":"Checkboxes can be in an indeterminate state, independently of whether they are checked or unchecked:<script>\n\tlet checked = $state(false);\n\tlet indeterminate = $state(true);\n</script>\n\n<form>\n\t<input type=\"checkbox\" bind:checked bind:indeterminate>\n\n\t{#if indeterminate}\n\t\twaiting...\n\t{:else if checked}\n\t\tchecked\n\t{:else}\n\t\tunchecked\n\t{/if}\n</form>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<input bind:group>"],"href":"/docs/svelte/bind#input-bind:group","content":"Inputs that work together can use bind:group:\n<!--- file: App.svelte --->\n<script>\n\tlet tortilla = $state('Plain');\n\n\t/** @type {string[]} */\n\tlet fillings = $state([]);\n</script>\n\n<h1>Customize your burrito</h1>\n\n<!-- grouped radio inputs are mutually exclusive -->\n<label><input type=\"radio\" bind:group={tortilla} value=\"Plain\" /> Plain</label>\n<label><input type=\"radio\" bind:group={tortilla} value=\"Whole wheat\" /> Whole wheat</label>\n<label><input type=\"radio\" bind:group={tortilla} value=\"Spinach\" /> Spinach</label>\n\n<!-- grouped checkbox inputs populate an array -->\n<label><input type=\"checkbox\" bind:group={fillings} value=\"Rice\" /> Rice</label>\n<label><input type=\"checkbox\" bind:group={fillings} value=\"Beans\" /> Beans</label>\n<label><input type=\"checkbox\" bind:group={fillings} value=\"Cheese\" /> Cheese</label>\n<label><input type=\"checkbox\" bind:group={fillings} value=\"Guac (extra)\" /> Guac (extra)</label>\n\n<p>Tortilla: {tortilla}</p>\n<p>Fillings: {fillings.join(', ') || 'None'}</p>\n\n<style>\n\tlabel {\n\t\tdisplay: block;\n\t}\n</style>\n[!NOTE] `bind:group` only works if the inputs are in the same Svelte component.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<input bind:files>"],"href":"/docs/svelte/bind#input-bind:files","content":"On <input> elements with type=\"file\", you can use bind:files to get the `FileList` of selected files. When you want to update the files programmatically, you always need to use a FileList object. Currently FileList objects cannot be constructed directly, so you need to create a new `DataTransfer` object and get files from there.<script>\n\tlet files = $state();\n\n\tfunction clear() {\n\t\tfiles = new DataTransfer().files; // null or undefined does not work\n\t}\n</script>\n\n<label for=\"avatar\">Upload a picture:</label>\n<input accept=\"image/png, image/jpeg\" bind:files id=\"avatar\" name=\"avatar\" type=\"file\" />\n<button onclick={clear}>clear</button>FileList objects also cannot be modified, so if you want to e.g. delete a single file from the list, you need to create a new DataTransfer object and add the files you want to keep.[!NOTE] `DataTransfer` may not be available in server-side JS runtimes. Leaving the state that is bound to `files` uninitialized prevents potential errors if components are server-side rendered.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<select bind:value>"],"href":"/docs/svelte/bind#select-bind:value","content":"A <select> value binding corresponds to the value property on the selected <option>, which can be any value (not just strings, as is normally the case in the DOM).<select bind:value={selected}>\n\t<option value={a}>a</option>\n\t<option value={b}>b</option>\n\t<option value={c}>c</option>\n</select>A <select multiple> element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the value property of each selected <option>.<select multiple bind:value={fillings}>\n\t<option value=\"Rice\">Rice</option>\n\t<option value=\"Beans\">Beans</option>\n\t<option value=\"Cheese\">Cheese</option>\n\t<option value=\"Guac (extra)\">Guac (extra)</option>\n</select>When the value of an <option> matches its text content, the attribute can be omitted.<select multiple bind:value={fillings}>\n\t<option>Rice</option>\n\t<option>Beans</option>\n\t<option>Cheese</option>\n\t<option>Guac (extra)</option>\n</select>You can give the <select> a default value by adding a selected attribute to the <option> (or options, in the case of <select multiple>) that should be initially selected. If the <select> is part of a form, it will revert to that selection when the form is reset. Note that for the initial render the value of the binding takes precedence if it's not undefined.<select bind:value={selected}>\n\t<option value={a}>a</option>\n\t<option value={b} selected>b</option>\n\t<option value={c}>c</option>\n</select>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<audio>"],"href":"/docs/svelte/bind#audio","content":"<audio> elements have their own set of bindings — five two-way ones...[`currentTime`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime)\n[`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate)\n[`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused)\n[`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume)\n[`muted`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted)...and six readonly ones:[`duration`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)\n[`buffered`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered)\n[`seekable`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekable)\n[`seeking`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking_event)\n[`ended`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended)\n[`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)\n[`played`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/played)<audio src={clip} bind:duration bind:currentTime bind:paused></audio>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<video>"],"href":"/docs/svelte/bind#video","content":"<video> elements have all the same bindings as `<audio>` elements, plus readonly `videoWidth` and `videoHeight` bindings.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<img>"],"href":"/docs/svelte/bind#img","content":"<img> elements have two readonly bindings:[`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth)\n[`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight)","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","<details bind:open>"],"href":"/docs/svelte/bind#details-bind:open","content":"<details> elements support binding to the open property.<details bind:open={isOpen}>\n\t<summary>How do you comfort a JavaScript bug?</summary>\n\t<p>You console it.</p>\n</details>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","window` and document`"],"href":"/docs/svelte/bind#window-and-document","content":"To bind to properties of window and document, see `<svelte:window>` and `<svelte:document>`.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","Contenteditable bindings"],"href":"/docs/svelte/bind#Contenteditable-bindings","content":"Elements with the contenteditable attribute support the following bindings:[`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)\n[`innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText)\n[`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)[!NOTE] There are [subtle differences between `innerText` and `textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext).\n\n<div contenteditable=\"true\" bind:innerHTML={html}></div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","Dimensions"],"href":"/docs/svelte/bind#Dimensions","content":"All visible elements have the following readonly bindings, measured with a ResizeObserver:[`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)\n[`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)\n[`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)\n[`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)\n[`contentRect`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentRect)\n[`contentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize)\n[`borderBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/borderBoxSize)\n[`devicePixelContentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/devicePixelContentBoxSize)<div bind:offsetWidth={width} bind:offsetHeight={height}>\n\t<Chart {width} {height} />\n</div>[!NOTE] `display: inline` elements do not have a width or height (except for elements with 'intrinsic' dimensions, like `<img>` and `<canvas>`), and cannot be observed with a `ResizeObserver`. You will need to change the `display` style of these elements to something else, such as `inline-block`. Note that CSS transformations do not trigger `ResizeObserver` callbacks.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","bind:this"],"href":"/docs/svelte/bind#bind:this","content":"<!--- copy: false --->\nbind:this={dom_node}To get a reference to a DOM node, use bind:this. The value will be undefined until the component is mounted — in other words, you should read it inside an effect or an event handler, but not during component initialisation:<script>\n\t/** @type {HTMLCanvasElement} */\n\tlet canvas;\n\n\t$effect(() => {\n\t\tconst ctx = canvas.getContext('2d');\n\t\tdrawStuff(ctx);\n\t});\n</script>\n\n<canvas bind:this={canvas}></canvas>Components also support bind:this, allowing you to interact with component instances programmatically.<!--- file: App.svelte --->\n<ShoppingCart bind:this={cart} />\n\n<button onclick={() => cart.empty()}> Empty shopping cart </button><!--- file: ShoppingCart.svelte --->\n<script>\n\t// All instance exports are available on the instance object\n\texport function empty() {\n\t\t// ...\n\t}\n</script>[!NOTE] In case of using [the function bindings](#Function-bindings), the getter is required to ensure that the correct value is nullified on component or element destruction.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","bind:","bind:property for components"],"href":"/docs/svelte/bind#bind:property-for-components","content":"bind:property={variable}You can bind to component props using the same syntax as for elements.<Keypad bind:value={pin} />While Svelte props are reactive without binding, that reactivity only flows downward into the component by default. Using bind:property allows changes to the property from within the component to flow back up out of the component.To mark a property as bindable, use the `$bindable` rune:<script>\n\tlet { readonlyProperty, bindableProperty = $bindable() } = $props();\n</script>Declaring a property as bindable means it can be used using bind:, not that it must be used using bind:.Bindable properties can have a fallback value:<script>\n\tlet { bindableProperty = $bindable('fallback value') } = $props();\n</script>This fallback value only applies when the property is not bound. When the property is bound and a fallback value is present, the parent is expected to provide a value other than undefined, else a runtime error is thrown. This prevents hard-to-reason-about situations where it's unclear which value should apply.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","use:"],"href":"/docs/svelte/use","content":"[!NOTE]\nIn Svelte 5.29 and newer, consider using [attachments](@attach) instead, as they are more flexible and composable.Actions are functions that are called when an element is mounted. They are added with the use: directive, and will typically use an $effect so that they can reset any state when the element is unmounted:<!--- file: App.svelte --->\n<script>\n\t/** @type {import('svelte/action').Action} */\n\tfunction myaction(node) {\n\t\t// the node has been mounted in the DOM\n\n\t\t$effect(() => {\n\t\t\t// setup goes here\n\n\t\t\treturn () => {\n\t\t\t\t// teardown goes here\n\t\t\t};\n\t\t});\n\t}\n</script>\n\n<div use:myaction>...</div>An action can be called with an argument:<!--- file: App.svelte --->\n<script>\n\t/** @type {import('svelte/action').Action} */\n\tfunction myaction(node, +++data+++) {\n\t\t// ...\n\t}\n</script>\n\n<div use:myaction={+++data+++}>...</div>The action is only called once (but not during server-side rendering) — it will not run again if the argument changes.[!LEGACY]\nPrior to the `$effect` rune, actions could return an object with `update` and `destroy` methods, where `update` would be called with the latest value of the argument if it changed. Using effects is preferred.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","use:","Typing"],"href":"/docs/svelte/use#Typing","content":"The Action interface receives three optional type arguments — a node type (which can be Element, if the action applies to everything), a parameter, and any custom event handlers created by the action:<!--- file: App.svelte --->\n<script>\n\t/**\n\t * @type {import('svelte/action').Action<\n\t * \tHTMLDivElement,\n\t * \tundefined,\n\t * \t{\n\t * \t\tonswiperight: (e: CustomEvent) => void;\n\t * \t\tonswipeleft: (e: CustomEvent) => void;\n\t * \t\t// ...\n\t * \t}\n\t * >}\n\t */\n\tfunction gestures(node) {\n\t\t$effect(() => {\n\t\t\t// ...\n\t\t\tnode.dispatchEvent(new CustomEvent('swipeleft'));\n\n\t\t\t// ...\n\t\t\tnode.dispatchEvent(new CustomEvent('swiperight'));\n\t\t});\n\t}\n</script>\n\n<div\n\tuse:gestures\n\tonswipeleft={next}\n\tonswiperight={prev}\n>...</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:"],"href":"/docs/svelte/transition","content":"A transition is triggered by an element entering or leaving the DOM as a result of a state change.When a block (such as an {#if ...} block) is transitioning out, all elements inside it, including those that do not have their own transitions, are kept in the DOM until every transition in the block has been completed.The transition: directive indicates a bidirectional transition, which means it can be smoothly reversed while the transition is in progress.<script>\n\t+++import { fade } from 'svelte/transition';+++\n\n\tlet visible = $state(false);\n</script>\n\n<button onclick={() => visible = !visible}>toggle</button>\n\n{#if visible}\n\t<div +++transition:fade+++>fades in and out</div>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:","Local vs global"],"href":"/docs/svelte/transition#Local-vs-global","content":"Transitions are local by default. Local transitions only play when the block they belong to is created or destroyed, not when parent blocks are created or destroyed.{#if x}\n\t{#if y}\n\t\t<p transition:fade>fades in and out only when y changes</p>\n\n\t\t<p transition:fade|global>fades in and out when x or y change</p>\n\t{/if}\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:","Built-in transitions"],"href":"/docs/svelte/transition#Built-in-transitions","content":"A selection of built-in transitions can be imported from the `svelte/transition` module.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:","Transition parameters"],"href":"/docs/svelte/transition#Transition-parameters","content":"Transitions can have parameters.(The double {{curlies}} aren't a special syntax; this is an object literal inside an expression tag.){#if visible}\n\t<div transition:fade={{ duration: 2000 }}>fades in and out over two seconds</div>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:","Custom transition functions"],"href":"/docs/svelte/transition#Custom-transition-functions","content":"/// copy: false\n \ntransition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => {\n\tdelay?: number,\n\tduration?: number,\n\teasing?: (t: number) => number,\n\tcss?: (t: number, u: number) => string,\n\ttick?: (t: number, u: number) => void\n}Transitions can use custom functions. If the returned object has a css function, Svelte will generate keyframes for a web animation.The t argument passed to css is a value between 0 and 1 after the easing function has been applied. In transitions run from 0 to 1, out transitions run from 1 to 0 — in other words, 1 is the element's natural state, as though no transition had been applied. The u argument is equal to 1 - t.The function is called repeatedly before the transition begins, with different t and u arguments.<!--- file: App.svelte --->\n<script>\n\timport { elasticOut } from 'svelte/easing';\n\n\t/** @type {boolean} */\n\texport let visible;\n\n\t/**\n\t * @param {HTMLElement} node\n\t * @param {{ delay?: number, duration?: number, easing?: (t: number) => number }} params\n\t */\n\tfunction whoosh(node, params) {\n\t\tconst existingTransform = getComputedStyle(node).transform.replace('none', '');\n\n\t\treturn {\n\t\t\tdelay: params.delay || 0,\n\t\t\tduration: params.duration || 400,\n\t\t\teasing: params.easing || elasticOut,\n\t\t\tcss: (t, u) => `transform: ${existingTransform} scale(${t})`\n\t\t};\n\t}\n</script>\n\n{#if visible}\n\t<div in:whoosh>whooshes in</div>\n{/if}A custom transition function can also return a tick function, which is called during the transition with the same t and u arguments.[!NOTE] If it's possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.<!--- file: App.svelte --->\n<script>\n\texport let visible = false;\n\n\t/**\n\t * @param {HTMLElement} node\n\t * @param {{ speed?: number }} params\n\t */\n\tfunction typewriter(node, { speed = 1 }) {\n\t\tconst valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;\n\n\t\tif (!valid) {\n\t\t\tthrow new Error(`This transition only works on elements with a single text node child`);\n\t\t}\n\n\t\tconst text = node.textContent;\n\t\tconst duration = text.length / (speed * 0.01);\n\n\t\treturn {\n\t\t\tduration,\n\t\t\ttick: (t) => {\n\t\t\t\tconst i = ~~(text.length * t);\n\t\t\t\tnode.textContent = text.slice(0, i);\n\t\t\t}\n\t\t};\n\t}\n</script>\n\n{#if visible}\n\t<p in:typewriter={{ speed: 1 }}>The quick brown fox jumps over the lazy dog</p>\n{/if}If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making crossfade effects possible.Transition functions also receive a third argument, options, which contains information about the transition.Available values in the options object are:`direction` - one of `in`, `out`, or `both` depending on the type of transition","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","transition:","Transition events"],"href":"/docs/svelte/transition#Transition-events","content":"An element with transitions will dispatch the following events in addition to any standard DOM events:`introstart`\n`introend`\n`outrostart`\n`outroend`{#if visible}\n\t<p\n\t\ttransition:fly={{ y: 200, duration: 2000 }}\n\t\tonintrostart={() => (status = 'intro started')}\n\t\tonoutrostart={() => (status = 'outro started')}\n\t\tonintroend={() => (status = 'intro ended')}\n\t\tonoutroend={() => (status = 'outro ended')}\n\t>\n\t\tFlies in and out\n\t</p>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","in: and out:"],"href":"/docs/svelte/in-and-out","content":"The in: and out: directives are identical to `transition:`, except that the resulting transitions are not bidirectional — an in transition will continue to 'play' alongside the out transition, rather than reversing, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.<script>\n  import { fade, fly } from 'svelte/transition';\n\n  let visible = $state(false);\n</script>\n\n<label>\n  <input type=\"checkbox\" bind:checked={visible}>\n  visible\n</label>\n\n{#if visible}\n\t<div in:fly={{ y: 200 }} out:fade>flies in, fades out</div>\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","animate:"],"href":"/docs/svelte/animate","content":"An animation is triggered when the contents of a keyed each block are re-ordered. Animations do not run when an element is added or removed, only when the index of an existing data item within the each block changes. Animate directives must be on an element that is an immediate child of a keyed each block.Animations can be used with Svelte's built-in animation functions or custom animation functions.<!-- When `list` is reordered the animation will run -->\n{#each list as item, index (item)}\n\t<li animate:flip>{item}</li>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","animate:","Animation Parameters"],"href":"/docs/svelte/animate#Animation-Parameters","content":"As with actions and transitions, animations can have parameters.(The double {{curlies}} aren't a special syntax; this is an object literal inside an expression tag.){#each list as item, index (item)}\n\t<li animate:flip={{ delay: 500 }}>{item}</li>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","animate:","Custom animation functions"],"href":"/docs/svelte/animate#Custom-animation-functions","content":"/// copy: false\n \nanimation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {\n\tdelay?: number,\n\tduration?: number,\n\teasing?: (t: number) => number,\n\tcss?: (t: number, u: number) => string,\n\ttick?: (t: number, u: number) => void\n}Animations can use custom functions that provide the node, an animation object and any parameters as arguments. The animation parameter is an object containing from and to properties each containing a DOMRect describing the geometry of the element in its start and end positions. The from property is the DOMRect of the element in its starting position, and the to property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.If the returned object has a css method, Svelte will create a web animation that plays on the element.The t argument passed to css is a value that goes from 0 and 1 after the easing function has been applied. The u argument is equal to 1 - t.The function is called repeatedly before the animation begins, with different t and u arguments.\n<!--- file: App.svelte --->\n<script>\n\timport { cubicOut } from 'svelte/easing';\n\n\t/**\n\t * @param {HTMLElement} node\n\t * @param {{ from: DOMRect; to: DOMRect }} states\n\t * @param {any} params\n\t */\n\tfunction whizz(node, { from, to }, params) {\n\t\tconst dx = from.left - to.left;\n\t\tconst dy = from.top - to.top;\n\n\t\tconst d = Math.sqrt(dx * dx + dy * dy);\n\n\t\treturn {\n\t\t\tdelay: 0,\n\t\t\tduration: Math.sqrt(d) * 120,\n\t\t\teasing: cubicOut,\n\t\t\tcss: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`\n\t\t};\n\t}\n</script>\n\n{#each list as item, index (item)}\n\t<div animate:whizz>{item}</div>\n{/each}A custom animation function can also return a tick function, which is called during the animation with the same t and u arguments.[!NOTE] If it's possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.<!--- file: App.svelte --->\n<script>\n\timport { cubicOut } from 'svelte/easing';\n\n\t/**\n\t * @param {HTMLElement} node\n\t * @param {{ from: DOMRect; to: DOMRect }} states\n\t * @param {any} params\n\t */\n\tfunction whizz(node, { from, to }, params) {\n\t\tconst dx = from.left - to.left;\n\t\tconst dy = from.top - to.top;\n\n\t\tconst d = Math.sqrt(dx * dx + dy * dy);\n\n\t\treturn {\n\t\t\tdelay: 0,\n\t\t\tduration: Math.sqrt(d) * 120,\n\t\t\teasing: cubicOut,\n\t\t\ttick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })\n\t\t};\n\t}\n</script>\n\n{#each list as item, index (item)}\n\t<div animate:whizz>{item}</div>\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","style:"],"href":"/docs/svelte/style","content":"The style: directive provides a shorthand for setting multiple styles on an element.<!-- These are equivalent -->\n<div style:color=\"red\">...</div>\n<div style=\"color: red;\">...</div>The value can contain arbitrary expressions:<div style:color={myColor}>...</div>The shorthand form is allowed:<div style:color>...</div>Multiple styles can be set on a single element:<div style:color style:width=\"12rem\" style:background-color={darkMode ? 'black' : 'white'}>...</div>To mark a style as important, use the |important modifier:<div style:color|important=\"red\">...</div>When style: directives are combined with style attributes, the directives will take precedence,\neven over !important properties:<div style:color=\"red\" style=\"color: blue\">This will be red</div>\n<div style:color=\"red\" style=\"color: blue !important\">This will still be red</div>You can set CSS custom properties:<div style:--columns={columns}>...</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","class"],"href":"/docs/svelte/class","content":"There are two ways to set classes on elements: the class attribute, and the class: directive.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","class","Attributes"],"href":"/docs/svelte/class#Attributes","content":"Primitive values are treated like any other attribute:<div class={large ? 'large' : 'small'}>...</div>[!NOTE]\nFor historical reasons, falsy values (like `false` and `NaN`) are stringified (`class=\"false\"`), though `class={undefined}` (or `null`) cause the attribute to be omitted altogether. In a future version of Svelte, all falsy values will cause `class` to be omitted.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","class","Attributes","Objects and arrays"],"href":"/docs/svelte/class#Attributes-Objects-and-arrays","content":"Since Svelte 5.16, class can be an object or array, and is converted to a string using clsx.If the value is an object, the truthy keys are added:<script>\n\tlet { cool } = $props();\n</script>\n\n<!-- results in `class=\"cool\"` if `cool` is truthy,\n     `class=\"lame\"` otherwise -->\n<div class={{ cool, lame: !cool }}>...</div>If the value is an array, the truthy values are combined:<!-- if `faded` and `large` are both truthy, results in\n     `class=\"saturate-0 opacity-50 scale-200\"` -->\n<div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}>...</div>Note that whether we're using the array or object form, we can set multiple classes simultaneously with a single condition, which is particularly useful if you're using things like Tailwind.Arrays can contain arrays and objects, and clsx will flatten them. This is useful for combining local classes with props, for example:<!--- file: Button.svelte --->\n<script>\n\tlet props = $props();\n</script>\n\n<button {...props} class={['cool-button', props.class]}>\n\t{@render props.children?.()}\n</button>The user of this component has the same flexibility to use a mixture of objects, arrays and strings:<!--- file: App.svelte --->\n<script>\n\timport Button from './Button.svelte';\n\tlet useTailwind = $state(false);\n</script>\n\n<Button\n\tonclick={() => useTailwind = true}\n\tclass={{ 'bg-blue-700 sm:w-1/2': useTailwind }}\n>\n\tAccept the inevitability of Tailwind\n</Button>Since Svelte 5.19, Svelte also exposes the ClassValue type, which is the type of value that the class attribute on elements accept. This is useful if you want to use a type-safe class name in component props:<script lang=\"ts\">\n\timport type { ClassValue } from 'svelte/elements';\n\n\tconst props: { class: ClassValue } = $props();\n</script>\n\n<div class={['original', props.class]}>...</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","class","The `class:` directive"],"href":"/docs/svelte/class#The-class:-directive","content":"Prior to Svelte 5.16, the class: directive was the most convenient way to set classes on elements conditionally.<!-- These are equivalent -->\n<div class={{ cool, lame: !cool }}>...</div>\n<div class:cool={cool} class:lame={!cool}>...</div>As with other directives, we can use a shorthand when the name of the class coincides with the value:<div class:cool class:lame={!cool}>...</div>[!NOTE] Unless you're using an older version of Svelte, consider avoiding `class:`, since the attribute is more powerful and composable.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await"],"href":"/docs/svelte/await-expressions","content":"As of Svelte 5.36, you can use the await keyword inside your components in three places where it was previously unavailable:at the top level of your component's `<script>`\ninside `$derived(...)` declarations\ninside your markupThis feature is currently experimental, and you must opt in by adding the experimental.async option wherever you configure Svelte, usually svelte.config.js: \nexport default {\n\tcompilerOptions: {\n\t\texperimental: {\n\t\t\tasync: true\n\t\t}\n\t}\n};The experimental flag will be removed in Svelte 6.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Synchronized updates"],"href":"/docs/svelte/await-expressions#Synchronized-updates","content":"When an await expression depends on a particular piece of state, changes to that state will not be reflected in the UI until the asynchronous work has completed, so that the UI is not left in an inconsistent state. In other words, in an example like this...\n<!--- file: App.svelte --->\n<script>\n\tlet a = $state(1);\n\tlet b = $state(2);\n\n\tasync function add(a, b) {\n\t\tawait new Promise((f) => setTimeout(f, 500)); // artificial delay\n\t\treturn a + b;\n\t}\n</script>\n\n<input type=\"number\" bind:value={a}>\n<input type=\"number\" bind:value={b}>\n\n<p>{a} + {b} = {await add(a, b)}</p>\n...if you increment a, the contents of the <p> will not immediately update to read this —<p>2 + 2 = 3</p>— instead, the text will update to 2 + 2 = 4 when add(a, b) resolves.Updates can overlap — a fast update will be reflected in the UI while an earlier slow update is still ongoing.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Concurrency"],"href":"/docs/svelte/await-expressions#Concurrency","content":"Svelte will do as much asynchronous work as it can in parallel. For example if you have two await expressions in your markup...<p>{await one(x)}</p>\n<p>{await two(y)}</p>...both functions will run at the same time, as they are independent expressions, even though they are visually sequential.This does not apply to sequential await expressions inside your <script> or inside async functions — these run like any other asynchronous JavaScript. An exception is that independent $derived expressions will update independently, even though they will run sequentially when they are first created:// `b` will not be created until `a` has resolved,\n// but once created they will update independently\n// even if `x` and `y` update simultaneously\nlet a = $derived(await one(x));\nlet b = $derived(await two(y));[!NOTE] If you write code like this, expect Svelte to give you an [`await_waterfall`](runtime-warnings#Client-warnings-await_waterfall) warning","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Indicating loading states"],"href":"/docs/svelte/await-expressions#Indicating-loading-states","content":"To render placeholder UI, you can wrap content in a <svelte:boundary> with a `pending` snippet. This will be shown when the boundary is first created, but not for subsequent updates, which are globally coordinated.After the contents of a boundary have resolved for the first time and have replaced the pending snippet, you can detect subsequent async work with `$effect.pending()`. This is what you would use to display a \"we're asynchronously validating your input\" spinner next to a form field, for example.You can also use `settled()` to get a promise that resolves when the current update is complete:import { tick, settled } from 'svelte';\n\nasync function onclick() {\n\tupdating = true;\n\n\t// without this, the change to `updating` will be\n\t// grouped with the other changes, meaning it\n\t// won't be reflected in the UI\n\tawait tick();\n\n\tcolor = 'octarine';\n\tanswer = 42;\n\n\tawait settled();\n\n\t// any updates affected by `color` or `answer`\n\t// have now been applied\n\tupdating = false;\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Error handling"],"href":"/docs/svelte/await-expressions#Error-handling","content":"Errors in await expressions will bubble to the nearest error boundary.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Server-side rendering"],"href":"/docs/svelte/await-expressions#Server-side-rendering","content":"Svelte supports asynchronous server-side rendering (SSR) with the render(...) API. To use it, simply await the return value: \nimport { render } from 'svelte/server';\nimport App from './App.svelte';\n\nconst { head, body } = +++await+++ render(App);[!NOTE] If you're using a framework like SvelteKit, this is done on your behalf.If a <svelte:boundary> with a pending snippet is encountered during SSR, that snippet will be rendered while the rest of the content is ignored. All await expressions encountered outside boundaries with pending snippets will resolve and render their contents prior to await render(...) returning.[!NOTE] In the future, we plan to add a streaming implementation that renders the content in the background.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Forking"],"href":"/docs/svelte/await-expressions#Forking","content":"The `fork(...)` API, added in 5.42, makes it possible to run await expressions that you expect to happen in the near future. This is mainly intended for frameworks like SvelteKit to implement preloading when (for example) users signal an intent to navigate.<script>\n\timport { fork } from 'svelte';\n\timport Menu from './Menu.svelte';\n\n\tlet open = $state(false);\n\n\t/** @type {import('svelte').Fork | null} */\n\tlet pending = null;\n\n\tfunction preload() {\n\t\tpending ??= fork(() => {\n\t\t\topen = true;\n\t\t});\n\t}\n\n\tfunction discard() {\n\t\tpending?.discard();\n\t\tpending = null;\n\t}\n</script>\n\n<button\n\tonfocusin={preload}\n\tonfocusout={discard}\n\tonpointerenter={preload}\n\tonpointerleave={discard}\n\tonclick={() => {\n\t\tpending?.commit();\n\t\tpending = null;\n\n\t\t// in case `pending` didn't exist\n\t\t// (if it did, this is a no-op)\n\t\topen = true;\n\t}}\n>open menu</button>\n\n{#if open}\n\t<!-- any async work inside this component will start\n\t     as soon as the fork is created -->\n\t<Menu onclose={() => open = false} />\n{/if}","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Caveats"],"href":"/docs/svelte/await-expressions#Caveats","content":"As an experimental feature, the details of how await is handled (and related APIs like $effect.pending()) are subject to breaking changes outside of a semver major release, though we intend to keep such changes to a bare minimum.","rank":null},{"breadcrumbs":["Docs","Svelte","Template syntax","await","Breaking changes"],"href":"/docs/svelte/await-expressions#Breaking-changes","content":"Effects run in a slightly different order when the experimental.async option is true. Specifically, block effects like {#if ...} and {#each ...} now run before an $effect.pre or beforeUpdate in the same component, which means that in very rare situations it is possible to update a block that should no longer exist, but only if you update state inside an effect, which you should avoid.","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Scoped styles"],"href":"/docs/svelte/scoped-styles","content":"Svelte components can include a <style> element containing CSS that belongs to the component. This CSS is scoped by default, meaning that styles will not apply to any elements on the page outside the component in question.This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. svelte-123xyz).<style>\n\tp {\n\t\t/* this will only affect <p> elements in this component */\n\t\tcolor: burlywood;\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Scoped styles","Specificity"],"href":"/docs/svelte/scoped-styles#Specificity","content":"Each scoped selector receives a specificity increase of 0-1-0, as a result of the scoping class (e.g. .svelte-123xyz) being added to the selector. This means that (for example) a p selector defined in a component will take precedence over a p selector defined in a global stylesheet, even if the global stylesheet is loaded later.In some cases, the scoping class must be added to a selector multiple times, but after the first occurrence it is added with :where(.svelte-xyz123) in order to not increase specificity further.","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Scoped styles","Scoped keyframes"],"href":"/docs/svelte/scoped-styles#Scoped-keyframes","content":"If a component defines @keyframes, the name is scoped to the component using the same hashing approach. Any animation rules in the component will be similarly adjusted:<style>\n\t.bouncy {\n\t\tanimation: bounce 10s;\n\t}\n\n\t/* these keyframes are only accessible inside this component */\n\t@keyframes bounce {\n\t\t/* ... */\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Global styles"],"href":"/docs/svelte/global-styles","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Global styles",":global(...)"],"href":"/docs/svelte/global-styles#:global()","content":"To apply styles to a single selector globally, use the :global(...) modifier:<style>\n\t:global(body) {\n\t\t/* applies to <body> */\n\t\tmargin: 0;\n\t}\n\n\tdiv :global(strong) {\n\t\t/* applies to all <strong> elements, in any component,\n\t\t   that are inside <div> elements belonging\n\t\t   to this component */\n\t\tcolor: goldenrod;\n\t}\n\n\tp:global(.big.red) {\n\t\t/* applies to all <p> elements belonging to this component\n\t\t   with `class=\"big red\"`, even if it is applied\n\t\t   programmatically (for example by a library) */\n\t}\n</style>If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with -global-.The -global- part will be removed when compiled, and the keyframe will then be referenced using just my-animation-name elsewhere in your code.<style>\n\t@keyframes -global-my-animation-name {\n\t\t/* code goes here */\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Global styles",":global"],"href":"/docs/svelte/global-styles#:global","content":"To apply styles to a group of selectors globally, create a :global {...} block:<style>\n\t:global {\n\t\t/* applies to every <div> in your application */\n\t\tdiv { ... }\n\n\t\t/* applies to every <p> in your application */\n\t\tp { ... }\n\t}\n\n\t.a :global {\n\t\t/* applies to every `.b .c .d` element, in any component,\n\t\t   that is inside an `.a` element in this component */\n\t\t.b .c .d {...}\n\t}\n</style>[!NOTE] The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Custom properties"],"href":"/docs/svelte/custom-properties","content":"You can pass CSS custom properties — both static and dynamic — to components:<Slider\n\tbind:value\n\tmin={0}\n\tmax={100}\n\t--track-color=\"black\"\n\t--thumb-color=\"rgb({r} {g} {b})\"\n/>The above code essentially desugars to this:<svelte-css-wrapper style=\"display: contents; --track-color: black; --thumb-color: rgb({r} {g} {b})\">\n\t<Slider\n\t\tbind:value\n\t\tmin={0}\n\t\tmax={100}\n\t/>\n</svelte-css-wrapper>For an SVG element, it would use <g> instead:<g style=\"--track-color: black; --thumb-color: rgb({r} {g} {b})\">\n\t<Slider\n\t\tbind:value\n\t\tmin={0}\n\t\tmax={100}\n\t/>\n</g>Inside the component, we can read these custom properties (and provide fallback values) using `var(...)`:<style>\n\t.track {\n\t\tbackground: var(--track-color, #aaa);\n\t}\n\n\t.thumb {\n\t\tbackground: var(--thumb-color, blue);\n\t}\n</style>You don't have to specify the values directly on the component; as long as the custom properties are defined on a parent element, the component can use them. It's common to define custom properties on the :root element in a global stylesheet so that they apply to your entire application.[!NOTE] While the extra element will not affect layout, it _will_ affect any CSS selectors that (for example) use the `>` combinator to target an element directly inside the component's container.","rank":null},{"breadcrumbs":["Docs","Svelte","Styling","Nested <style> elements"],"href":"/docs/svelte/nested-style-elements","content":"There can only be one top-level <style> tag per component.However, it is possible to have a <style> tag nested inside other elements or logic blocks.In that case, the <style> tag will be inserted as-is into the DOM; no scoping or processing will be done on the <style> tag.<div>\n\t<style>\n\t\t/* this style tag will be inserted as-is */\n\t\tdiv {\n\t\t\t/* this will apply to all `<div>` elements in the DOM */\n\t\t\tcolor: red;\n\t\t}\n\t</style>\n</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>"],"href":"/docs/svelte/svelte-boundary","content":"<svelte:boundary onerror={handler}>...</svelte:boundary>[!NOTE]\nThis feature was added in 5.3.0Boundaries allow you to 'wall off' parts of your app, so that you can:provide UI that should be shown when [`await`](await-expressions) expressions are first resolving\nhandle errors that occur during rendering or while running effects, and provide UI that should be rendered when an error happensIf a boundary handles an error (with a failed snippet or onerror handler, or both) its existing content will be removed.[!NOTE] Errors occurring outside the rendering process (for example, in event handlers or after a `setTimeout` or async work) are _not_ caught by error boundaries.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>","Properties"],"href":"/docs/svelte/svelte-boundary#Properties","content":"For the boundary to do anything, one or more of the following must be provided.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>","Properties","pending"],"href":"/docs/svelte/svelte-boundary#Properties-pending","content":"This snippet will be shown when the boundary is first created, and will remain visible until all the `await` expressions inside the boundary have resolved (demo):<svelte:boundary>\n\t<p>{await delayed('hello!')}</p>\n\n\t{#snippet pending()}\n\t\t<p>loading...</p>\n\t{/snippet}\n</svelte:boundary>The pending snippet will not be shown for subsequent async updates — for these, you can use `$effect.pending()`.[!NOTE] In the [playground](/playground), your app is rendered inside a boundary with an empty pending snippet, so that you can use `await` without having to create one.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>","Properties","failed"],"href":"/docs/svelte/svelte-boundary#Properties-failed","content":"If a failed snippet is provided, it will be rendered when an error is thrown inside the boundary, with the error and a reset function that recreates the contents (demo):<svelte:boundary>\n\t<FlakyComponent />\n\n\t{#snippet failed(error, reset)}\n\t\t<button onclick={reset}>oops! try again</button>\n\t{/snippet}\n</svelte:boundary>[!NOTE]\nAs with [snippets passed to components](snippet#Passing-snippets-to-components), the `failed` snippet can be passed explicitly as a property...\n\n```svelte\n<svelte:boundary {failed}>...</svelte:boundary>\n```\n\n...or implicitly by declaring it directly inside the boundary, as in the example above.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>","Properties","onerror"],"href":"/docs/svelte/svelte-boundary#Properties-onerror","content":"If an onerror function is provided, it will be called with the same two error and reset arguments. This is useful for tracking the error with an error reporting service...<svelte:boundary onerror={(e) => report(e)}>\n\t...\n</svelte:boundary>...or using error and reset outside the boundary itself:<script>\n\tlet error = $state(null);\n\tlet reset = $state(() => {});\n\n\tfunction onerror(e, r) {\n\t\terror = e;\n\t\treset = r;\n\t}\n</script>\n\n<svelte:boundary {onerror}>\n\t<FlakyComponent />\n</svelte:boundary>\n\n{#if error}\n\t<button onclick={() => {\n\t\terror = null;\n\t\treset();\n\t}}>\n\t\toops! try again\n\t</button>\n{/if}If an error occurs inside the onerror function (or if you rethrow the error), it will be handled by a parent boundary if such exists.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:boundary>","Using `transformError`"],"href":"/docs/svelte/svelte-boundary#Using-transformError","content":"By default, error boundaries have no effect on the server — if an error occurs during rendering, the render as a whole will fail.Since 5.51 you can control this behaviour for boundaries with a failed snippet, by calling `render(...)` with a transformError function.[!NOTE] If you're using Svelte via a framework such as SvelteKit, you most likely don't have direct access to the `render(...)` call — the framework must configure `transformError` on your behalf. SvelteKit will add support for this in the near future, via the [`handleError`](../kit/hooks#Shared-hooks-handleError) hook.The transformError function must return a JSON-stringifiable object which will be used to render the failed snippet. This object will be serialized and used to hydrate the snippet in the browser: \nimport { render } from 'svelte/server';\nimport App from './App.svelte';\n\nconst { head, body } = await render(App, {\n\ttransformError: (error) => {\n\t\t// log the original error, with the stack trace...\n\t\tconsole.error(error);\n\n\t\t// ...and return a sanitized user-friendly error\n\t\t// to display in the `failed` snippet\n\t\treturn {\n\t\t\tmessage: 'An error occurred!'\n\t\t};\n\t};\n});If transformError throws (or rethrows) an error, render(...) as a whole will fail with that error.[!NOTE] Errors that occur during server-side rendering can contain sensitive information in the `message` and `stack`. It's recommended to redact these rather than sending them unaltered to the browser.If the boundary has an onerror handler, it will be called upon hydration with the deserialized error object.The `mount` and `hydrate` functions also accept a transformError option, which defaults to the identity function. As with render, this function transforms a render-time error before it is passed to a failed snippet or onerror handler.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:window>"],"href":"/docs/svelte/svelte-window","content":"<svelte:window onevent={handler} /><svelte:window bind:prop={value} />The <svelte:window> element allows you to add event listeners to the window object without worrying about removing them when the component is destroyed, or checking for the existence of window when server-side rendering.This element may only appear at the top level of your component — it cannot be inside a block or element.<script>\n\tfunction handleKeydown(event) {\n\t\talert(`pressed the ${event.key} key`);\n\t}\n</script>\n\n<svelte:window onkeydown={handleKeydown} />You can also bind to the following properties:`innerWidth`\n`innerHeight`\n`outerWidth`\n`outerHeight`\n`scrollX`\n`scrollY`\n`online` — an alias for `window.navigator.onLine`\n`devicePixelRatio`All except scrollX and scrollY are readonly.<svelte:window bind:scrollY={y} />[!NOTE] Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. If you have a legitimate reason to scroll when the component is rendered, call `scrollTo()` in an `$effect`.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:document>"],"href":"/docs/svelte/svelte-document","content":"<svelte:document onevent={handler} /><svelte:document bind:prop={value} />Similarly to <svelte:window>, this element allows you to add listeners to events on document, such as visibilitychange, which don't fire on window. It also lets you use attachments on document.As with <svelte:window>, this element may only appear the top level of your component and must never be inside a block or element.<svelte:document onvisibilitychange={handleVisibilityChange} {@attach someAttachment} />You can also bind to the following properties:`activeElement`\n`fullscreenElement`\n`pointerLockElement`\n`visibilityState`All are readonly.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:body>"],"href":"/docs/svelte/svelte-body","content":"<svelte:body onevent={handler} />Similarly to <svelte:window>, this element allows you to add listeners to events on document.body, such as mouseenter and mouseleave, which don't fire on window. It also lets you use actions on the <body> element.As with <svelte:window> and <svelte:document>, this element may only appear at the top level of your component and must never be inside a block or element.<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:head>"],"href":"/docs/svelte/svelte-head","content":"<svelte:head>...</svelte:head>This element makes it possible to insert elements into document.head. During server-side rendering, head content is exposed separately to the main body content.As with <svelte:window>, <svelte:document> and <svelte:body>, this element may only appear at the top level of your component and must never be inside a block or element.<svelte:head>\n\t<title>Hello world!</title>\n\t<meta name=\"description\" content=\"This is where the description goes for SEO\" />\n</svelte:head>","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:element>"],"href":"/docs/svelte/svelte-element","content":"<svelte:element this={expression} />The <svelte:element> element lets you render an element that is unknown at author time, for example because it comes from a CMS. Any properties and event listeners present will be applied to the element.The only supported binding is bind:this, since Svelte's built-in bindings do not work with generic elements.If this has a nullish value, the element and its children will not be rendered.If this is the name of a void element (e.g., br) and <svelte:element> has child elements, a runtime error will be thrown in development mode:<script>\n\tlet tag = $state('hr');\n</script>\n\n<svelte:element this={tag}>\n\tThis text cannot appear inside an hr element\n</svelte:element>Svelte tries its best to infer the correct namespace from the element's surroundings, but it's not always possible. You can make it explicit with an xmlns attribute:<svelte:element this={tag} xmlns=\"http://www.w3.org/2000/svg\" />this needs to be a valid DOM element tag, things like #text or svelte:head will not work.","rank":null},{"breadcrumbs":["Docs","Svelte","Special elements","<svelte:options>"],"href":"/docs/svelte/svelte-options","content":"<svelte:options option={value} />The <svelte:options> element provides a place to specify per-component compiler options, which are detailed in the compiler section. The possible options are:`runes={true}` — forces a component into _runes mode_ (see the [Legacy APIs](legacy-overview) section)\n`runes={false}` — forces a component into _legacy mode_\n`namespace=\"...\"` — the namespace where this component will be used, can be \"html\" (the default), \"svg\" or \"mathml\"\n`customElement={...}` — the [options](custom-elements#Component-options) to use when compiling this component as a custom element. If a string is passed, it is used as the `tag` option\n`css=\"injected\"` — the component will inject its styles inline: During server-side rendering, it's injected as a `<style>` tag in the `head`, during client side rendering, it's loaded via JavaScript[!LEGACY] Deprecated options\nSvelte 4 also included the following options. They are deprecated in Svelte 5 and non-functional in runes mode.\n\n- `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed\n- `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed\n- `accessors={true}` — adds getters and setters for the component's props\n- `accessors={false}` — the default<svelte:options customElement=\"my-custom-element\" />","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores"],"href":"/docs/svelte/stores","content":"A store is an object that allows reactive access to a value via a simple store contract. The `svelte/store` module contains minimal store implementations which fulfil this contract.Any time you have a reference to a store, you can access its value inside a component by prefixing it with the $ character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialisation and unsubscribe when appropriate.Assignments to $-prefixed variables require that the variable be a writable store, and will result in a call to the store's .set method.Note that the store must be declared at the top level of the component — not inside an if block or a function, for example.Local variables (that do not represent store values) must not have a $ prefix.<script>\n\timport { writable } from 'svelte/store';\n\n\tconst count = writable(0);\n\tconsole.log($count); // logs 0\n\n\tcount.set(1);\n\tconsole.log($count); // logs 1\n\n\t$count = 2;\n\tconsole.log($count); // logs 2\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","When to use stores"],"href":"/docs/svelte/stores#When-to-use-stores","content":"Prior to Svelte 5, stores were the go-to solution for creating cross-component reactive states or extracting logic. With runes, these use cases have greatly diminished.when extracting logic, it's better to take advantage of runes' universal reactivity: You can use runes outside the top level of components and even place them into JavaScript or TypeScript files (using a `.svelte.js` or `.svelte.ts` file ending)\nwhen creating shared state, you can create a `$state` object containing the values you need and then manipulate said state \nexport const userState = $state({\n\tname: 'name',\n\t/* ... */\n});<!--- file: App.svelte --->\n<script>\n\timport { userState } from './state.svelte.js';\n</script>\n\n<p>User name: {userState.name}</p>\n<button onclick={() => {\n\tuserState.name = 'new name';\n}}>\n\tchange name\n</button>Stores are still a good solution when you have complex asynchronous data streams or it's important to have more manual control over updating values or listening to changes. If you're familiar with RxJs and want to reuse that knowledge, the $ also comes in handy for you.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store"],"href":"/docs/svelte/stores#svelte-store","content":"The svelte/store module contains a minimal store implementation which fulfil the store contract. It provides methods for creating stores that you can update from the outside, stores you can only update from the inside, and for combining and deriving stores.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store","writable"],"href":"/docs/svelte/stores#svelte-store-writable","content":"Function that creates a store which has values that can be set from 'outside' components. It gets created as an object with additional set and update methods.set is a method that takes one argument which is the value to be set. The store value gets set to the value of the argument if the store value is not already equal to it.update is a method that takes one argument which is a callback. The callback takes the existing store value as its argument and returns the new value to be set to the store. \nimport { writable } from 'svelte/store';\n\nconst count = writable(0);\n\ncount.subscribe((value) => {\n\tconsole.log(value);\n}); // logs '0'\n\ncount.set(1); // logs '1'\n\ncount.update((n) => n + 1); // logs '2'If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a set function which changes the value of the store, and an update function which works like the update method on the store, taking a callback to calculate the store's new value from its old value. It must return a stop function that is called when the subscriber count goes from one to zero. \nimport { writable } from 'svelte/store';\n\nconst count = writable(0, () => {\n\tconsole.log('got a subscriber');\n\treturn () => console.log('no more subscribers');\n});\n\ncount.set(1); // does nothing\n\nconst unsubscribe = count.subscribe((value) => {\n\tconsole.log(value);\n}); // logs 'got a subscriber', then '1'\n\nunsubscribe(); // logs 'no more subscribers'Note that the value of a writable is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the localStorage.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store","readable"],"href":"/docs/svelte/stores#svelte-store-readable","content":"Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value, and the second argument to readable is the same as the second argument to writable.import { readable } from 'svelte/store';\n\nconst time = readable(new Date(), (set) => {\n\tset(new Date());\n\n\tconst interval = setInterval(() => {\n\t\tset(new Date());\n\t}, 1000);\n\n\treturn () => clearInterval(interval);\n});\n\nconst ticktock = readable('tick', (set, update) => {\n\tconst interval = setInterval(() => {\n\t\tupdate((sound) => (sound === 'tick' ? 'tock' : 'tick'));\n\t}, 1000);\n\n\treturn () => clearInterval(interval);\n});","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store","derived"],"href":"/docs/svelte/stores#svelte-store-derived","content":"Derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.In the simplest version, derived takes a single store, and the callback returns a derived value.import { derived } from 'svelte/store';\n\nconst doubled = derived(a, ($a) => $a * 2);The callback can set a value asynchronously by accepting a second argument, set, and an optional third argument, update, calling either or both of them when appropriate.In this case, you can also pass a third argument to derived — the initial value of the derived store before set or update is first called. If no initial value is specified, the store's initial value will be undefined.import { derived } from 'svelte/store';\n\nconst delayed = derived(\n\ta,\n\t($a, set) => {\n\t\tsetTimeout(() => set($a), 1000);\n\t},\n\t2000\n);\n\nconst delayedIncrement = derived(a, ($a, set, update) => {\n\tset($a);\n\tsetTimeout(() => update((x) => x + 1), 1000);\n\t// every time $a produces a value, this produces two\n\t// values, $a immediately and then $a + 1 a second later\n});If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes.import { derived } from 'svelte/store';\n\nconst tick = derived(\n\tfrequency,\n\t($frequency, set) => {\n\t\tconst interval = setInterval(() => {\n\t\t\tset(Date.now());\n\t\t}, 1000 / $frequency);\n\n\t\treturn () => {\n\t\t\tclearInterval(interval);\n\t\t};\n\t},\n\t2000\n);In both cases, an array of arguments can be passed as the first argument instead of a single store.import { derived } from 'svelte/store';\n\nconst summed = derived([a, b], ([$a, $b]) => $a + $b);\n\nconst delayed = derived([a, b], ([$a, $b], set) => {\n\tsetTimeout(() => set($a + $b), 1000);\n});","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store","readonly"],"href":"/docs/svelte/stores#svelte-store-readonly","content":"This simple helper function makes a store readonly. You can still subscribe to the changes from the original one using this new readable store.import { readonly, writable } from 'svelte/store';\n\nconst writableStore = writable(1);\nconst readableStore = readonly(writableStore);\n\nreadableStore.subscribe(console.log);\n\nwritableStore.set(2); // console: 2\n \nreadableStore.set(2); // ERROR","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","svelte/store","get"],"href":"/docs/svelte/stores#svelte-store-get","content":"Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you're not subscribed. get allows you to do so.[!NOTE] This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.import { get } from 'svelte/store';\n\nconst value = get(store);","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Stores","Store contract"],"href":"/docs/svelte/stores#Store-contract","content":"store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }You can create your own stores without relying on `svelte/store`, by implementing the store contract:A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes.\nThe `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store.\nA store may _optionally_ contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a _writable store_.For interoperability with RxJS Observables, the .subscribe method is also allowed to return an object with an .unsubscribe method, rather than return the unsubscription function directly. Note however that unless .subscribe synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as undefined until it does.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Context"],"href":"/docs/svelte/context","content":"Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as 'prop-drilling').By creating a [get, set] pair of functions with createContext, you can set the context in a parent component and get it in a child component:\n<!--- file: App.svelte --->\n<script>\n\timport Parent from './Parent.svelte';\n\timport Child from './Child.svelte';\n</script>\n\n<Parent>\n\t<Child />\n</Parent><!--- file: Parent.svelte --->\n<script>\n\timport { setUserContext } from './context';\n\n\tlet { children } = $props();\n\n\tsetUserContext({ name: 'world' });\n</script>\n\n{@render children()}<!--- file: Child.svelte --->\n<script>\n\timport { getUserContext } from './context';\n\n\tconst user = getUserContext();\n</script>\n\n<h1>hello {user.name}, inside Child.svelte</h1> \nimport { createContext } from 'svelte';\n\ninterface User {\n\tname: string;\n}\n\nexport const [getUserContext, setUserContext] = createContext<User>();\n[!NOTE] `createContext` was added in version 5.40. If you are using an earlier version of Svelte, you must use `setContext` and `getContext` instead.This is particularly useful when Parent.svelte is not directly aware of Child.svelte, but instead renders it as part of a children snippet as shown above.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Context","setContext` and getContext`"],"href":"/docs/svelte/context#setContext-and-getContext","content":"As an alternative to createContext, you can use setContext and getContext directly. The parent component sets context with setContext(key, value)...<!--- file: Parent.svelte --->\n<script>\n\timport { setContext } from 'svelte';\n\n\tsetContext('my-context', 'hello from Parent.svelte');\n</script>...and the child retrieves it with getContext:<!--- file: Child.svelte --->\n<script>\n\timport { getContext } from 'svelte';\n\n\tconst message = getContext('my-context');\n</script>\n\n<h1>{message}, inside Child.svelte</h1>The key ('my-context', in the example above) and the context itself can be any JavaScript value.[!NOTE] `createContext` is preferred since it provides better type safety and makes it unnecessary to use keys.In addition to `setContext` and `getContext`, Svelte exposes `hasContext` and `getAllContexts` functions.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Context","Using context with state"],"href":"/docs/svelte/context#Using-context-with-state","content":"You can store reactive state in context...\n<!--- file: App.svelte --->\n<script>\n\timport { setCounter } from './context.ts';\n\timport Child from './Child.svelte';\n\n\tlet counter = $state({\n\t\tcount: 0\n\t});\n\n\tsetCounter(counter);\n</script>\n\n<button onclick={() => counter.count += 1}>\n\tincrement\n</button>\n\n<Child />\n<Child />\n<Child />\n\n<button onclick={() => counter.count = 0}>\n\treset\n</button><!--- file: Child.svelte --->\n<script>\n\timport { getCounter } from './context.ts';\n\n\tconst counter = getCounter();\n</script>\n\n<p>{counter.count}</p> \nimport { createContext } from 'svelte';\n\ninterface Counter {\n\tcount: number;\n}\n\nexport const [getCounter, setCounter] = createContext<Counter>();\n...though note that if you reassign counter instead of updating it, you will 'break the link' — in other words instead of this...<button onclick={() => counter = { count: 0 } }>\n\treset\n</button>...you must do this:<button onclick={() => +++counter.count = 0+++}>\n\treset\n</button>Svelte will warn you if you get it wrong.Similarly, to pass primitive values through context, use functions as described in Passing state into functions.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Context","Component testing"],"href":"/docs/svelte/context#Component-testing","content":"When writing component tests, it can be useful to create a wrapper component that sets the context in order to check the behaviour of a component that uses it. As of version 5.49, you can do this sort of thing:import { mount, unmount } from 'svelte';\nimport { expect, test } from 'vitest';\nimport { setUserContext } from './context';\nimport MyComponent from './MyComponent.svelte';\n\ntest('MyComponent', () => {\n\tfunction Wrapper(...args) {\n\t\tsetUserContext({ name: 'Bob' });\n\t\treturn MyComponent(...args);\n\t}\n\n\tconst component = mount(Wrapper, {\n\t\ttarget: document.body\n\t});\n\n\texpect(document.body.innerHTML).toBe('<h1>Hello Bob!</h1>');\n\n\tunmount(component);\n});This approach also works with `hydrate` and `render`.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Context","Replacing global state"],"href":"/docs/svelte/context#Replacing-global-state","content":"When you have state shared by many different components, you might be tempted to put it in its own module and just import it wherever it's needed: \nexport const myGlobalState = $state({\n\tuser: {\n\t\t// ...\n\t}\n\t// ...\n});In many cases this is perfectly fine, but there is a risk: if you mutate the state during server-side rendering (which is discouraged, but entirely possible!)...<!--- file: App.svelte --->\n<script>\n\timport { myGlobalState } from './state.svelte.js';\n\n\tlet { data } = $props();\n\n\tif (data.user) {\n\t\tmyGlobalState.user = data.user;\n\t}\n</script>...then the data may be accessible by the next user. Context solves this problem because it is not shared between requests.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks"],"href":"/docs/svelte/lifecycle-hooks","content":"In Svelte 5, the component lifecycle consists of only two parts: Its creation and its destruction. Everything in-between — when certain state is updated — is not related to the component as a whole; only the parts that need to react to the state change are notified. This is because under the hood the smallest unit of change is actually not a component, it's the (render) effects that the component sets up upon component initialization. Consequently, there's no such thing as a \"before update\"/\"after update\" hook.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks","onMount"],"href":"/docs/svelte/lifecycle-hooks#onMount","content":"The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live inside the component; it can be called from an external module).onMount does not run inside a component that is rendered on the server.<script>\n\timport { onMount } from 'svelte';\n\n\tonMount(() => {\n\t\tconsole.log('the component has mounted');\n\t});\n</script>If a function is returned from onMount, it will be called when the component is unmounted.<script>\n\timport { onMount } from 'svelte';\n\n\tonMount(() => {\n\t\tconst interval = setInterval(() => {\n\t\t\tconsole.log('beep');\n\t\t}, 1000);\n\n\t\treturn () => clearInterval(interval);\n\t});\n</script>[!NOTE] This behaviour will only work when the function passed to `onMount` is _synchronous_. `async` functions always return a `Promise`.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks","onDestroy"],"href":"/docs/svelte/lifecycle-hooks#onDestroy","content":"Schedules a callback to run immediately before the component is unmounted.Out of onMount, beforeUpdate, afterUpdate and onDestroy, this is the only one that runs inside a server-side component.<script>\n\timport { onDestroy } from 'svelte';\n\n\tonDestroy(() => {\n\t\tconsole.log('the component is being destroyed');\n\t});\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks","tick"],"href":"/docs/svelte/lifecycle-hooks#tick","content":"While there's no \"after update\" hook, you can use tick to ensure that the UI is updated before continuing. tick returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.<script>\n\timport { tick } from 'svelte';\n\n\t$effect.pre(() => {\n\t\tconsole.log('the component is about to update');\n\t\ttick().then(() => {\n\t\t\t\tconsole.log('the component just updated');\n\t\t});\n\t});\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks","Deprecated: `beforeUpdate` / `afterUpdate`"],"href":"/docs/svelte/lifecycle-hooks#Deprecated:-beforeUpdate-afterUpdate","content":"Svelte 4 contained hooks that ran before and after the component as a whole was updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not available inside components that use runes.<script>\n\timport { beforeUpdate, afterUpdate } from 'svelte';\n\n\tbeforeUpdate(() => {\n\t\tconsole.log('the component is about to update');\n\t});\n\n\tafterUpdate(() => {\n\t\tconsole.log('the component just updated');\n\t});\n</script>Instead of beforeUpdate use $effect.pre and instead of afterUpdate use $effect instead — these runes offer more granular control and only react to the changes you're actually interested in.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Lifecycle hooks","Deprecated: `beforeUpdate` / `afterUpdate`","Chat window example"],"href":"/docs/svelte/lifecycle-hooks#Deprecated:-beforeUpdate-afterUpdate-Chat-window-example","content":"To implement a chat window that autoscrolls to the bottom when new messages appear (but only if you were already scrolled to the bottom), we need to measure the DOM before we update it.In Svelte 4, we do this with beforeUpdate, but this is a flawed approach — it fires before every update, whether it's relevant or not. In the example below, we need to introduce checks like updatingMessages to make sure we don't mess with the scroll position when someone toggles dark mode.With runes, we can use $effect.pre, which behaves the same as $effect but runs before the DOM is updated. As long as we explicitly reference messages inside the effect body, it will run whenever messages changes, but not when theme changes.beforeUpdate, and its equally troublesome counterpart afterUpdate, are therefore deprecated in Svelte 5.[Before](/playground/untitled#H4sIAAAAAAAAE31WXa_bNgz9K6yL1QmWOLlrC-w6H8MeBgwY9tY9NfdBtmlbiywZkpyPBfnvo2zLcZK28AWuRPGI5OGhkEuQc4EmiL9eAskqDOLg97oOZoE9125jDigs0t6oRqfOsjap5rXd7uTO8qpW2sIFEsyVxn_qjFmcAcstar-xPN3DFXKtKgi768IVgQku0ELj3Lgs_kZjWIEGNpAzYXDlHWyJFZI1zJjeh4O5uvl_DY8oUkVeVoFuJKYls-_CGYS25Aboj0EtWNqel0wWoBoLTGZgmdgDS9zW4Uz4NsrswPHoyutN4xInkylstnBxdmIhh8m7xzqmoNE2Wq46n1RJQzEbq4g-JQSl7e-HDx-GdaTy3KD9E3lRWvj5Zu9QX1QN20dj7zyHz8s-1S6lW7Cpz3RnXTcm04hIlfdFuO8p2mQ5-3a06cqjrn559bF_2NHOnRZ5I1PLlXQNyQT-hedMHeUEDyjtdMxsa4n2eIbNhlTwhyRthaOKOmYtniwF6pwt0wXa6MBEg0OibZec27gz_dk3UrZ6hB2LLYoiv521Yd8Gt-foTrfhiCDP0lC9VUUhcDLU49Xe_9943cNvEArHfAjxeBTovvXiNpFynfEDpIIZs9kFbg52QbeNHWZzebz32s7xHco3nJAJl1nshmhz8dYOQJDyZetnbb2gTWe-vEeWlrfpZMavr56ldb29eNt6UXvgwgFbp_WC0tl2RK25rGk6lYz3nUI2lzvBXGHhPZPGWmKUXFNBKqdaW259wl_aHbiqoVIZdpE60Nax6IOujT0LbFFxIVTCxCRR2XloUcYNvSbnGHKBp763jHoj59xiZWJI0Wm0P_m3MSS985xkasn-cFq20xTDy3J5KFcjgUTD69BHdcHIjz431z28IqlxGcPSfdFnrGDZn6gD6lyo45zyHAD-btczf-98nhQxHEvKfeUtOVkSejD3q-9X7JbzjGtsdUxlKdFU8qGsT78uaw848syWMXz85Waq2Gnem4mAn3prweq4q6Y3JEpnqMmnPoFRgmd3ySW0LLRqSKlwYHriCvJvUs2yjMaaoA-XzTXLeGMe45zmhv_XAno3Mj0xF7USuqNvnE9H343QHlq-eAgxpbTPNR9yzUkgLjwSR0NK4wKoxy-jDg-9vy8sUSToakzW-9fX13Em9Q8T6Z26uZhBN36XUYo5q7ggLXBZoub2Ofv7g6GCZfTxe034NCjiudXj7Omla0eTfo7QBPOcYxbE7qG-vl3_B1G-_i_JCAAA)\n[After](/playground/untitled#H4sIAAAAAAAAE31WXa-jNhD9K7PsdknUQJLurtRLPqo-VKrU1327uQ8GBnBjbGSb5KZR_nvHgMlXtyIS9njO-MyZGZRzUHCBJkhez4FkNQZJ8HvTBLPAnhq3MQcUFmlvVKszZ1mbTPPGbndyZ3ndKG3hDJZne7hAoVUNYY8JV-RBPgIt2AprhA18MpZZnIQ50_twuvLHNRrDSjRXj9fwiCJTBLIKdCsxq5j9EM4gtBU3QD8GjWBZd14xWYJqLTCZg2ViDyx1W4cz4dv0hsiB49FRHkyfsCgws3GjcTKZwmYLZ2feWc9o1W8zJQ2Fb62i5JUQRNRHgs-fx3WsisKg_RN5WVn4-WrvUd9VA9tH4-AcwbfFQIpkLWByvWzqSe2sk3kyjUlOec_XPU-3TRaz_75tuvKoi19e3OvipSpamVmupJM2F_gXnnJ1lBM8oLQjHceys8R7PMFms4HwD2lRhzeEe-EsvluSrHe2TJdo4wMTLY48XKwPzm0KGm2r5ajFtRYU4TWOY7-ddWHfxhDP0QkQhnf5PWRnVVkKnIx8fZsOb5dR16nwG4TCCRdCMphWQ7z1_DoOcp3zA2SCGbPZBa5jd0G_TRxmc36Me-mG6A7l60XIlMs8ce2-OXtrDyBItdz6qVjPadObzx-RZdV1nJjx64tXad1sz962njceOHfAzmk9JzrbXqg1lw3NkZL7vgE257t-uMDcO6attSSokpmgFqVMO2U93e_dDlzOUKsc-3t6zNZp6K9cG3sS2KGSUqiUiUmq8tNYoJwbmvpTAoXA96GyjCojI26xNglk6DpwOPm7NdRYp4ia0JL94bTqRiGB5WJxqFY37RGPoz3c6i4jP3rcUA7wmhqNywQW7om_YQ2L4UQdUBdCHSPiOQJ8bFcxHzeK0jKBY0XcV95SkCWlD9t-9eOM3TLKucauiyktJdpaPqT19ddF4wFHntsqgS-_XE01e48GMwnw02AtWZP02QyGVOkcNfk072CU4PkduZSWpVYt9SkcmJ64hPwHpWF5ziVls3wIFmmW89Y83vMeGf5PBxjcyPSkXNy10J18t3x6-a6CDtBq6SGklNKeazFyLahB3PVIGo2UbhOgGi9vKjzW_j6xVFFD17difXx5ebll0vwvkcGpn4sZ9MN3vqFYsJoL6gUuK9TcPrO_PxgzWMRfflSEr2NHPJf6lj1957rRpH8CNMG84JgHidUtXt4u_wK21LXERAgAAA==)\n<script>\n\timport { ---beforeUpdate, afterUpdate,--- tick } from 'svelte';\n\n\t---let updatingMessages = false;---\n\tlet theme = +++$state('dark')+++;\n\tlet messages = +++$state([])+++;\n\n\tlet viewport;\n\n\t---beforeUpdate(() => {---\n\t+++$effect.pre(() => {+++\n\t\t---if (!updatingMessages) return;---\n\t\t+++messages;+++\n\t\tconst autoscroll = viewport && viewport.offsetHeight + viewport.scrollTop > viewport.scrollHeight - 50;\n\n\t\tif (autoscroll) {\n\t\t\ttick().then(() => {\n\t\t\t\tviewport.scrollTo(0, viewport.scrollHeight);\n\t\t\t});\n\t\t}\n\n\t\t---updatingMessages = false;---\n\t});\n\n\tfunction handleKeydown(event) {\n\t\tif (event.key === 'Enter') {\n\t\t\tconst text = event.target.value;\n\t\t\tif (!text) return;\n\n\t\t\t---updatingMessages = true;---\n\t\t\tmessages = [...messages, text];\n\t\t\tevent.target.value = '';\n\t\t}\n\t}\n\n\tfunction toggle() {\n\t\ttheme = theme === 'dark' ? 'light' : 'dark';\n\t}\n</script>\n\n<div class:dark={theme === 'dark'}>\n\t<div bind:this={viewport}>\n\t\t{#each messages as message}\n\t\t\t<p>{message}</p>\n\t\t{/each}\n\t</div>\n\n\t<input +++onkeydown+++={handleKeydown} />\n\n\t<button +++onclick+++={toggle}> Toggle dark mode </button>\n</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Imperative component API"],"href":"/docs/svelte/imperative-component-api","content":"Every Svelte application starts by imperatively creating a root component. On the client this component is mounted to a specific element. On the server, you want to get back a string of HTML instead which you can render. The following functions help you achieve those tasks.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Imperative component API","mount"],"href":"/docs/svelte/imperative-component-api#mount","content":"Instantiates a component and mounts it to the given target: \nimport { mount } from 'svelte';\nimport App from './App.svelte';\n\nconst app = mount(App, {\n\ttarget: document.querySelector('#app'),\n\tprops: { some: 'property' }\n});You can mount multiple components per page, and you can also mount from within your application, for example when creating a tooltip component and attaching it to the hovered element.Note that unlike calling new App(...) in Svelte 4, things like effects (including onMount callbacks, and action functions) will not run during mount. If you need to force pending effects to run (in the context of a test, for example) you can do so with flushSync().","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Imperative component API","unmount"],"href":"/docs/svelte/imperative-component-api#unmount","content":"Unmounts a component that was previously created with `mount` or `hydrate`.If options.outro is true, transitions will play before the component is removed from the DOM:import { mount, unmount } from 'svelte';\nimport App from './App.svelte';\n\nconst app = mount(App, { target: document.body });\n\n// later\nunmount(app, { outro: true });Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Imperative component API","render"],"href":"/docs/svelte/imperative-component-api#render","content":"Only available on the server and when compiling with the server option. Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app: \nimport { render } from 'svelte/server';\nimport App from './App.svelte';\n\nconst result = render(App, {\n\tprops: { some: 'property' }\n});\nresult.body; // HTML for somewhere in this <body> tag\nresult.head; // HTML for somewhere in this <head> tag","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Imperative component API","hydrate"],"href":"/docs/svelte/imperative-component-api#hydrate","content":"Like mount, but will reuse up any HTML rendered by Svelte's SSR output (from the `render` function) inside the target and make it interactive: \nimport { hydrate } from 'svelte';\nimport App from './App.svelte';\n\nconst app = hydrate(App, {\n\ttarget: document.querySelector('#app'),\n\tprops: { some: 'property' }\n});As with mount, effects will not run during hydrate — use flushSync() immediately afterwards if you need them to.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Hydratable data"],"href":"/docs/svelte/hydratable","content":"In Svelte, when you want to render asynchronous content data on the server, you can simply await it. This is great! However, it comes with a pitfall: when hydrating that content on the client, Svelte has to redo the asynchronous work, which blocks hydration for however long it takes:<script>\n  import { getUser } from 'my-database-library';\n\n  // This will get the user on the server, render the user's name into the h1,\n  // and then, during hydration on the client, it will get the user _again_,\n  // blocking hydration until it's done.\n  const user = await getUser();\n</script>\n\n<h1>{user.name}</h1>That's silly, though. If we've already done the hard work of getting the data on the server, we don't want to get it again during hydration on the client. hydratable is a low-level API built to solve this problem. You probably won't need this very often — it will be used behind the scenes by whatever datafetching library you use. For example, it powers remote functions in SvelteKit.To fix the example above:<script>\n  import { hydratable } from 'svelte';\n  import { getUser } from 'my-database-library';\n\n  // During server rendering, this will serialize and stash the result of `getUser`, associating\n  // it with the provided key and baking it into the `head` content. During hydration, it will\n  // look for the serialized version, returning it instead of running `getUser`. After hydration\n  // is done, if it's called again, it'll simply invoke `getUser`.\n  const user = await hydratable('user', () => getUser());\n</script>\n\n<h1>{user.name}</h1>This API can also be used to provide access to random or time-based values that are stable between server rendering and hydration. For example, to get a random number that doesn't update on hydration:import { hydratable } from 'svelte';\nconst rand = hydratable('random', () => Math.random());If you're a library author, be sure to prefix the keys of your hydratable values with the name of your library so that your keys don't conflict with other libraries.","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Hydratable data","Serialization"],"href":"/docs/svelte/hydratable#Serialization","content":"All data returned from a hydratable function must be serializable. But this doesn't mean you're limited to JSON — Svelte uses `devalue`, which can serialize all sorts of things including Map, Set, URL, and BigInt. Check the documentation page for a full list. In addition to these, thanks to some Svelte magic, you can also fearlessly use promises:<script>\n  import { hydratable } from 'svelte';\n  const promises = hydratable('random', () => {\n    return {\n      one: Promise.resolve(1),\n      two: Promise.resolve(2)\n    }\n  });\n</script>\n\n{await promises.one}\n{await promises.two}","rank":null},{"breadcrumbs":["Docs","Svelte","Runtime","Hydratable data","CSP"],"href":"/docs/svelte/hydratable#CSP","content":"hydratable adds an inline <script> block to the head returned from render. If you're using Content Security Policy (CSP), this script will likely fail to run. You can provide a nonce to render:const nonce = crypto.randomUUID();\n\nconst { head, body } = await render(App, {\n\tcsp: { nonce }\n});This will add the nonce to the script block, on the assumption that you will later add the same nonce to the CSP header of the document that contains it:response.headers.set(\n  'Content-Security-Policy',\n  `script-src 'nonce-${nonce}'`\n );It's essential that a nonce — which, British slang definition aside, means 'number used once' — is only used when dynamically server rendering an individual response.If instead you are generating static HTML ahead of time, you must use hashes instead:const { head, body, hashes } = await render(App, {\n\tcsp: { hash: true }\n});hashes.script will be an array of strings like [\"sha256-abcd123\"]. As with nonce, the hashes should be used in your CSP header:response.headers.set(\n  'Content-Security-Policy',\n  `script-src ${hashes.script.map((hash) => `'${hash}'`).join(' ')}`\n );We recommend using nonce over hash if you can, as hash will interfere with streaming SSR in the future.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices"],"href":"/docs/svelte/best-practices","content":"This document outlines some best practices that will help you write fast, robust Svelte apps. It is also available as a svelte-core-bestpractices skill for your agents.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","$state"],"href":"/docs/svelte/best-practices#$state","content":"Only use the $state rune for variables that should be reactive — in other words, variables that cause an $effect, $derived or template expression to update. Everything else can be a normal variable.Objects and arrays ($state({...}) or $state([...])) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you're dealing with large objects that are only ever reassigned (rather than mutated), use $state.raw instead. This is often the case with API responses, for example.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","$derived"],"href":"/docs/svelte/best-practices#$derived","content":"To compute something from state, use $derived rather than $effect:// do this\nlet square = $derived(num * num);\n\n// don't do this\nlet square;\n\n$effect(() => {\n\tsquare = num * num;\n});[!NOTE] `$derived` is given an expression, _not_ a function. If you need to use a function (because the expression is complex, for example) use `$derived.by`.Deriveds are writable — you can assign to them, just like $state, except that they will re-evaluate when their expression changes.If the derived expression is an object or array, it will be returned as-is — it is not made deeply reactive. You can, however, use $state inside $derived.by in the rare cases that you need this.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","$effect"],"href":"/docs/svelte/best-practices#$effect","content":"Effects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.If you need to sync state to an external library such as D3, it is often neater to use [`{@attach ...}`](@attach)\nIf you need to run some code in response to user interaction, put the code directly in an event handler or use a [function binding](bind#Function-bindings) as appropriate\nIf you need to log values for debugging purposes, use [`$inspect`]($inspect)\nIf you need to observe something external to Svelte, use [`createSubscriber`](svelte-reactivity#createSubscriber)Never wrap the contents of an effect in if (browser) {...} or similar — effects do not run on the server.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","$props"],"href":"/docs/svelte/best-practices#$props","content":"Treat props as though they will change. For example, values that depend on props should usually use $derived: \nlet { type } = $props();\n\n// do this\nlet color = $derived(type === 'danger' ? 'red' : 'green');\n\n// don't do this — `color` will not update if `type` changes\nlet color = type === 'danger' ? 'red' : 'green';","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","$inspect.trace"],"href":"/docs/svelte/best-practices#$inspect.trace","content":"$inspect.trace is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add $inspect.trace(label) as the first line of an $effect or $derived.by (or any function they call) to trace their dependencies and discover which one triggered an update.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Events"],"href":"/docs/svelte/best-practices#Events","content":"Any element attribute starting with on is treated as an event listener:<button onclick={() => {...}}>click me</button>\n\n<!-- attribute shorthand also works -->\n<button {onclick}>...</button>\n\n<!-- so do spread attributes -->\n<button {...props}>...</button>If you need to attach listeners to window or document you can use <svelte:window> and <svelte:document>:<svelte:window onkeydown={...} />\n<svelte:document onvisibilitychange={...} />Avoid using onMount or $effect for this.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Snippets"],"href":"/docs/svelte/best-practices#Snippets","content":"Snippets are a way to define reusable chunks of markup that can be instantiated with the `{@render ...}` tag, or passed to components as props. They must be declared within the template.{#snippet greeting(name)}\n  <p>hello {name}!</p>\n{/snippet}\n\n{@render greeting('world')}[!NOTE] Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside `<script>`. A snippet that doesn't reference component state is also available in a `<script module>`, in which case it can be exported for use by other components.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Each blocks"],"href":"/docs/svelte/best-practices#Each-blocks","content":"Prefer to use keyed each blocks — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.[!NOTE] The key _must_ uniquely identify the object. Do not use the index as a key.Avoid destructuring if you need to mutate the item (with something like bind:value={item.count}, for example).","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Using JavaScript variables in CSS"],"href":"/docs/svelte/best-practices#Using-JavaScript-variables-in-CSS","content":"If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the style: directive.<div style:--columns={columns}>...</div>You can then reference var(--columns) inside the component's <style>.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Styling child components"],"href":"/docs/svelte/best-practices#Styling-child-components","content":"The CSS in a component's <style> is scoped to that component. If a parent component needs to control the child's styles, the preferred way is to use CSS custom properties:<!-- Parent.svelte -->\n<Child --color=\"red\" />\n\n<!-- Child.svelte -->\n<h1>Hello</h1>\n\n<style>\n\th1 {\n\t\tcolor: var(--color);\n\t}\n</style>If this is impossible (for example, the child component comes from a library) you can use :global to override styles:<div>\n\t<Child />\n</div>\n\n<style>\n\tdiv :global {\n\t\th1 {\n\t\t\tcolor: red;\n\t\t}\n\t}\n</style>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Context"],"href":"/docs/svelte/best-practices#Context","content":"Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.Use createContext rather than setContext and getContext, as it provides type safety.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Async Svelte"],"href":"/docs/svelte/best-practices#Async-Svelte","content":"If using version 5.36 or higher, you can use await expressions and hydratable to use promises directly inside components. Note that these require the experimental.async option to be enabled in svelte.config.js as they are not yet considered fully stable.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Best practices","Avoid legacy features"],"href":"/docs/svelte/best-practices#Avoid-legacy-features","content":"Always use runes mode for new code, and avoid features that have more modern replacements:use `$state` instead of implicit reactivity (e.g. `let count = 0; count += 1`)\nuse `$derived` and `$effect` instead of `$:` assignments and statements (but only use effects when there is no better solution)\nuse `$props` instead of `export let`, `$$props` and `$$restProps`\nuse `onclick={...}` instead of `on:click={...}`\nuse `{#snippet ...}` and `{@render ...}` instead of `<slot>` and `$$slots` and `<svelte:fragment>`\nuse `<DynamicComponent>` instead of `<svelte:component this={DynamicComponent}>`\nuse `import Self from './ThisComponent.svelte'` and `<Self>` instead of `<svelte:self>`\nuse classes with `$state` fields to share reactivity between components, instead of using stores\nuse `{@attach ...}` instead of `use:action`\nuse clsx-style arrays and objects in `class` attributes, instead of the `class:` directive","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing"],"href":"/docs/svelte/testing","content":"Testing helps you write and maintain your code and guard against regressions. Testing frameworks help you with that, allowing you to describe assertions or expectations about how your code should behave. Svelte is unopinionated about which testing framework you use — you can write unit tests, integration tests, and end-to-end tests using solutions like Vitest, Jasmine, Cypress and Playwright.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing","Unit and component tests with Vitest"],"href":"/docs/svelte/testing#Unit-and-component-tests-with-Vitest","content":"Unit tests allow you to test small isolated parts of your code. Integration tests allow you to test parts of your application to see if they work together. If you're using Vite (including via SvelteKit), we recommend using Vitest. You can use the Svelte CLI to setup Vitest either during project creation or later on.To setup Vitest manually, first install it:npm install -D vitestThen adjust your vite.config.js:\n \nimport { defineConfig } from +++'vitest/config'+++;\n\nexport default defineConfig({\n\t// ...\n\t// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node\n\tresolve: process.env.VITEST\n\t\t? {\n\t\t\t\tconditions: ['browser']\n\t\t\t}\n\t\t: undefined\n});[!NOTE] If loading the browser version of all your packages is undesirable, because (for example) you also test backend libraries, [you may need to resort to an alias configuration](https://github.com/testing-library/svelte-testing-library/issues/222#issuecomment-1909993331)You can now write unit tests for code inside your .js/.ts files:import { flushSync } from 'svelte';\nimport { expect, test } from 'vitest';\nimport { multiplier } from './multiplier.svelte.js';\n\ntest('Multiplier', () => {\n\tlet double = multiplier(0, 2);\n\n\texpect(double.value).toEqual(0);\n\n\tdouble.set(5);\n\n\texpect(double.value).toEqual(10);\n}); \n/**\n * @param {number} initial\n * @param {number} k\n */\nexport function multiplier(initial, k) {\n\tlet count = $state(initial);\n\n\treturn {\n\t\tget value() {\n\t\t\treturn count * k;\n\t\t},\n\t\t/** @param {number} c */\n\t\tset: (c) => {\n\t\t\tcount = c;\n\t\t}\n\t};\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing","Unit and component tests with Vitest","Using runes inside your test files"],"href":"/docs/svelte/testing#Unit-and-component-tests-with-Vitest-Using-runes-inside-your-test-files","content":"Since Vitest processes your test files the same way as your source files, you can use runes inside your tests as long as the filename includes .svelte:import { flushSync } from 'svelte';\nimport { expect, test } from 'vitest';\nimport { multiplier } from './multiplier.svelte.js';\n\ntest('Multiplier', () => {\n\tlet count = $state(0);\n\tlet double = multiplier(() => count, 2);\n\n\texpect(double.value).toEqual(0);\n\n\tcount = 5;\n\n\texpect(double.value).toEqual(10);\n}); \n/**\n * @param {() => number} getCount\n * @param {number} k\n */\nexport function multiplier(getCount, k) {\n\treturn {\n\t\tget value() {\n\t\t\treturn getCount() * k;\n\t\t}\n\t};\n}If the code being tested uses effects, you need to wrap the test inside $effect.root:import { flushSync } from 'svelte';\nimport { expect, test } from 'vitest';\nimport { logger } from './logger.svelte.js';\n\ntest('Effect', () => {\n\tconst cleanup = $effect.root(() => {\n\t\tlet count = $state(0);\n\n\t\t// logger uses an $effect to log updates of its input\n\t\tlet log = logger(() => count);\n\n\t\t// effects normally run after a microtask,\n\t\t// use flushSync to execute all pending effects synchronously\n\t\tflushSync();\n\t\texpect(log).toEqual([0]);\n\n\t\tcount = 1;\n\t\tflushSync();\n\n\t\texpect(log).toEqual([0, 1]);\n\t});\n\n\tcleanup();\n}); \n/**\n * @param {() => any} getValue\n */\nexport function logger(getValue) {\n\t/** @type {any[]} */\n\tlet log = [];\n\n\t$effect(() => {\n\t\tlog.push(getValue());\n\t});\n\n\treturn log;\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing","Unit and component tests with Vitest","Component testing"],"href":"/docs/svelte/testing#Unit-and-component-tests-with-Vitest-Component-testing","content":"It is possible to test your components in isolation, which allows you to render them in a browser (real or simulated), simulate behavior, and make assertions, without spinning up your whole app.[!NOTE] Before writing component tests, think about whether you actually need to test the component, or if it's more about the logic _inside_ the component. If so, consider extracting out that logic to test it in isolation, without the overhead of a component.To get started, install jsdom (a library that shims DOM APIs):npm install -D jsdomThen adjust your vite.config.js: \nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n\tplugins: [\n\t\t/* ... */\n\t],\n\ttest: {\n\t\t// If you are testing components client-side, you need to set up a DOM environment.\n\t\t// If not all your files should have this environment, you can use a\n\t\t// `// @vitest-environment jsdom` comment at the top of the test files instead.\n\t\tenvironment: 'jsdom'\n\t},\n\t// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node\n\tresolve: process.env.VITEST\n\t\t? {\n\t\t\t\tconditions: ['browser']\n\t\t\t}\n\t\t: undefined\n});After that, you can create a test file in which you import the component to test, interact with it programmatically and write expectations about the results: \nimport { flushSync, mount, unmount } from 'svelte';\nimport { expect, test } from 'vitest';\nimport Component from './Component.svelte';\n\ntest('Component', () => {\n\t// Instantiate the component using Svelte's `mount` API\n\tconst component = mount(Component, {\n\t\ttarget: document.body, // `document` exists because of jsdom\n\t\tprops: { initial: 0 }\n\t});\n\n\texpect(document.body.innerHTML).toBe('<button>0</button>');\n\n\t// Click the button, then flush the changes so you can synchronously write expectations\n\tdocument.body.querySelector('button')?.click();\n\tflushSync();\n\n\texpect(document.body.innerHTML).toBe('<button>1</button>');\n\n\t// Remove the component from the DOM\n\tunmount(component);\n});While the process is very straightforward, it is also low level and somewhat brittle, as the precise structure of your component may change frequently. Tools like @testing-library/svelte can help streamline your tests. The above test could be rewritten like this: \n \nimport { render, screen } from '@testing-library/svelte';\nimport userEvent from '@testing-library/user-event';\nimport { expect, test } from 'vitest';\nimport Component from './Component.svelte';\n\ntest('Component', async () => {\n\tconst user = userEvent.setup();\n\trender(Component);\n\n\tconst button = screen.getByRole('button');\n\texpect(button).toHaveTextContent(0);\n\n\tawait user.click(button);\n\texpect(button).toHaveTextContent(1);\n});When writing component tests that involve two-way bindings, context or snippet props, it's best to create a wrapper component for your specific test and interact with that. @testing-library/svelte contains some examples.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing","Component tests with Storybook"],"href":"/docs/svelte/testing#Component-tests-with-Storybook","content":"Storybook is a tool for developing and documenting UI components, and it can also be used to test your components. They're run with Vitest's browser mode, which renders your components in a real browser for the most realistic testing environment.To get started, first install Storybook (using Svelte's CLI) in your project via npx sv add storybook and choose the recommended configuration that includes testing features. If you're already using Storybook, and for more information on Storybook's testing capabilities, follow the Storybook testing docs to get started.You can create stories for component variations and test interactions with the play function, which allows you to simulate behavior and make assertions using the Testing Library and Vitest APIs. Here's an example of two stories that can be tested, one that renders an empty LoginForm component and one that simulates a user filling out the form: \n<script module>\n\timport { defineMeta } from '@storybook/addon-svelte-csf';\n\timport { expect, fn } from 'storybook/test';\n\n\timport LoginForm from './LoginForm.svelte';\n\n\tconst { Story } = defineMeta({\n\t\tcomponent: LoginForm,\n\t\targs: {\n\t\t\t// Pass a mock function to the `onSubmit` prop\n\t\t\tonSubmit: fn(),\n\t\t}\n\t});\n</script>\n\n<Story name=\"Empty Form\" />\n\n<Story\n\tname=\"Filled Form\"\n\tplay={async ({ args, canvas, userEvent }) => {\n\t\t// Simulate a user filling out the form\n\t\tawait userEvent.type(canvas.getByTestId('email'), 'email@provider.com');\n\t\tawait userEvent.type(canvas.getByTestId('password'), 'a-random-password');\n\t\tawait userEvent.click(canvas.getByRole('button'));\n\n\t\t// Run assertions\n\t\tawait expect(args.onSubmit).toHaveBeenCalledTimes(1);\n\t\tawait expect(canvas.getByText('You’re in!')).toBeInTheDocument();\n\t}}\n/>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Testing","End-to-end tests with Playwright"],"href":"/docs/svelte/testing#End-to-end-tests-with-Playwright","content":"E2E (short for 'end to end') tests allow you to test your full application through the eyes of the user. This section uses Playwright as an example, but you can also use other solutions like Cypress or NightwatchJS.You can use the Svelte CLI to setup Playwright either during project creation or later on. You can also set it up with `npm init playwright`. Additionally, you may also want to install an IDE plugin such as the VS Code extension to be able to execute tests from inside your IDE.If you've run npm init playwright or are not using Vite, you may need to adjust the Playwright config to tell Playwright what to do before running the tests — mainly starting your application at a certain port. For example: \nconst config = {\n\twebServer: {\n\t\tcommand: 'npm run build && npm run preview',\n\t\tport: 4173\n\t},\n\ttestDir: 'tests',\n\ttestMatch: /(.+\\.)?(test|spec)\\.[jt]s/\n};\n\nexport default config;You can now start writing tests. These are totally unaware of Svelte as a framework, so you mainly interact with the DOM and write assertions. \n \nimport { expect, test } from '@playwright/test';\n\ntest('home page has expected h1', async ({ page }) => {\n\tawait page.goto('/');\n\tawait expect(page.locator('h1')).toBeVisible();\n});","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript"],"href":"/docs/svelte/typescript","content":"You can use TypeScript within Svelte components. IDE extensions like the Svelte VS Code extension will help you catch errors right in your editor, and `svelte-check` does the same on the command line, which you can integrate into your CI.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","<script lang=\"ts\">"],"href":"/docs/svelte/typescript#script-lang-ts","content":"To use TypeScript inside your Svelte components, add lang=\"ts\" to your script tags:<script lang=\"ts\">\n\tlet name: string = 'world';\n\n\tfunction greet(name: string) {\n\t\talert(`Hello, ${name}!`);\n\t}\n</script>\n\n<button onclick={(e: Event) => greet(e.target.innerText)}>\n\t{name as string}\n</button>Doing so allows you to use TypeScript's type-only features. That is, all features that just disappear when transpiling to JavaScript, such as type annotations or interface declarations. Features that require the TypeScript compiler to output actual code are not supported. This includes:using enums\nusing `private`, `protected` or `public` modifiers in constructor functions together with initializers\nusing features that are not yet part of the ECMAScript standard (i.e. not level 4 in the TC39 process) and therefore not implemented yet within Acorn, the parser we use for parsing JavaScriptIf you want to use one of these features, you need to setup up a script preprocessor.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Preprocessor setup"],"href":"/docs/svelte/typescript#Preprocessor-setup","content":"To use non-type-only TypeScript features within Svelte components, you need to add a preprocessor that will turn TypeScript into JavaScript.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Preprocessor setup","Using Vite"],"href":"/docs/svelte/typescript#Preprocessor-setup-Using-Vite","content":"If you're using SvelteKit, or Vite without SvelteKit, you can use vitePreprocess from @sveltejs/vite-plugin-svelte in your config file: \n \nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\nconst config = {\n\t// Note the additional `{ script: true }`\n\tpreprocess: vitePreprocess({ script: true })\n};\n\nexport default config;","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Preprocessor setup","Using other build tools"],"href":"/docs/svelte/typescript#Preprocessor-setup-Using-other-build-tools","content":"If you're using tools like Rollup (via rollup-plugin-svelte) or Webpack (via svelte-loader) instead, install typescript and svelte-preprocess and add the preprocessor to the plugin config. See the respective plugin READMEs for more info.[!NOTE] If you're starting a new project, we recommend using SvelteKit or Vite instead","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","tsconfig.json settings"],"href":"/docs/svelte/typescript#tsconfig.json-settings","content":"When using TypeScript, make sure your tsconfig.json is setup correctly.Use a [`target`](https://www.typescriptlang.org/tsconfig/#target) of at least `ES2015` so classes are not compiled to functions\nSet [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) to `true` so that imports are left as-is\nSet [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules) to `true` so that each file is looked at in isolation. TypeScript has a few features which require cross-file analysis and compilation, which the Svelte compiler and tooling like Vite don't do.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Typing `$props`"],"href":"/docs/svelte/typescript#Typing-$props","content":"Type $props just like a regular object with certain properties.<script lang=\"ts\">\n\timport type { Snippet } from 'svelte';\n\n\tinterface Props {\n\t\trequiredProperty: number;\n\t\toptionalProperty?: boolean;\n\t\tsnippetWithStringArgument: Snippet<[string]>;\n\t\teventHandler: (arg: string) => void;\n\t\t[key: string]: unknown;\n\t}\n\n\tlet {\n\t\trequiredProperty,\n\t\toptionalProperty,\n\t\tsnippetWithStringArgument,\n\t\teventHandler,\n\t\t...everythingElse\n\t}: Props = $props();\n</script>\n\n<button onclick={() => eventHandler('clicked button')}>\n\t{@render snippetWithStringArgument('hello')}\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Generic `$props`"],"href":"/docs/svelte/typescript#Generic-$props","content":"Components can declare a generic relationship between their properties. One example is a generic list component that receives a list of items and a callback property that receives an item from the list. To declare that the items property and the select callback operate on the same types, add the generics attribute to the script tag:<script lang=\"ts\" generics=\"Item extends { text: string }\">\n\tinterface Props {\n\t\titems: Item[];\n\t\tselect(item: Item): void;\n\t}\n\n\tlet { items, select }: Props = $props();\n</script>\n\n{#each items as item}\n\t<button onclick={() => select(item)}>\n\t\t{item.text}\n\t</button>\n{/each}The content of generics is what you would put between the <...> tags of a generic function. In other words, you can use multiple generics, extends and fallback types.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Typing wrapper components"],"href":"/docs/svelte/typescript#Typing-wrapper-components","content":"In case you're writing a component that wraps a native element, you may want to expose all the attributes of the underlying element to the user. In that case, use (or extend from) one of the interfaces provided by svelte/elements. Here's an example for a Button component:<script lang=\"ts\">\n\timport type { HTMLButtonAttributes } from 'svelte/elements';\n\n\tlet { children, ...rest }: HTMLButtonAttributes = $props();\n</script>\n\n<button {...rest}>\n\t{@render children?.()}\n</button>Not all elements have a dedicated type definition. For those without one, use SvelteHTMLElements:<script lang=\"ts\">\n\timport type { SvelteHTMLElements } from 'svelte/elements';\n\n\tlet { children, ...rest }: SvelteHTMLElements['div'] = $props();\n</script>\n\n<div {...rest}>\n\t{@render children?.()}\n</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Typing `$state`"],"href":"/docs/svelte/typescript#Typing-$state","content":"You can type $state like any other variable.let count: number = $state(0);If you don't give $state an initial value, part of its types will be undefined. \n// Error: Type 'number | undefined' is not assignable to type 'number'\nlet count: number = $state();If you know that the variable will be defined before you first use it, use an as casting. This is especially useful in the context of classes:class Counter {\n\tcount = $state() as number;\n\tconstructor(initial: number) {\n\t\tthis.count = initial;\n\t}\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","The `Component` type"],"href":"/docs/svelte/typescript#The-Component-type","content":"Svelte components are of type Component. You can use it and its related types to express a variety of constraints.Using it together with dynamic components to restrict what kinds of component can be passed to it:<script lang=\"ts\">\n\timport type { Component } from 'svelte';\n\n\tinterface Props {\n\t\t// only components that have at most the \"prop\"\n\t\t// property required can be passed\n\t\tDynamicComponent: Component<{ prop: string }>;\n\t}\n\n\tlet { DynamicComponent }: Props = $props();\n</script>\n\n<DynamicComponent prop=\"foo\" />[!LEGACY] In Svelte 4, components were of type `SvelteComponent`To extract the properties from a component, use ComponentProps.import type { Component, ComponentProps } from 'svelte';\nimport MyComponent from './MyComponent.svelte';\n\nfunction withProps<TComponent extends Component<any>>(\n\tcomponent: TComponent,\n\tprops: ComponentProps<TComponent>\n) {}\n\n// Errors if the second argument is not the correct props expected\n// by the component in the first argument.\nwithProps(MyComponent, { foo: 'bar' });To declare that a variable expects the constructor or instance type of a component:<script lang=\"ts\">\n\timport MyComponent from './MyComponent.svelte';\n\n\tlet componentConstructor: typeof MyComponent = MyComponent;\n\tlet componentInstance: MyComponent;\n</script>\n\n<MyComponent bind:this={componentInstance} />","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","TypeScript","Enhancing built-in DOM types"],"href":"/docs/svelte/typescript#Enhancing-built-in-DOM-types","content":"Svelte provides a best effort of all the HTML DOM types that exist. Sometimes you may want to use experimental attributes or custom events coming from an action. In these cases, TypeScript will throw a type error, saying that it does not know these types. If it's a non-experimental standard attribute/event, this may very well be a missing typing from our HTML typings. In that case, you are welcome to open an issue and/or a PR fixing it.In case this is a custom or experimental attribute/event, you can enhance the typings by augmenting the svelte/elements module like this: \nimport { HTMLButtonAttributes } from 'svelte/elements';\n\ndeclare module 'svelte/elements' {\n\t// add a new element\n\texport interface SvelteHTMLElements {\n\t\t'custom-button': HTMLButtonAttributes;\n\t}\n\n\t// add a new global attribute that is available on all html elements\n\texport interface HTMLAttributes<T> {\n\t\tglobalattribute?: string;\n\t}\n\n\t// add a new attribute for button elements\n\texport interface HTMLButtonAttributes {\n\t\tveryexperimentalattribute?: string;\n\t}\n}\n\nexport {}; // ensure this is not an ambient module, else types will be overridden instead of augmentedThen make sure that the d.ts file is referenced in your tsconfig.json. If it reads something like \"include\": [\"src/**/*\"] and your d.ts file is inside src, it should work. You may need to reload for the changes to take effect.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Custom elements"],"href":"/docs/svelte/custom-elements","content":"Svelte components can also be compiled to custom elements (aka web components) using the customElement: true compiler option. You should specify a tag name for the component using the <svelte:options> element. Within the custom element you can access the host element via the `$host` rune.<svelte:options customElement=\"my-element\" />\n\n<script>\n\tlet { name = 'world' } = $props();\n</script>\n\n<h1>Hello {name}!</h1>\n<slot />You can leave out the tag name for any of your inner components which you don't want to expose and use them like regular Svelte components. Consumers of the component can still name it afterwards if needed, using the static element property which contains the custom element constructor and which is available when the customElement compiler option is true. \nimport MyElement from './MyElement.svelte';\n\ncustomElements.define('my-element', MyElement.element);Once a custom element has been defined, it can be used as a regular DOM element:document.body.innerHTML = `\n\t<my-element>\n\t\t<p>This is some slotted content</p>\n\t</my-element>\n`;Any props are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible). \nconst el = document.querySelector('my-element');\n\n// get the current value of the 'name' prop\nconsole.log(el.name);\n\n// set a new value, updating the shadow DOM\nel.name = 'everybody';Note that you need to list out all properties explicitly, i.e. doing let props = $props() without declaring props in the component options means that Svelte can't know which props to expose as properties on the DOM element.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Custom elements","Component lifecycle"],"href":"/docs/svelte/custom-elements#Component-lifecycle","content":"Custom elements are created from Svelte components using a wrapper approach. This means the inner Svelte component has no knowledge that it is a custom element. The custom element wrapper takes care of handling its lifecycle appropriately.When a custom element is created, the Svelte component it wraps is not created right away. It is only created in the next tick after the connectedCallback is invoked. Properties assigned to the custom element before it is inserted into the DOM are temporarily saved and then set on component creation, so their values are not lost. The same does not work for invoking exported functions on the custom element though, they are only available after the element has mounted. If you need to invoke functions before component creation, you can work around it by using the `extend` option.When a custom element written with Svelte is created or updated, the shadow DOM will reflect the value in the next tick, not immediately. This way updates can be batched, and DOM moves which temporarily (but synchronously) detach the element from the DOM don't lead to unmounting the inner component.The inner Svelte component is destroyed in the next tick after the disconnectedCallback is invoked.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Custom elements","Component options"],"href":"/docs/svelte/custom-elements#Component-options","content":"When constructing a custom element, you can tailor several aspects by defining customElement as an object within <svelte:options> since Svelte 4. This object may contain the following properties:`tag: string`: an optional `tag` property for the custom element's name. If set, a custom element with this tag name will be defined with the document's `customElements` registry upon importing this component.\n`shadow`: an optional property to modify shadow root properties. It accepts the following values:\n- `\"none\"`: No shadow root is created. Note that styles are then no longer encapsulated, and you can't use slots.\n- `\"open\"`: Shadow root is created with the `mode: \"open\"` option.\n- [`ShadowRootInit`](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options): You can pass a settings object that will be passed to `attachShadow()` when shadow root is created.\n`props`: an optional property to modify certain details and behaviors of your component's properties. It offers the following settings:\n- `attribute: string`: To update a custom element's prop, you have two alternatives: either set the property on the custom element's reference as illustrated above or use an HTML attribute. For the latter, the default attribute name is the lowercase property name. Modify this by assigning `attribute: \"<desired name>\"`.\n- `reflect: boolean`: By default, updated prop values do not reflect back to the DOM. To enable this behavior, set `reflect: true`.\n- `type: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object'`: While converting an attribute value to a prop value and reflecting it back, the prop value is assumed to be a `String` by default. This may not always be accurate. For instance, for a number type, define it using `type: \"Number\"`\n  You don't need to list all properties, those not listed will use the default settings.\n`extend`: an optional property which expects a function as its argument. It is passed the custom element class generated by Svelte and expects you to return a custom element class. This comes in handy if you have very specific requirements to the life cycle of the custom element or want to enhance the class to for example use [ElementInternals](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals#examples) for better HTML form integration.<svelte:options\n\tcustomElement={{\n\t\ttag: 'custom-element',\n\t\tshadow: {\n\t\t\tmode: import.meta.env.DEV ? 'open' : 'closed',\n\t\t\tclonable: true,\n\t\t\t// ...\n\t\t},\n\t\tprops: {\n\t\t\tname: { reflect: true, type: 'Number', attribute: 'element-index' }\n\t\t},\n\t\textend: (customElementConstructor) => {\n\t\t\t// Extend the class so we can let it participate in HTML forms\n\t\t\treturn class extends customElementConstructor {\n\t\t\t\tstatic formAssociated = true;\n\n\t\t\t\tconstructor() {\n\t\t\t\t\tsuper();\n\t\t\t\t\tthis.attachedInternals = this.attachInternals();\n\t\t\t\t}\n\n\t\t\t\t// Add the function here, not below in the component so that\n\t\t\t\t// it's always available, not just when the inner Svelte component\n\t\t\t\t// is mounted\n\t\t\t\trandomIndex() {\n\t\t\t\t\tthis.elementIndex = Math.random();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}}\n/>\n\n<script>\n\tlet { elementIndex, attachedInternals } = $props();\n\t// ...\n\tfunction check() {\n\t\tattachedInternals.checkValidity();\n\t}\n</script>\n\n...[!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang=\"ts\"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Custom elements","Caveats and limitations"],"href":"/docs/svelte/custom-elements#Caveats-and-limitations","content":"Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as most frameworks. There are, however, some important differences to be aware of:Styles are _encapsulated_, rather than merely _scoped_ (unless you set `shadow: \"none\"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier\nInstead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string\nCustom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads\nIn Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times\nThe deprecated `let:` directive has no effect, because custom elements do not have a way to pass data to the parent component that fills the slot\nPolyfills are required to support older browsers\nYou can use Svelte's context feature between regular Svelte components within a custom element, but you can't use them across custom elements. In other words, you can't use `setContext` on a parent custom element and read that with `getContext` in a child custom element.\nDon't declare properties or attributes starting with `on`, as their usage will be interpreted as an event listener. In other words, Svelte treats `<custom-element oneworld={true}></custom-element>` as `customElement.addEventListener('eworld', true)` (and not as `customElement.oneworld = true`)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Browser support"],"href":"/docs/svelte/browser-support","content":"The table below shows the minimum browser versions Svelte is expected to work in, derived from the browser APIs used by Svelte's internal code.\nBrowser ,Minimum version \nChrome/Edge ,87 \nFirefox ,83 \nSafari ,14 \nOpera ,73 \nOpera (Android) ,62 \nSamsung Internet ,14.0 \nAndroid WebView ,87 \nInternet Explorer ,not supported [!NOTE] This equates to a <a href=\"https://web-platform-dx.github.io/baseline/\">Baseline</a> target of 2020.This table only covers Svelte itself. It does not include SvelteKit, other Svelte libraries, or your own code.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Browser support","Exceptions"],"href":"/docs/svelte/browser-support#Exceptions","content":"A few Svelte features require a higher minimum browser version. You'll only need to take the following table into consideration if you use these specific features.\nFeature ,Chrome/Edge ,Firefox ,Safari \n[`$state.snapshot`](/docs/svelte/$state#$state.snapshot) ,98 ,94 ,15.4 \n[`bind:devicePixelContentBoxSize`](/docs/svelte/bind#Dimensions) ,<span style=\"color: var(--sk-fg-4)\">—</span> ,93 ,not supported \n[`flip` from `svelte/animate`](/docs/svelte/svelte-animate#flip) ,<span style=\"color: var(--sk-fg-4)\">—</span> ,126 ,<span style=\"color: var(--sk-fg-4)\">—</span>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide"],"href":"/docs/svelte/v4-migration-guide","content":"This migration guide provides an overview of how to migrate from Svelte version 3 to 4. See the linked PRs for more details about each change. Use the migration script to migrate some of these automatically: npx svelte-migrate@latest svelte-4If you're a library author, consider whether to only support Svelte 4 or if it's possible to support Svelte 3 too. Since most of the breaking changes don't affect many people, this may be easily possible. Also remember to update the version range in your peerDependencies.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Minimum version requirements"],"href":"/docs/svelte/v4-migration-guide#Minimum-version-requirements","content":"Upgrade to Node 16 or higher. Earlier versions are no longer supported. ([#8566](https://github.com/sveltejs/svelte/issues/8566))\nIf you are using SvelteKit, upgrade to 1.20.4 or newer ([sveltejs/kit#10172](https://github.com/sveltejs/kit/pull/10172))\nIf you are using Vite without SvelteKit, upgrade to `vite-plugin-svelte` 2.4.1 or newer ([#8516](https://github.com/sveltejs/svelte/issues/8516))\nIf you are using webpack, upgrade to webpack 5 or higher and `svelte-loader` 3.1.8 or higher. Earlier versions are no longer supported. ([#8515](https://github.com/sveltejs/svelte/issues/8515), [198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))\nIf you are using Rollup, upgrade to `rollup-plugin-svelte` 7.1.5 or higher ([198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))\nIf you are using TypeScript, upgrade to TypeScript 5 or higher. Lower versions might still work, but no guarantees are made about that. ([#8488](https://github.com/sveltejs/svelte/issues/8488))","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Browser conditions for bundlers"],"href":"/docs/svelte/v4-migration-guide#Browser-conditions-for-bundlers","content":"Bundlers must now specify the browser condition when building a frontend bundle for the browser. SvelteKit and Vite will handle this automatically for you. If you're using any others, you may observe lifecycle callbacks such as onMount not get called and you'll need to update the module resolution configuration.For Rollup this is done within the `@rollup/plugin-node-resolve` plugin by setting `browser: true` in its options. See the [`rollup-plugin-svelte`](https://github.com/sveltejs/rollup-plugin-svelte/#usage) documentation for more details\nFor webpack this is done by adding `\"browser\"` to the `conditionNames` array. You may also have to update your `alias` config, if you have set it. See the [`svelte-loader`](https://github.com/sveltejs/svelte-loader#usage) documentation for more details(#8516)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Removal of CJS related output"],"href":"/docs/svelte/v4-migration-guide#Removal-of-CJS-related-output","content":"Svelte no longer supports the CommonJS (CJS) format for compiler output and has also removed the svelte/register hook and the CJS runtime version. If you need to stay on the CJS output format, consider using a bundler to convert Svelte's ESM output to CJS in a post-build step. (#8613)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Stricter types for Svelte functions"],"href":"/docs/svelte/v4-migration-guide#Stricter-types-for-Svelte-functions","content":"There are now stricter types for createEventDispatcher, Action, ActionReturn, and onMount:`createEventDispatcher` now supports specifying that a payload is optional, required, or non-existent, and the call sites are checked accordingly ([#7224](https://github.com/sveltejs/svelte/issues/7224)) \nimport { createEventDispatcher } from 'svelte';\n\nconst dispatch = createEventDispatcher<{\n\toptional: number | null;\n\trequired: string;\n\tnoArgument: null;\n}>();\n\n// Svelte version 3:\ndispatch('optional');\ndispatch('required'); // I can still omit the detail argument\ndispatch('noArgument', 'surprise'); // I can still add a detail argument\n\n// Svelte version 4 using TypeScript strict mode:\ndispatch('optional');\ndispatch('required'); // error, missing argument\ndispatch('noArgument', 'surprise'); // error, cannot pass an argument`Action` and `ActionReturn` have a default parameter type of `undefined` now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically ([#7442](https://github.com/sveltejs/svelte/pull/7442)) \n---const action: Action = (node, params) => { ... } // this is now an error if you use params in any way---\n+++const action: Action<HTMLElement, string> = (node, params) => { ... } // params is of type string+++`onMount` now shows a type error if you return a function asynchronously from it, because this is likely a bug in your code where you expect the callback to be called on destroy, which it will only do for synchronously returned functions ([#8136](https://github.com/sveltejs/svelte/issues/8136)) \n// Example where this change reveals an actual bug\nonMount(\n---\t// someCleanup() not called because function handed to onMount is async\n\tasync () => {\n\t\tconst something = await foo();---\n+++\t// someCleanup() is called because function handed to onMount is sync\n\t() => {\n\t\tfoo().then(something => {...});\n\t\t// ...\n\t\treturn () => someCleanup();\n\t}\n);","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Custom Elements with Svelte"],"href":"/docs/svelte/v4-migration-guide#Custom-Elements-with-Svelte","content":"The creation of custom elements with Svelte has been overhauled and significantly improved. The tag option is deprecated in favor of the new customElement option:---<svelte:options tag=\"my-component\" />---\n+++<svelte:options customElement=\"my-component\" />+++This change was made to allow more configurability for advanced use cases. The migration script will adjust your code automatically. The update timing of properties has changed slightly as well. (#8457)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","SvelteComponentTyped is deprecated"],"href":"/docs/svelte/v4-migration-guide#SvelteComponentTyped-is-deprecated","content":"SvelteComponentTyped is deprecated, as SvelteComponent now has all its typing capabilities. Replace all instances of SvelteComponentTyped with SvelteComponent.---import { SvelteComponentTyped } from 'svelte';---\n+++import { SvelteComponent } from 'svelte';+++\n\n---export class Foo extends SvelteComponentTyped<{ aProp: string }> {}---\n+++export class Foo extends SvelteComponent<{ aProp: string }> {}+++If you have used SvelteComponent as the component instance type previously, you may see a somewhat opaque type error now, which is solved by changing : typeof SvelteComponent to : typeof SvelteComponent<any>.<script>\n\timport ComponentA from './ComponentA.svelte';\n\timport ComponentB from './ComponentB.svelte';\n\timport { SvelteComponent } from 'svelte';\n\n\tlet component: typeof SvelteComponent+++<any>+++;\n\n\tfunction choseRandomly() {\n\t\tcomponent = Math.random() > 0.5 ? ComponentA : ComponentB;\n\t}\n</script>\n\n<button on:click={choseRandomly}>random</button>\n<svelte:element this={component} />The migration script will do both automatically for you. (#8512)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Transitions are local by default"],"href":"/docs/svelte/v4-migration-guide#Transitions-are-local-by-default","content":"Transitions are now local by default to prevent confusion around page navigations. \"local\" means that a transition will not play if it's within a nested control flow block (each/if/await/key) and not the direct parent block but a block above it is created/destroyed. In the following example, the slide intro animation will only play when success goes from false to true, but it will not play when show goes from false to true:{#if show}\n\t...\n\t{#if success}\n\t\t<p in:slide>Success</p>\n\t{/each}\n{/if}To make transitions global, add the |global modifier — then they will play when any control flow block above is created/destroyed. The migration script will do this automatically for you. (#6686)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Default slot bindings"],"href":"/docs/svelte/v4-migration-guide#Default-slot-bindings","content":"Default slot bindings are no longer exposed to named slots and vice versa:<script>\n\timport Nested from './Nested.svelte';\n</script>\n\n<Nested let:count>\n\t<p>\n\t\tcount in default slot — is available: {count}\n\t</p>\n\t<p slot=\"bar\">\n\t\tcount in bar slot — is not available: {count}\n\t</p>\n</Nested>This makes slot bindings more consistent as the behavior is undefined when for example the default slot is from a list and the named slot is not. (#6049)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Preprocessors"],"href":"/docs/svelte/v4-migration-guide#Preprocessors","content":"The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style. \nimport { preprocess } from 'svelte/compiler';\n\nconst { code } = await preprocess(\n\tsource,\n\t[\n\t\t{\n\t\t\tmarkup: () => {\n\t\t\t\tconsole.log('markup-1');\n\t\t\t},\n\t\t\tscript: () => {\n\t\t\t\tconsole.log('script-1');\n\t\t\t},\n\t\t\tstyle: () => {\n\t\t\t\tconsole.log('style-1');\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tmarkup: () => {\n\t\t\t\tconsole.log('markup-2');\n\t\t\t},\n\t\t\tscript: () => {\n\t\t\t\tconsole.log('script-2');\n\t\t\t},\n\t\t\tstyle: () => {\n\t\t\t\tconsole.log('style-2');\n\t\t\t}\n\t\t}\n\t],\n\t{\n\t\tfilename: 'App.svelte'\n\t}\n);\n\n// Svelte 3 logs:\n// markup-1\n// markup-2\n// script-1\n// script-2\n// style-1\n// style-2\n\n// Svelte 4 logs:\n// markup-1\n// script-1\n// style-1\n// markup-2\n// script-2\n// style-2This could affect you for example if you are using MDsveX - in which case you should make sure it comes before any script or style preprocessor. \npreprocess: [\n---\tvitePreprocess(),\n\tmdsvex(mdsvexConfig)---\n+++\tmdsvex(mdsvexConfig),\n\tvitePreprocess()+++\n]Each preprocessor must also have a name. (#8618)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","New eslint package"],"href":"/docs/svelte/v4-migration-guide#New-eslint-package","content":"eslint-plugin-svelte3 is deprecated. It may still work with Svelte 4 but we make no guarantees about that. We recommend switching to our new package eslint-plugin-svelte. See this Github post for an instruction how to migrate. Alternatively, you can create a new project using npm create svelte@latest, select the eslint (and possibly TypeScript) option and then copy over the related files into your existing project.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 4 migration guide","Other breaking changes"],"href":"/docs/svelte/v4-migration-guide#Other-breaking-changes","content":"the `inert` attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction. ([#8628](https://github.com/sveltejs/svelte/pull/8628))\nthe runtime now uses `classList.toggle(name, boolean)` which may not work in very old browsers. Consider using a [polyfill](https://github.com/eligrey/classList.js) if you need to support these browsers. ([#8629](https://github.com/sveltejs/svelte/issues/8629))\nthe runtime now uses the `CustomEvent` constructor which may not work in very old browsers. Consider using a [polyfill](https://github.com/theftprevention/event-constructor-polyfill/tree/master) if you need to support these browsers. ([#8775](https://github.com/sveltejs/svelte/pull/8775))\npeople implementing their own stores from scratch using the `StartStopNotifier` interface (which is passed to the create function of `writable` etc) from `svelte/store` now need to pass an update function in addition to the set function. This has no effect on people using stores or creating stores using the existing Svelte stores. ([#6750](https://github.com/sveltejs/svelte/issues/6750))\n`derived` will now throw an error on falsy values instead of stores passed to it. ([#7947](https://github.com/sveltejs/svelte/issues/7947))\ntype definitions for `svelte/internal` were removed to further discourage usage of those internal methods which are not public API. Most of these will likely change for Svelte 5\nRemoval of DOM nodes is now batched which slightly changes its order, which might affect the order of events fired if you're using a `MutationObserver` on these elements ([#8763](https://github.com/sveltejs/svelte/pull/8763))\nif you enhanced the global typings through the `svelte.JSX` namespace before, you need to migrate this to use the `svelteHTML` namespace. Similarly if you used the `svelte.JSX` namespace to use type definitions from it, you need to migrate those to use the types from `svelte/elements` instead. You can find more information about what to do [here](https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#im-getting-deprecation-warnings-for-sveltejsx--i-want-to-migrate-to-the-new-typings)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide"],"href":"/docs/svelte/v5-migration-guide","content":"Version 5 comes with an overhauled syntax and reactivity system. While it may look different at first, you'll soon notice many similarities. This guide goes over the changes in detail and shows you how to upgrade. Along with it, we also provide information on why we did these changes.You don't have to migrate to the new syntax right away — Svelte 5 still supports the old Svelte 4 syntax, and you can mix and match components using the new syntax with components using the old and vice versa. We expect many people to be able to upgrade with only a few lines of code changed initially. There's also a migration script that helps you with many of these steps automatically.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Reactivity syntax changes"],"href":"/docs/svelte/v5-migration-guide#Reactivity-syntax-changes","content":"At the heart of Svelte 5 is the new runes API. Runes are basically compiler instructions that inform Svelte about reactivity. Syntactically, runes are functions starting with a dollar-sign.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Reactivity syntax changes","let → $state"],"href":"/docs/svelte/v5-migration-guide#Reactivity-syntax-changes-let-$state","content":"In Svelte 4, a let declaration at the top level of a component was implicitly reactive. In Svelte 5, things are more explicit: a variable is reactive when created using the $state rune. Let's migrate the counter to runes mode by wrapping the counter in $state:<script>\n\tlet count = +++$state(0)+++;\n</script>Nothing else changes. count is still the number itself, and you read and write directly to it, without a wrapper like .value or getCount().[!DETAILS] Why we did this\n`let` being implicitly reactive at the top level worked great, but it meant that reactivity was constrained — a `let` declaration anywhere else was not reactive. This forced you to resort to using stores when refactoring code out of the top level of components for reuse. This meant you had to learn an entirely separate reactivity model, and the result often wasn't as nice to work with. Because reactivity is more explicit in Svelte 5, you can keep using the same API outside the top level of components. Head to [the tutorial](/tutorial) to learn more.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Reactivity syntax changes","$: → $derived/$effect"],"href":"/docs/svelte/v5-migration-guide#Reactivity-syntax-changes-$:-$derived-$effect","content":"In Svelte 4, a $: statement at the top level of a component could be used to declare a derivation, i.e. state that is entirely defined through a computation of other state. In Svelte 5, this is achieved using the $derived rune:<script>\n\tlet count = $state(0);\n\t---$:--- +++const+++ double = +++$derived(count * 2)+++;\n</script>As with $state, nothing else changes. double is still the number itself, and you read it directly, without a wrapper like .value or getDouble().A $: statement could also be used to create side effects. In Svelte 5, this is achieved using the $effect rune:<script>\n\tlet count = $state(0);\n\n\t---$:---+++$effect(() =>+++ {\n\t\tif (count > 5) {\n\t\t\talert('Count is too high!');\n\t\t}\n\t}+++);+++\n</script>Note that when `$effect` runs is different than when $: runs.[!DETAILS] Why we did this\n`$:` was a great shorthand and easy to get started with: you could slap a `$:` in front of most code and it would somehow work. This intuitiveness was also its drawback the more complicated your code became, because it wasn't as easy to reason about. Was the intent of the code to create a derivation, or a side effect? With `$derived` and `$effect`, you have a bit more up-front decision making to do (spoiler alert: 90% of the time you want `$derived`), but future-you and other developers on your team will have an easier time.\n\nThere were also gotchas that were hard to spot:\n\n- `$:` only updated directly before rendering, which meant you could read stale values in-between rerenders\n- `$:` only ran once per tick, which meant that statements may run less often than you think\n- `$:` dependencies were determined through static analysis of the dependencies. This worked in most cases, but could break in subtle ways during a refactoring where dependencies would be for example moved into a function and no longer be visible as a result\n- `$:` statements were also ordered by using static analysis of the dependencies. In some cases there could be ties and the ordering would be wrong as a result, needing manual interventions. Ordering could also break while refactoring code and some dependencies no longer being visible as a result.\n\nLastly, it wasn't TypeScript-friendly (our editor tooling had to jump through some hoops to make it valid for TypeScript), which was a blocker for making Svelte's reactivity model truly universal.\n\n`$derived` and `$effect` fix all of these by\n\n- always returning the latest value\n- running as often as needed to be stable\n- determining the dependencies at runtime, and therefore being immune to refactorings\n- executing dependencies as needed and therefore being immune to ordering problems\n- being TypeScript-friendly","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Reactivity syntax changes","export let → $props"],"href":"/docs/svelte/v5-migration-guide#Reactivity-syntax-changes-export-let-$props","content":"In Svelte 4, properties of a component were declared using export let. Each property was one declaration. In Svelte 5, all properties are declared through the $props rune, through destructuring:<script>\n\t---export let optional = 'unset';---\n\t---export let required;---\n\t+++let { optional = 'unset', required } = $props();+++\n</script>There are multiple cases where declaring properties becomes less straightforward than having a few export let declarations:you want to rename the property, for example because the name is a reserved identifier (e.g. `class`)\nyou don't know which other properties to expect in advance\nyou want to forward every property to another componentAll these cases need special syntax in Svelte 4:renaming: `export { klass as class}`\nother properties: `$$restProps`\nall properties `$$props`In Svelte 5, the $props rune makes this straightforward without any additional Svelte-specific syntax:renaming: use property renaming `let { class: klass } = $props();`\nother properties: use spreading `let { foo, bar, ...rest } = $props();`\nall properties: don't destructure `let props = $props();`<script>\n\t---let klass = '';---\n\t---export { klass as class};---\n\t+++let { class: klass, ...rest } = $props();+++\n</script>\n<button class={klass} {...---$$restProps---+++rest+++}>click me</button>[!DETAILS] Why we did this\n`export let` was one of the more controversial API decisions, and there was a lot of debate about whether you should think about a property being `export`ed or `import`ed. `$props` doesn't have this trait. It's also in line with the other runes, and the general thinking reduces to \"everything special to reactivity in Svelte is a rune\".\n\nThere were also a lot of limitations around `export let`, which required additional API, as shown above. `$props` unite this in one syntactical concept that leans heavily on regular JavaScript destructuring syntax.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Event changes"],"href":"/docs/svelte/v5-migration-guide#Event-changes","content":"Event handlers have been given a facelift in Svelte 5. Whereas in Svelte 4 we use the on: directive to attach an event listener to an element, in Svelte 5 they are properties like any other (in other words — remove the colon):<script>\n\tlet count = $state(0);\n</script>\n\n<button on---:---click={() => count++}>\n\tclicks: {count}\n</button>Since they're just properties, you can use the normal shorthand syntax...<script>\n\tlet count = $state(0);\n\n\tfunction onclick() {\n\t\tcount++;\n\t}\n</script>\n\n<button {onclick}>\n\tclicks: {count}\n</button>...though when using a named event handler function it's usually better to use a more descriptive name.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Event changes","Component events"],"href":"/docs/svelte/v5-migration-guide#Event-changes-Component-events","content":"In Svelte 4, components could emit events by creating a dispatcher with createEventDispatcher.This function is deprecated in Svelte 5. Instead, components should accept callback props — which means you then pass functions as properties to these components:<!--- file: App.svelte --->\n<script>\n\timport Pump from './Pump.svelte';\n\n\tlet size = $state(15);\n\tlet burst = $state(false);\n\n\tfunction reset() {\n\t\tsize = 15;\n\t\tburst = false;\n\t}\n</script>\n\n<Pump\n\t---on:---inflate={(power) => {\n\t\tsize += power---.detail---;\n\t\tif (size > 75) burst = true;\n\t}}\n\t---on:---deflate={(power) => {\n\t\tif (size > 0) size -= power---.detail---;\n\t}}\n/>\n\n{#if burst}\n\t<button onclick={reset}>new balloon</button>\n\t<span class=\"boom\">💥</span>\n{:else}\n\t<span class=\"balloon\" style=\"scale: {0.01 * size}\">\n\t\t🎈\n\t</span>\n{/if}<!--- file: Pump.svelte --->\n<script>\n\t---import { createEventDispatcher } from 'svelte';---\n\t---const dispatch = createEventDispatcher();---\n\n\t+++let { inflate, deflate } = $props();+++\n\tlet power = $state(5);\n</script>\n\n<button onclick={() => ---dispatch('inflate', power)---+++inflate(power)+++}>\n\tinflate\n</button>\n<button onclick={() => ---dispatch('deflate', power)---+++deflate(power)+++}>\n\tdeflate\n</button>\n<button onclick={() => power--}>-</button>\nPump power: {power}\n<button onclick={() => power++}>+</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Event changes","Bubbling events"],"href":"/docs/svelte/v5-migration-guide#Event-changes-Bubbling-events","content":"Instead of doing <button on:click> to 'forward' the event from the element to the component, the component should accept an onclick callback prop:<script>\n\t+++let { onclick } = $props();+++\n</script>\n\n<button ---on:click--- +++{onclick}+++>\n\tclick me\n</button>Note that this also means you can 'spread' event handlers onto the element along with other props instead of tediously forwarding each event separately:<script>\n\tlet props = $props();\n</script>\n\n<button ---{...$$props} on:click on:keydown on:all_the_other_stuff--- +++{...props}+++>\n\tclick me\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Event changes","Event modifiers"],"href":"/docs/svelte/v5-migration-guide#Event-changes-Event-modifiers","content":"In Svelte 4, you can add event modifiers to handlers:<button on:click|once|preventDefault={handler}>...</button>Modifiers are specific to on: and so do not work with modern event handlers. Adding things like event.preventDefault() inside the handler itself is preferable, since all the logic lives in one place rather than being split between handler and modifiers.Since event handlers are just functions, you can create your own wrappers as necessary:<script>\n\tfunction once(fn) {\n\t\treturn function (event) {\n\t\t\tif (fn) fn.call(this, event);\n\t\t\tfn = null;\n\t\t};\n\t}\n\n\tfunction preventDefault(fn) {\n\t\treturn function (event) {\n\t\t\tevent.preventDefault();\n\t\t\tfn.call(this, event);\n\t\t};\n\t}\n</script>\n\n<button onclick={once(preventDefault(handler))}>...</button>There are three modifiers — capture, passive and nonpassive — that can't be expressed as wrapper functions, since they need to be applied when the event handler is bound rather than when it runs.For capture, we add the modifier to the event name:<button onclickcapture={...}>...</button>Changing the `passive` option of an event handler, meanwhile, is not something to be done lightly. If you have a use case for it — and you probably don't! — then you will need to use an action to apply the event handler yourself.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Event changes","Multiple event handlers"],"href":"/docs/svelte/v5-migration-guide#Event-changes-Multiple-event-handlers","content":"In Svelte 4, this is possible:<button on:click={one} on:click={two}>...</button>Duplicate attributes/properties on elements — which now includes event handlers — are not allowed. Instead, do this:<button\n\tonclick={(e) => {\n\t\tone(e);\n\t\ttwo(e);\n\t}}\n>\n\t...\n</button>When spreading props, local event handlers must go after the spread, or they risk being overwritten:<button\n\t{...props}\n\tonclick={(e) => {\n\t\tdoStuff(e);\n\t\tprops.onclick?.(e);\n\t}}\n>\n\t...\n</button>[!DETAILS] Why we did this\n`createEventDispatcher` was always a bit boilerplate-y:\n\n- import the function\n- call the function to get a dispatch function\n- call said dispatch function with a string and possibly a payload\n- retrieve said payload on the other end through a `.detail` property, because the event itself was always a `CustomEvent`\n\nIt was always possible to use component callback props, but because you had to listen to DOM events using `on:`, it made sense to use `createEventDispatcher` for component events due to syntactical consistency. Now that we have event attributes (`onclick`), it's the other way around: Callback props are now the more sensible thing to do.\n\nThe removal of event modifiers is arguably one of the changes that seems like a step back for those who've liked the shorthand syntax of event modifiers. Given that they are not used that frequently, we traded a smaller surface area for more explicitness. Modifiers also were inconsistent, because most of them were only usable on DOM elements.\n\nMultiple listeners for the same event are also no longer possible, but it was something of an anti-pattern anyway, since it impedes readability: if there are many attributes, it becomes harder to spot that there are two handlers unless they are right next to each other. It also implies that the two handlers are independent, when in fact something like `event.stopImmediatePropagation()` inside `one` would prevent `two` from being called.\n\nBy deprecating `createEventDispatcher` and the `on:` directive in favour of callback props and normal element properties, we:\n\n- reduce Svelte's learning curve\n- remove boilerplate, particularly around `createEventDispatcher`\n- remove the overhead of creating `CustomEvent` objects for events that may not even have listeners\n- add the ability to spread event handlers\n- add the ability to know which event handlers were provided to a component\n- add the ability to express whether a given event handler is required or optional\n- increase type safety (previously, it was effectively impossible for Svelte to guarantee that a component didn't emit a particular event)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Snippets instead of slots"],"href":"/docs/svelte/v5-migration-guide#Snippets-instead-of-slots","content":"In Svelte 4, content can be passed to components using slots. Svelte 5 replaces them with snippets, which are more powerful and flexible, and so slots are deprecated in Svelte 5.They continue to work, however, and you can pass snippets to a component that uses slots:<!--- file: Child.svelte --->\n<slot />\n<hr />\n<slot name=\"foo\" message=\"hello\" /><!--- file: Parent.svelte --->\n<script>\n\timport Child from './Child.svelte';\n</script>\n\n<Child>\n\tdefault child content\n\n\t{#snippet foo({ message })}\n\t\tmessage from child: {message}\n\t{/snippet}\n</Child>(The reverse is not true — you cannot pass slotted content to a component that uses `{@render ...}` tags.)When using custom elements, you should still use <slot /> like before. In a future version, when Svelte removes its internal version of slots, it will leave those slots as-is, i.e. output a regular DOM tag instead of transforming it.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Snippets instead of slots","Default content"],"href":"/docs/svelte/v5-migration-guide#Snippets-instead-of-slots-Default-content","content":"In Svelte 4, the easiest way to pass a piece of UI to the child was using a <slot />. In Svelte 5, this is done using the children prop instead, which is then shown with {@render children()}:<script>\n\t+++let { children } = $props();+++\n</script>\n\n---<slot />---\n+++{@render children?.()}+++","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Snippets instead of slots","Multiple content placeholders"],"href":"/docs/svelte/v5-migration-guide#Snippets-instead-of-slots-Multiple-content-placeholders","content":"If you wanted multiple UI placeholders, you had to use named slots. In Svelte 5, use props instead, name them however you like and {@render ...} them:<script>\n\t+++let { header, main, footer } = $props();+++\n</script>\n\n<header>\n\t---<slot name=\"header\" />---\n\t+++{@render header()}+++\n</header>\n\n<main>\n\t---<slot name=\"main\" />---\n\t+++{@render main()}+++\n</main>\n\n<footer>\n\t---<slot name=\"footer\" />---\n\t+++{@render footer()}+++\n</footer>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Snippets instead of slots","Passing data back up"],"href":"/docs/svelte/v5-migration-guide#Snippets-instead-of-slots-Passing-data-back-up","content":"In Svelte 4, you would pass data to a <slot /> and then retrieve it with let: in the parent component. In Svelte 5, snippets take on that responsibility:<!--- file: App.svelte --->\n<script>\n\timport List from './List.svelte';\n</script>\n\n<List items={['one', 'two', 'three']} ---let:item--->\n\t+++{#snippet item(text)}+++\n\t\t<span>{text}</span>\n\t+++{/snippet}+++\n\t---<span slot=\"empty\">No items yet</span>---\n\t+++{#snippet empty()}\n\t\t<span>No items yet</span>\n\t{/snippet}+++\n</List><!--- file: List.svelte --->\n<script>\n\tlet { items, +++item, empty+++ } = $props();\n</script>\n\n{#if items.length}\n\t<ul>\n\t\t{#each items as entry}\n\t\t\t<li>\n\t\t\t\t---<slot item={entry} />---\n\t\t\t\t+++{@render item(entry)}+++\n\t\t\t</li>\n\t\t{/each}\n\t</ul>\n{:else}\n\t---<slot name=\"empty\" />---\n\t+++{@render empty?.()}+++\n{/if}[!DETAILS] Why we did this\nSlots were easy to get started with, but the more advanced the use case became, the more involved and confusing the syntax became:\n\n- the `let:` syntax was confusing to many people as it _creates_ a variable whereas all other `:` directives _receive_ a variable\n- the scope of a variable declared with `let:` wasn't clear. In the example above, it may look like you can use the `item` slot prop in the `empty` slot, but that's not true\n- named slots had to be applied to an element using the `slot` attribute. Sometimes you didn't want to create an element, so we had to add the `<svelte:fragment>` API\n- named slots could also be applied to a component, which changed the semantics of where `let:` directives are available (even today us maintainers often don't know which way around it works)\n\nSnippets solve all of these problems by being much more readable and clear. At the same time they're more powerful as they allow you to define sections of UI that you can render _anywhere_, not just passing them as props to a component.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Migration script"],"href":"/docs/svelte/v5-migration-guide#Migration-script","content":"By now you should have a pretty good understanding of the before/after and how the old syntax relates to the new syntax. It probably also became clear that a lot of these migrations are rather technical and repetitive — something you don't want to do by hand.We thought the same, which is why we provide a migration script to do most of the migration automatically. You can upgrade your project by using npx sv migrate svelte-5. This will do the following things:bump core dependencies in your `package.json`\nmigrate to runes (`let` → `$state` etc)\nmigrate to event attributes for DOM elements (`on:click` → `onclick`)\nmigrate slot creations to render tags (`<slot />` → `{@render children()}`)\nmigrate slot usages to snippets (`<div slot=\"x\">...</div>` → `{#snippet x()}<div>...</div>{/snippet}`)\nmigrate obvious component creations (`new Component(...)` → `mount(Component, ...)`)You can also migrate a single component in VS Code through the Migrate Component to Svelte 5 Syntax command, or in our Playground through the Migrate button.Not everything can be migrated automatically, and some migrations need manual cleanup afterwards. The following sections describe these in more detail.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Migration script","run"],"href":"/docs/svelte/v5-migration-guide#Migration-script-run","content":"You may see that the migration script converts some of your $: statements to a run function which is imported from svelte/legacy. This happens if the migration script couldn't reliably migrate the statement to a $derived and concluded this is a side effect instead. In some cases this may be wrong and it's best to change this to use a $derived instead. In other cases it may be right, but since $: statements also ran on the server but $effect does not, it isn't safe to transform it as such. Instead, run is used as a stopgap solution. run mimics most of the characteristics of $:, in that it runs on the server once, and runs as $effect.pre on the client ($effect.pre runs before changes are applied to the DOM; most likely you want to use $effect instead).<script>\n\t---import { run } from 'svelte/legacy';---\n\t---run(() => {---\n\t+++$effect(() => {+++\n\t\t// some side effect code\n\t})\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Migration script","Event modifiers"],"href":"/docs/svelte/v5-migration-guide#Migration-script-Event-modifiers","content":"Event modifiers are not applicable to event attributes (e.g. you can't do onclick|preventDefault={...}). Therefore, when migrating event directives to event attributes, we need a function-replacement for these modifiers. These are imported from svelte/legacy, and should be migrated away from in favor of e.g. just using event.preventDefault().<script>\n\t---import { preventDefault } from 'svelte/legacy';---\n</script>\n\n<button\n\tonclick={---preventDefault---((event) => {\n\t\t+++event.preventDefault();+++\n\t\t// ...\n\t})}\n>\n\tclick me\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Migration script","Things that are not automigrated"],"href":"/docs/svelte/v5-migration-guide#Migration-script-Things-that-are-not-automigrated","content":"The migration script does not convert createEventDispatcher. You need to adjust those parts manually. It doesn't do it because it's too risky because it could result in breakage for users of the component, which the migration script cannot find out.The migration script does not convert beforeUpdate/afterUpdate. It doesn't do it because it's impossible to determine the actual intent of the code. As a rule of thumb you can often go with a combination of $effect.pre (runs at the same time as beforeUpdate did) and tick (imported from svelte, allows you to wait until changes are applied to the DOM and then do some work).","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Components are no longer classes"],"href":"/docs/svelte/v5-migration-guide#Components-are-no-longer-classes","content":"In Svelte 3 and 4, components are classes. In Svelte 5 they are functions and should be instantiated differently. If you need to manually instantiate components, you should use mount or hydrate (imported from svelte) instead. If you see this error using SvelteKit, try updating to the latest version of SvelteKit first, which adds support for Svelte 5. If you're using Svelte without SvelteKit, you'll likely have a main.js file (or similar) which you need to adjust:+++import { mount } from 'svelte';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\") });---\n+++const app = mount(App, { target: document.getElementById(\"app\") });+++\n\nexport default app;mount and hydrate have the exact same API. The difference is that hydrate will pick up the Svelte's server-rendered HTML inside its target and hydrate it. Both return an object with the exports of the component and potentially property accessors (if compiled with accessors: true). They do not come with the $on, $set and $destroy methods you may know from the class component API. These are its replacements:For $on, instead of listening to events, pass them via the events property on the options argument.+++import { mount } from 'svelte';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\") });\napp.$on('event', callback);---\n+++const app = mount(App, { target: document.getElementById(\"app\"), events: { event: callback } });+++[!NOTE] Note that using `events` is discouraged — instead, [use callbacks](#Event-changes)For $set, use $state instead to create a reactive property object and manipulate it. If you're doing this inside a .js or .ts file, adjust the ending to include .svelte, i.e. .svelte.js or .svelte.ts.+++import { mount } from 'svelte';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\"), props: { foo: 'bar' } });\napp.$set({ foo: 'baz' });---\n+++const props = $state({ foo: 'bar' });\nconst app = mount(App, { target: document.getElementById(\"app\"), props });\nprops.foo = 'baz';+++For $destroy, use unmount instead.+++import { mount, unmount } from 'svelte';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\"), props: { foo: 'bar' } });\napp.$destroy();---\n+++const app = mount(App, { target: document.getElementById(\"app\") });\nunmount(app);+++As a stop-gap-solution, you can also use createClassComponent or asClassComponent (imported from svelte/legacy) instead to keep the same API known from Svelte 4 after instantiating.+++import { createClassComponent } from 'svelte/legacy';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\") });---\n+++const app = createClassComponent({ component: App, target: document.getElementById(\"app\") });+++\n\nexport default app;If this component is not under your control, you can use the compatibility.componentApi compiler option for auto-applied backwards compatibility, which means code using new Component(...) keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add $set and $on methods for all component instances you get through bind:this./// svelte.config.js\nexport default {\n\tcompilerOptions: {\n\t\tcompatibility: {\n\t\t\tcomponentApi: 4\n\t\t}\n\t}\n};Note that mount and hydrate are not synchronous, so things like onMount won't have been called by the time the function returns and the pending block of promises will not have been rendered yet (because #await waits a microtask to wait for a potentially immediately-resolved promise). If you need that guarantee, call flushSync (import from 'svelte') after calling mount/hydrate.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Components are no longer classes","Server API changes"],"href":"/docs/svelte/v5-migration-guide#Components-are-no-longer-classes-Server-API-changes","content":"Similarly, components no longer have a render method when compiled for server-side rendering. Instead, pass the function to render from svelte/server:+++import { render } from 'svelte/server';+++\nimport App from './App.svelte';\n\n---const { html, head } = App.render({ props: { message: 'hello' }});---\n+++const { html, head } = render(App, { props: { message: 'hello' }});+++In Svelte 4, rendering a component to a string also returned the CSS of all components. In Svelte 5, this is no longer the case by default because most of the time you're using a tooling chain that takes care of it in other ways (like SvelteKit). If you need CSS to be returned from render, you can set the css compiler option to 'injected' and it will add <style> elements to the head.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Components are no longer classes","Component typing changes"],"href":"/docs/svelte/v5-migration-guide#Components-are-no-longer-classes-Component-typing-changes","content":"The change from classes towards functions is also reflected in the typings: SvelteComponent, the base class from Svelte 4, is deprecated in favour of the new Component type which defines the function shape of a Svelte component. To manually define a component shape in a d.ts file:import type { Component } from 'svelte';\nexport declare const MyComponent: Component<{\n\tfoo: string;\n}>;To declare that a component of a certain type is required:import { ComponentA, ComponentB } from 'component-library';\n---import type { SvelteComponent } from 'svelte';---\n+++import type { Component } from 'svelte';+++\n\n---let C: typeof SvelteComponent<{ foo: string }> = $state(---\n+++let C: Component<{ foo: string }> = $state(+++\n\tMath.random() ? ComponentA : ComponentB\n);The two utility types ComponentEvents and ComponentType are also deprecated. ComponentEvents is obsolete because events are defined as callback props now, and ComponentType is obsolete because the new Component type is the component type already (i.e. ComponentType<SvelteComponent<{ prop: string }>> is equivalent to Component<{ prop: string }>).","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Components are no longer classes","bind:this changes"],"href":"/docs/svelte/v5-migration-guide#Components-are-no-longer-classes-bind:this-changes","content":"Because components are no longer classes, using bind:this no longer returns a class instance with $set, $on and $destroy methods on it. It only returns the instance exports (export function/const) and, if you're using the accessors option, a getter/setter-pair for each property.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","`<svelte:component>` is no longer necessary"],"href":"/docs/svelte/v5-migration-guide#svelte:component-is-no-longer-necessary","content":"In Svelte 4, components are static — if you render <Thing>, and the value of Thing changes, nothing happens. To make it dynamic you had to use <svelte:component>.This is no longer true in Svelte 5:<script>\n\timport A from './A.svelte';\n\timport B from './B.svelte';\n\n\tlet Thing = $state();\n</script>\n\n<select bind:value={Thing}>\n\t<option value={A}>A</option>\n\t<option value={B}>B</option>\n</select>\n\n<!-- these are equivalent -->\n<Thing />\n<svelte:component this={Thing} />While migrating, keep in mind that your component's name should be capitalized (Thing) to distinguish it from elements, unless using dot notation.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","`<svelte:component>` is no longer necessary","Dot notation indicates a component"],"href":"/docs/svelte/v5-migration-guide#svelte:component-is-no-longer-necessary-Dot-notation-indicates-a-component","content":"In Svelte 4, <foo.bar> would create an element with a tag name of \"foo.bar\". In Svelte 5, foo.bar is treated as a component instead. This is particularly useful inside each blocks:{#each items as item}\n\t<item.component {...item.props} />\n{/each}","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Whitespace handling changed"],"href":"/docs/svelte/v5-migration-guide#Whitespace-handling-changed","content":"Previously, Svelte employed a very complicated algorithm to determine if whitespace should be kept or not. Svelte 5 simplifies this which makes it easier to reason about as a developer. The rules are:Whitespace between nodes is collapsed to one whitespace\nWhitespace at the start and end of a tag is removed completely\n\nThis new behavior is slightly different from native HTML rendering. For example, `<p>foo<span> - bar</span></p>` will render:\n\n- `foo - bar` in HTML\n- `foo- bar` in Svelte 5\n\nYou can reintroduce the missing space by moving it outside the `<span>`...\n\n```svelte\n<p>foo <span>- bar</span></p>\n```\n\n...or, if necessary for styling reasons, including it as an expression:\n\n```svelte\n<p>foo<span>{' '}- bar</span></p>\n```\n\nCertain exceptions apply such as keeping whitespace inside `pre` tagsAs before, you can disable whitespace trimming by setting the preserveWhitespace option in your compiler settings or on a per-component basis in <svelte:options>.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Modern browser required"],"href":"/docs/svelte/v5-migration-guide#Modern-browser-required","content":"Svelte 5 requires a modern browser (in other words, not Internet Explorer) for various reasons:it uses [`Proxies`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)\nelements with `clientWidth`/`clientHeight`/`offsetWidth`/`offsetHeight` bindings use a [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) rather than a convoluted `<iframe>` hack\n`<input type=\"range\" bind:value={...} />` only uses an `input` event listener, rather than also listening for `change` events as a fallbackThe legacy compiler option, which generated bulkier but IE-friendly code, no longer exists.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Changes to compiler options"],"href":"/docs/svelte/v5-migration-guide#Changes-to-compiler-options","content":"The `false`/`true` (already deprecated previously) and the `\"none\"` values were removed as valid values from the `css` option\nThe `legacy` option was repurposed\nThe `hydratable` option has been removed. Svelte components are always hydratable now\nThe `enableSourcemap` option has been removed. Source maps are always generated now, tooling can choose to ignore it\nThe `tag` option was removed. Use `<svelte:options customElement=\"tag-name\" />` inside the component instead\nThe `loopGuardTimeout`, `format`, `sveltePath`, `errorMode` and `varsReport` options were removed","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","The `children` prop is reserved"],"href":"/docs/svelte/v5-migration-guide#The-children-prop-is-reserved","content":"Content inside component tags becomes a snippet prop called children. You cannot have a separate prop by that name.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode","content":"Some breaking changes only apply once your component is in runes mode.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","Bindings to component exports are not allowed"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Bindings-to-component-exports-are-not-allowed","content":"Exports from runes mode components cannot be bound to directly. For example, having export const foo = ... in component A and then doing <A bind:foo /> causes an error. Use bind:this instead — <A bind:this={a} /> — and access the export as a.foo. This change makes things easier to reason about, as it enforces a clear separation between props and exports.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","Bindings need to be explicitly defined using `$bindable()`"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Bindings-need-to-be-explicitly-defined-using-$bindable()","content":"In Svelte 4 syntax, every property (declared via export let) is bindable, meaning you can bind: to it. In runes mode, properties are not bindable by default: you need to denote bindable props with the $bindable rune.If a bindable property has a default value (e.g. let { foo = $bindable('bar') } = $props();), you need to pass a non-undefined value to that property if you're binding to it. This prevents ambiguous behavior — the parent and child must have the same value — and results in better performance (in Svelte 4, the default value was reflected back to the parent, resulting in wasteful additional render cycles).","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","`accessors` option is ignored"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-accessors-option-is-ignored","content":"Setting the accessors option to true makes properties of a component directly accessible on the component instance.<svelte:options accessors={true} />\n\n<script>\n\t// available via componentInstance.name\n\texport let name;\n</script>In runes mode, properties are never accessible on the component instance. You can use component exports instead if you need to expose them.<script>\n\tlet { name } = $props();\n\t// available via componentInstance.getName()\n\texport const getName = () => name;\n</script>Alternatively, if the place where they are instantiated is under your control, you can also make use of runes inside .js/.ts files by adjusting their ending to include .svelte, i.e. .svelte.js or .svelte.ts, and then use $state:+++import { mount } from 'svelte';+++\nimport App from './App.svelte'\n\n---const app = new App({ target: document.getElementById(\"app\"), props: { foo: 'bar' } });\napp.foo = 'baz'---\n+++const props = $state({ foo: 'bar' });\nconst app = mount(App, { target: document.getElementById(\"app\"), props });\nprops.foo = 'baz';+++","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","`immutable` option is ignored"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-immutable-option-is-ignored","content":"Setting the immutable option has no effect in runes mode. This concept is replaced by how $state and its variations work.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","Classes are no longer \"auto-reactive\""],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Classes-are-no-longer-auto-reactive","content":"In Svelte 4, doing the following triggered reactivity:<script>\n\tlet foo = new Foo();\n</script>\n\n<button on:click={() => (foo.value = 1)}>{foo.value}</button\n>This is because the Svelte compiler treated the assignment to foo.value as an instruction to update anything that referenced foo. In Svelte 5, reactivity is determined at runtime rather than compile time, so you should define value as a reactive $state field on the Foo class. Wrapping new Foo() with $state(...) will have no effect — only vanilla objects and arrays are made deeply reactive.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","Touch events are passive"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Touch-events-are-passive","content":"When using ontouchstart and ontouchmove event attributes, the handlers are passive to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls event.preventDefault().In the very rare cases that you need to prevent these event defaults, you should use `on` instead (for example inside an action).","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","Attribute/prop syntax is stricter"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Attribute-prop-syntax-is-stricter","content":"In Svelte 4, complex attribute values needn't be quoted:\n<Component prop=this{is}valid />This is a footgun. In runes mode, if you want to concatenate stuff you must wrap the value in quotes:<Component prop=\"this{is}valid\" />Note that Svelte 5 will also warn if you have a single expression wrapped in quotes, like answer=\"{42}\" — in Svelte 6, that will cause the value to be converted to a string, rather than passed as a number.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Breaking changes in runes mode","HTML structure is stricter"],"href":"/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-HTML-structure-is-stricter","content":"In Svelte 4, you were allowed to write HTML code that would be repaired by the browser when server-side rendering it. For example you could write this...<table>\n\t<tr>\n\t\t<td>hi</td>\n\t</tr>\n</table>... and the browser would auto-insert a <tbody> element:<table>\n\t<tbody>\n\t\t<tr>\n\t\t\t<td>hi</td>\n\t\t</tr>\n\t</tbody>\n</table>Svelte 5 is more strict about the HTML structure and will throw a compiler error in cases where the browser would repair the DOM.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Stricter `@const` assignment validation"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Stricter-const-assignment-validation","content":"Assignments to destructured parts of a @const declaration are no longer allowed. It was an oversight that this was ever allowed.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes",":is(...), :has(...), and :where(...) are scoped"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-:is()-:has()-and-:where()-are-scoped","content":"Previously, Svelte did not analyse selectors inside :is(...), :has(...), and :where(...), effectively treating them as global. Svelte 5 analyses them in the context of the current component. Some selectors may now therefore be treated as unused if they were relying on this treatment. To fix this, use :global(...) inside the :is(...)/:has(...)/:where(...) selectors.When using Tailwind's @apply directive, add a :global selector to preserve rules that use Tailwind-generated :is(...) selectors:\nmain +++:global+++ {\n\t@apply bg-blue-100 dark:bg-blue-900;\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","CSS hash position no longer deterministic"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-CSS-hash-position-no-longer-deterministic","content":"Previously Svelte would always insert the CSS hash last. This is no longer guaranteed in Svelte 5. This is only breaking if you have very weird css selectors.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Scoped CSS uses :where(...)"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Scoped-CSS-uses-:where()","content":"To avoid issues caused by unpredictable specificity changes, scoped CSS selectors now use :where(.svelte-xyz123) selector modifiers alongside .svelte-xyz123 (where xyz123 is, as previously, a hash of the <style> contents). You can read more detail here.In the event that you need to support ancient browsers that don't implement :where, you can manually alter the emitted CSS, at the cost of unpredictable specificity changes: \ncss = css.replace(/:where\\((.+?)\\)/, '$1');","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Error/warning codes have been renamed"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Error-warning-codes-have-been-renamed","content":"Error and warning codes have been renamed. Previously they used dashes to separate the words, they now use underscores (e.g. foo-bar becomes foo_bar). Additionally, a handful of codes have been reworded slightly.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Reduced number of namespaces"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Reduced-number-of-namespaces","content":"The number of valid namespaces you can pass to the compiler option namespace has been reduced to html (the default), mathml and svg.The foreign namespace was only useful for Svelte Native, which we're planning to support differently in a 5.x minor.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","beforeUpdate/afterUpdate changes"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-beforeUpdate-afterUpdate-changes","content":"beforeUpdate no longer runs twice on initial render if it modifies a variable referenced in the template.afterUpdate callbacks in a parent component will now run after afterUpdate callbacks in any child components.beforeUpdate/afterUpdate no longer run when the component contains a <slot> and its content is updated.Both functions are disallowed in runes mode — use $effect.pre(...) and $effect(...) instead.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`contenteditable` behavior change"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-contenteditable-behavior-change","content":"If you have a contenteditable node with a corresponding binding and a reactive value inside it (example: <div contenteditable=true bind:textContent>count is {count}</div>), then the value inside the contenteditable will not be updated by updates to count because the binding takes full control over the content immediately and it should only be updated through it.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`oneventname` attributes no longer accept string values"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-oneventname-attributes-no-longer-accept-string-values","content":"In Svelte 4, it was possible to specify event attributes on HTML elements as a string:<button onclick=\"alert('hello')\">...</button>This is not recommended, and is no longer possible in Svelte 5, where properties like onclick replace on:click as the mechanism for adding event handlers.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","null` and undefined` become the empty string"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-null-and-undefined-become-the-empty-string","content":"In Svelte 4, null and undefined were printed as the corresponding string. In 99 out of 100 cases you want this to become the empty string instead, which is also what most other frameworks out there do. Therefore, in Svelte 5, null and undefined become the empty string.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","bind:files` values can only be null`, `undefined` or `FileList`"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-bind:files-values-can-only-be-null-undefined-or-FileList","content":"bind:files is now a two-way binding. As such, when setting a value, it needs to be either falsy (null or undefined) or of type FileList.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Bindings now react to form resets"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Bindings-now-react-to-form-resets","content":"Previously, bindings did not take into account reset event of forms, and therefore values could get out of sync with the DOM. Svelte 5 fixes this by placing a reset listener on the document and invoking bindings where necessary.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`walk` no longer exported"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-walk-no-longer-exported","content":"svelte/compiler reexported walk from estree-walker for convenience. This is no longer true in Svelte 5, import it directly from that package instead in case you need it.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Content inside `svelte:options` is forbidden"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Content-inside-svelte:options-is-forbidden","content":"In Svelte 4 you could have content inside a <svelte:options /> tag. It was ignored, but you could write something in there. In Svelte 5, content inside that tag is a compiler error.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`<slot>` elements in declarative shadow roots are preserved"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-slot-elements-in-declarative-shadow-roots-are-preserved","content":"Svelte 4 replaced the <slot /> tag in all places with its own version of slots. Svelte 5 preserves them in the case they are a child of a <template shadowrootmode=\"...\"> element.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`<svelte:element>` tag must be an expression"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-svelte:element-tag-must-be-an-expression","content":"In Svelte 4, <svelte:element this=\"div\"> is valid code. This makes little sense — you should just do <div>. In the vanishingly rare case that you do need to use a literal value for some reason, you can do this:<svelte:element this=+++{+++\"div\"+++}+++>Note that whereas Svelte 4 would treat <svelte:element this=\"input\"> (for example) identically to <input> for the purposes of determining which bind: directives could be applied, Svelte 5 does not.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`mount` plays transitions by default"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-mount-plays-transitions-by-default","content":"The mount function used to render a component tree plays transitions by default unless the intro option is set to false. This is different from legacy class components which, when manually instantiated, didn't play transitions by default.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`<img src={...}>` and `{@html ...}` hydration mismatches are not repaired"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-img-src-and-html-hydration-mismatches-are-not-repaired","content":"In Svelte 4, if the value of a src attribute or {@html ...} tag differ between server and client (a.k.a. a hydration mismatch), the mismatch is repaired. This is very costly: setting a src attribute (even if it evaluates to the same thing) causes images and iframes to be reloaded, and reinserting a large blob of HTML is slow.Since these mismatches are extremely rare, Svelte 5 assumes that the values are unchanged, but in development will warn you if they are not. To force an update you can do something like this:<script>\n\tlet { markup, src } = $props();\n\n\tif (typeof window !== 'undefined') {\n\t\t// stash the values...\n\t\tconst initial = { markup, src };\n\n\t\t// unset them...\n\t\tmarkup = src = undefined;\n\n\t\t$effect(() => {\n\t\t\t// ...and reset after we've mounted\n\t\t\tmarkup = initial.markup;\n\t\t\tsrc = initial.src;\n\t\t});\n\t}\n</script>\n\n{@html markup}\n<img {src} />","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","Hydration works differently"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-Hydration-works-differently","content":"Svelte 5 makes use of comments during server-side rendering which are used for more robust and efficient hydration on the client. You therefore should not remove comments from your HTML output if you intend to hydrate it, and if you manually authored HTML to be hydrated by a Svelte component, you need to adjust that HTML to include said comments at the correct positions.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`onevent` attributes are delegated"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-onevent-attributes-are-delegated","content":"Event attributes replace event directives: Instead of on:click={handler} you write onclick={handler}. For backwards compatibility the on:event syntax is still supported and behaves the same as in Svelte 4. Some of the onevent attributes however are delegated, which means you need to take care to not stop event propagation on those manually, as they then might never reach the listener for this event type at the root.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Svelte 5 migration guide","Other breaking changes","`--style-props` uses a different element"],"href":"/docs/svelte/v5-migration-guide#Other-breaking-changes-style-props-uses-a-different-element","content":"Svelte 5 uses an extra <svelte-css-wrapper> element instead of a <div> to wrap the component when using CSS custom properties.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions"],"href":"/docs/svelte/faq","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","I'm new to Svelte. Where should I start?"],"href":"/docs/svelte/faq#I'm-new-to-Svelte.-Where-should-I-start","content":"We think the best way to get started is playing through the interactive tutorial. Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Where can I get support?"],"href":"/docs/svelte/faq#Where-can-I-get-support","content":"If your question is about certain syntax, the reference docs are a good place to start.Stack Overflow is a popular forum to ask code-level questions or if you’re stuck with a specific error. Read through the existing questions tagged with Svelte or ask your own!There are online forums and chats which are a great place for discussion about best practices, application architecture or just to get to know fellow Svelte users. Our Discord or the Reddit channel are examples of that. If you have an answerable code-level question, Stack Overflow is usually a better fit.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Are there any third-party resources?"],"href":"/docs/svelte/faq#Are-there-any-third-party-resources","content":"Svelte Society maintains a list of books and videos.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","How can I get VS Code to syntax-highlight my .svelte files?"],"href":"/docs/svelte/faq#How-can-I-get-VS-Code-to-syntax-highlight-my-.svelte-files","content":"There is an official VS Code extension for Svelte.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Is there a tool to automatically format my .svelte files?"],"href":"/docs/svelte/faq#Is-there-a-tool-to-automatically-format-my-.svelte-files","content":"You can use prettier with the prettier-plugin-svelte plugin.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","How do I document my components?"],"href":"/docs/svelte/faq#How-do-I-document-my-components","content":"In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.<script>\n\t/** What should we call the user? */\n\texport let name = 'world';\n</script>\n\n<!--\n@component\nHere's some documentation for this component.\nIt will show up on hover.\n\n- You can use markdown here.\n- You can also use code blocks here.\n- Usage:\n  ```svelte\n  <main name=\"Arethra\">\n  ```\n-->\n<main>\n\t<h1>\n\t\tHello, {name}\n\t</h1>\n</main>Note: The @component is necessary in the HTML comment which describes your component.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Does Svelte scale?"],"href":"/docs/svelte/faq#Does-Svelte-scale","content":"There will be a blog post about this eventually, but in the meantime, check out this issue.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Is there a UI component library?"],"href":"/docs/svelte/faq#Is-there-a-UI-component-library","content":"There are several UI component libraries as well as standalone components listed on the packages page.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","How do I test Svelte apps?"],"href":"/docs/svelte/faq#How-do-I-test-Svelte-apps","content":"How your application is structured and where logic is defined will determine the best way to ensure it is properly tested. It is important to note that not all logic belongs within a component — this includes concerns such as data transformation, cross-component state management, and logging, among others. Remember that the Svelte library has its own test suite, so you do not need to write tests to validate implementation details provided by Svelte.A Svelte application will typically have three different types of tests: Unit, Component, and End-to-End (E2E).Unit Tests: Focus on testing business logic in isolation. Often this is validating individual functions and edge cases. By minimizing the surface area of these tests they can be kept lean and fast, and by extracting as much logic as possible from your Svelte components more of your application can be covered using them. When creating a new SvelteKit project, you will be asked whether you would like to setup Vitest for unit testing. There are a number of other test runners that could be used as well.Component Tests: Validating that a Svelte component mounts and interacts as expected throughout its lifecycle requires a tool that provides a Document Object Model (DOM). Components can be compiled (since Svelte is a compiler and not a normal library) and mounted to allow asserting against element structure, listeners, state, and all the other capabilities provided by a Svelte component. Tools for component testing range from an in-memory implementation like jsdom paired with a test runner like Vitest to solutions that leverage an actual browser to provide a visual testing capability such as Playwright or Cypress.End-to-End Tests: To ensure your users are able to interact with your application it is necessary to test it as a whole in a manner as close to production as possible. This is done by writing end-to-end (E2E) tests which load and interact with a deployed version of your application in order to simulate how the user will interact with your application. When creating a new SvelteKit project, you will be asked whether you would like to setup Playwright for end-to-end testing. There are many other E2E test libraries available for use as well.Some resources for getting started with testing:[Svelte docs on testing](/docs/svelte/testing)\n[Setup Vitest using the Svelte CLI](/docs/cli/vitest)\n[Svelte Testing Library](https://testing-library.com/docs/svelte-testing-library/example/)\n[Svelte Component Testing in Cypress](https://docs.cypress.io/guides/component-testing/svelte/overview)\n[Example using uvu test runner with JSDOM](https://github.com/lukeed/uvu/tree/master/examples/svelte)\n[Test Svelte components using Vitest & Playwright](https://davipon.hashnode.dev/test-svelte-component-using-vitest-playwright)\n[Component testing with WebdriverIO](https://webdriver.io/docs/component-testing/svelte)","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Is there a router?"],"href":"/docs/svelte/faq#Is-there-a-router","content":"The official routing library is SvelteKit. SvelteKit provides a filesystem router, server-side rendering (SSR), and hot module reloading (HMR) in one easy-to-use package. It shares similarities with Next.js for React and Nuxt.js for Vue. SvelteKit also supports hash-based routing for client-side applications.However, you can use any router library. A sampling of available routers are highlighted on the packages page.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","How do I write a mobile app with Svelte?"],"href":"/docs/svelte/faq#How-do-I-write-a-mobile-app-with-Svelte","content":"While most mobile apps are written without using JavaScript, if you'd like to leverage your existing Svelte components and knowledge of Svelte when building mobile apps, you can turn a SvelteKit SPA into a mobile app with Tauri or Capacitor. Mobile features like the camera, geolocation, and push notifications are available via plugins for both platforms.Some work has been completed towards custom renderer support in Svelte 5, but this feature is not yet available. The custom rendering API would support additional mobile frameworks like Lynx JS and Svelte Native. Svelte Native was an option available for Svelte 4, but Svelte 5 does not currently support it. Svelte Native lets you write NativeScript apps using Svelte components that contain NativeScript UI components rather than DOM elements, which may be familiar for users coming from React Native.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Can I tell Svelte not to remove my unused styles?"],"href":"/docs/svelte/faq#Can-I-tell-Svelte-not-to-remove-my-unused-styles","content":"No. Svelte removes the styles from the component and warns you about them in order to prevent issues that would otherwise arise.Svelte's component style scoping works by generating a class unique to the given component, adding it to the relevant elements in the component that are under Svelte's control, and then adding it to each of the selectors in that component's styles. When the compiler can't see what elements a style selector applies to, there would be two bad options for keeping it:If it keeps the selector and adds the scoping class to it, the selector will likely not match the expected elements in the component, and they definitely won't if they were created by a child component or `{@html ...}`.\nIf it keeps the selector without adding the scoping class to it, the given style will become a global style, affecting your entire page.If you need to style something that Svelte can't identify at compile time, you will need to explicitly opt into global styles by using :global(...). But also keep in mind that you can wrap :global(...) around only part of a selector. .foo :global(.bar) { ... } will style any .bar elements that appear within the component's .foo elements. As long as there's some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","Is Svelte v2 still available?"],"href":"/docs/svelte/faq#Is-Svelte-v2-still-available","content":"New features aren't being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.The documentation is still available here.","rank":null},{"breadcrumbs":["Docs","Svelte","Misc","Frequently asked questions","How do I do hot module reloading?"],"href":"/docs/svelte/faq#How-do-I-do-hot-module-reloading","content":"We recommend using SvelteKit, which supports HMR out of the box and is built on top of Vite and svelte-hmr. There are also community plugins for rollup and webpack.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte"],"href":"/docs/svelte/svelte","content":"import {\n\tSvelteComponent,\n\tSvelteComponentTyped,\n\tafterUpdate,\n\tbeforeUpdate,\n\tcreateContext,\n\tcreateEventDispatcher,\n\tcreateRawSnippet,\n\tflushSync,\n\tfork,\n\tgetAbortSignal,\n\tgetAllContexts,\n\tgetContext,\n\thasContext,\n\thydratable,\n\thydrate,\n\tmount,\n\tonDestroy,\n\tonMount,\n\tsetContext,\n\tsettled,\n\ttick,\n\tunmount,\n\tuntrack\n} from 'svelte';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","SvelteComponent"],"href":"/docs/svelte/svelte#SvelteComponent","content":"This was the base class for Svelte components in Svelte 4. Svelte 5+ components\nare completely different under the hood. For typing, use Component instead.\nTo instantiate components, use mount instead.\nSee migration guide for more info.\nclass SvelteComponent<\n\tProps extends Record<string, any> = Record<string, any>,\n\tEvents extends Record<string, any> = any,\n\tSlots extends Record<string, any> = any\n> {/*…*/}\nstatic element?: typeof HTMLElement;\nThe custom element version of the component. Only present if compiled with the customElement compiler option\n\n[prop: string]: any;\n\nconstructor(options: ComponentConstructorOptions<Properties<Props, Slots>>);\n\n<span class=\"tag deprecated\">deprecated</span> This constructor only exists when using the `asClassComponent` compatibility helper, which\nis a stop-gap solution. Migrate towards using `mount` instead. See\n[migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.\n\n\n$destroy(): void;\n\n<span class=\"tag deprecated\">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which\nis a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)\nfor more info.\n\n\n$on<K extends Extract<keyof Events, string>>(\n\ttype: K,\n\tcallback: (e: Events[K]) => void\n): () => void;\n\n<span class=\"tag deprecated\">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which\nis a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)\nfor more info.\n\n\n$set(props: Partial<Props>): void;\n\n<span class=\"tag deprecated\">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which\nis a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)\nfor more info.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","SvelteComponentTyped"],"href":"/docs/svelte/svelte#SvelteComponentTyped","content":"Use Component instead. See migration guide for more information.\n\nclass SvelteComponentTyped<\n\tProps extends Record<string, any> = Record<string, any>,\n\tEvents extends Record<string, any> = any,\n\tSlots extends Record<string, any> = any\n> extends SvelteComponent<Props, Events, Slots> {}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","afterUpdate"],"href":"/docs/svelte/svelte#afterUpdate","content":"Use `$effect` instead\nSchedules a callback to run immediately after the component has been updated.The first time the callback runs will be after the initial onMount.In runes mode use $effect instead.\nfunction afterUpdate(fn: () => void): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","beforeUpdate"],"href":"/docs/svelte/svelte#beforeUpdate","content":"Use `$effect.pre` instead\nSchedules a callback to run immediately before the component is updated after any state change.The first time the callback runs will be before the initial onMount.In runes mode use $effect.pre instead.\nfunction beforeUpdate(fn: () => void): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","createContext"],"href":"/docs/svelte/svelte#createContext","content":"Available since 5.40.0\nReturns a [get, set] pair of functions for working with context in a type-safe way.get will throw an error if no parent component called set.\nfunction createContext<T>(): [() => T, (context: T) => T];","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","createEventDispatcher"],"href":"/docs/svelte/svelte#createEventDispatcher","content":"Use callback props and/or the $host() rune instead — see migration guide\nCreates an event dispatcher that can be used to dispatch component events.\nEvent dispatchers are functions that can take two arguments: name and detail.Component events created with createEventDispatcher create a\nCustomEvent.\nThese events do not bubble.\nThe detail argument corresponds to the CustomEvent.detail\nproperty and can contain any type of data.The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:const dispatch = createEventDispatcher<{\n loaded: null; // does not take a detail argument\n change: string; // takes a detail argument of type string, which is required\n optional: number | null; // takes an optional detail argument of type number\n}>();\nfunction createEventDispatcher<\n\tEventMap extends Record<string, any> = any\n>(): EventDispatcher<EventMap>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","createRawSnippet"],"href":"/docs/svelte/svelte#createRawSnippet","content":"Create a snippet programmatically\nfunction createRawSnippet<Params extends unknown[]>(\n\tfn: (...params: Getters<Params>) => {\n\t\trender: () => string;\n\t\tsetup?: (element: Element) => void | (() => void);\n\t}\n): Snippet<Params>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","flushSync"],"href":"/docs/svelte/svelte#flushSync","content":"Synchronously flush any pending updates.\nReturns void if no callback is provided, otherwise returns the result of calling the callback.\nfunction flushSync<T = void>(fn?: (() => T) | undefined): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","fork"],"href":"/docs/svelte/svelte#fork","content":"Available since 5.42\nCreates a 'fork', in which state changes are evaluated but not applied to the DOM.\nThis is useful for speculatively loading data (for example) when you suspect that\nthe user is about to take some action.Frameworks like SvelteKit can use this to preload data when the user touches or\nhovers over a link, making any subsequent navigation feel instantaneous.The fn parameter is a synchronous function that modifies some state. The\nstate changes will be reverted after the fork is initialised, then reapplied\nif and when the fork is eventually committed.When it becomes clear that a fork will not be committed (e.g. because the\nuser navigated elsewhere), it must be discarded to avoid leaking memory.\nfunction fork(fn: () => void): Fork;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","getAbortSignal"],"href":"/docs/svelte/svelte#getAbortSignal","content":"Returns an `AbortSignal` that aborts when the current derived or effect re-runs or is destroyed.Must be called while a derived or effect is running.<script>\n\timport { getAbortSignal } from 'svelte';\n\n\tlet { id } = $props();\n\n\tasync function getData(id) {\n\t\tconst response = await fetch(`/items/${id}`, {\n\t\t\tsignal: getAbortSignal()\n\t\t});\n\n\t\treturn await response.json();\n\t}\n\n\tconst data = $derived(await getData(id));\n</script>\nfunction getAbortSignal(): AbortSignal;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","getAllContexts"],"href":"/docs/svelte/svelte#getAllContexts","content":"Retrieves the whole context map that belongs to the closest parent component.\nMust be called during component initialisation. Useful, for example, if you\nprogrammatically create a component and want to pass the existing context to it.\nfunction getAllContexts<\n\tT extends Map<any, any> = Map<any, any>\n>(): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","getContext"],"href":"/docs/svelte/svelte#getContext","content":"Retrieves the context that belongs to the closest parent component with the specified key.\nMust be called during component initialisation.`createContext` is a type-safe alternative.\nfunction getContext<T>(key: any): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","hasContext"],"href":"/docs/svelte/svelte#hasContext","content":"Checks whether a given key has been set in the context of a parent component.\nMust be called during component initialisation.\nfunction hasContext(key: any): boolean;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","hydratable"],"href":"/docs/svelte/svelte#hydratable","content":"function hydratable<T>(key: string, fn: () => T): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","hydrate"],"href":"/docs/svelte/svelte#hydrate","content":"Hydrates a component on the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component\nfunction hydrate<\n\tProps extends Record<string, any>,\n\tExports extends Record<string, any>\n>(\n\tcomponent:\n\t\t| ComponentType<SvelteComponent<Props>>\n\t\t| Component<Props, Exports, any>,\n\toptions: {} extends Props\n\t\t? {\n\t\t\t\ttarget: Document | Element | ShadowRoot;\n\t\t\t\tprops?: Props;\n\t\t\t\tevents?: Record<string, (e: any) => any>;\n\t\t\t\tcontext?: Map<any, any>;\n\t\t\t\tintro?: boolean;\n\t\t\t\trecover?: boolean;\n\t\t\t\ttransformError?: (error: unknown) => unknown;\n\t\t\t}\n\t\t: {\n\t\t\t\ttarget: Document | Element | ShadowRoot;\n\t\t\t\tprops: Props;\n\t\t\t\tevents?: Record<string, (e: any) => any>;\n\t\t\t\tcontext?: Map<any, any>;\n\t\t\t\tintro?: boolean;\n\t\t\t\trecover?: boolean;\n\t\t\t\ttransformError?: (error: unknown) => unknown;\n\t\t\t}\n): Exports;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","mount"],"href":"/docs/svelte/svelte#mount","content":"Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.\nTransitions will play during the initial render unless the intro option is set to false.\nfunction mount<\n\tProps extends Record<string, any>,\n\tExports extends Record<string, any>\n>(\n\tcomponent:\n\t\t| ComponentType<SvelteComponent<Props>>\n\t\t| Component<Props, Exports, any>,\n\toptions: MountOptions<Props>\n): Exports;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","onDestroy"],"href":"/docs/svelte/svelte#onDestroy","content":"Schedules a callback to run immediately before the component is unmounted.Out of onMount, beforeUpdate, afterUpdate and onDestroy, this is the\nonly one that runs inside a server-side component.\nfunction onDestroy(fn: () => any): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","onMount"],"href":"/docs/svelte/svelte#onMount","content":"onMount, like `$effect`, schedules a function to run as soon as the component has been mounted to the DOM.\nUnlike $effect, the provided function only runs once.It must be called during the component's initialisation (but doesn't need to live inside the component;\nit can be called from an external module). If a function is returned synchronously from onMount,\nit will be called when the component is unmounted.onMount functions do not run during server-side rendering.\nfunction onMount<T>(\n\tfn: () =>\n\t\t| NotFunction<T>\n\t\t| Promise<NotFunction<T>>\n\t\t| (() => any)\n): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","setContext"],"href":"/docs/svelte/svelte#setContext","content":"Associates an arbitrary context object with the current component and the specified key\nand returns that object. The context is then available to children of the component\n(including slotted content) with getContext.Like lifecycle functions, this must be called during component initialisation.`createContext` is a type-safe alternative.\nfunction setContext<T>(key: any, context: T): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","settled"],"href":"/docs/svelte/svelte#settled","content":"Available since 5.36\nReturns a promise that resolves once any state changes, and asynchronous work resulting from them,\nhave resolved and the DOM has been updated\nfunction settled(): Promise<void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","tick"],"href":"/docs/svelte/svelte#tick","content":"Returns a promise that resolves once any pending state changes have been applied.\nfunction tick(): Promise<void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","unmount"],"href":"/docs/svelte/svelte#unmount","content":"Unmounts a component that was previously mounted using mount or hydrate.Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void). \nimport { mount, unmount } from 'svelte';\nimport App from './App.svelte';\n\nconst app = mount(App, { target: document.body });\n\n// later...\nunmount(app, { outro: true });\nfunction unmount(\n\tcomponent: Record<string, any>,\n\toptions?:\n\t\t| {\n\t\t\t\toutro?: boolean;\n\t\t  }\n\t\t| undefined\n): Promise<void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","untrack"],"href":"/docs/svelte/svelte#untrack","content":"When used inside a `$derived` or `$effect`,\nany state read inside fn will not be treated as a dependency.$effect(() => {\n\t// this will run when `data` changes, but not when `time` changes\n\tsave(data, {\n\t\ttimestamp: untrack(() => time)\n\t});\n});\nfunction untrack<T>(fn: () => T): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","Component"],"href":"/docs/svelte/svelte#Component","content":"Can be used to create strongly typed Svelte components.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","Component","Example:"],"href":"/docs/svelte/svelte#Component-Example:","content":"You have component library on npm called component-library, from which\nyou export a component called MyComponent. For Svelte+TypeScript users,\nyou want to provide typings. Therefore you create a index.d.ts:import type { Component } from 'svelte';\nexport declare const MyComponent: Component<{ foo: string }> {}Typing this makes it possible for IDEs like VS Code with the Svelte extension\nto provide intellisense and to use the component like this in a Svelte file\nwith TypeScript:<script lang=\"ts\">\n\timport { MyComponent } from \"component-library\";\n</script>\n<MyComponent foo={'bar'} />\ninterface Component<\n\tProps extends Record<string, any> = {},\n\tExports extends Record<string, any> = {},\n\tBindings extends keyof Props | '' = string\n> {/*…*/}\n(\n\tthis: void,\n\tinternals: ComponentInternals,\n\tprops: Props\n): {\n\t/**\n\t * @deprecated This method only exists when using one of the legacy compatibility helpers, which\n\t * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)\n\t * for more info.\n\t */\n\t$on?(type: string, callback: (e: any) => void): () => void;\n\t/**\n\t * @deprecated This method only exists when using one of the legacy compatibility helpers, which\n\t * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)\n\t * for more info.\n\t */\n\t$set?(props: Partial<Props>): void;\n} & Exports;\n\n`internal` An internal object used by Svelte. Do not use or modify.\n`props` The props passed to the component.\n\n\nelement?: typeof HTMLElement;\nThe custom element version of the component. Only present if compiled with the customElement compiler option","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","ComponentConstructorOptions"],"href":"/docs/svelte/svelte#ComponentConstructorOptions","content":"In Svelte 4, components are classes. In Svelte 5, they are functions.\nUse mount instead to instantiate components.\nSee migration guide\nfor more info.\n\ninterface ComponentConstructorOptions<\n\tProps extends Record<string, any> = Record<string, any>\n> {/*…*/}\ntarget: Element | Document | ShadowRoot;\n\nanchor?: Element;\n\nprops?: Props;\n\ncontext?: Map<any, any>;\n\nhydrate?: boolean;\n\nintro?: boolean;\n\nrecover?: boolean;\n\nsync?: boolean;\n\nidPrefix?: string;\n\n$$inline?: boolean;\n\ntransformError?: (error: unknown) => unknown;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","ComponentEvents"],"href":"/docs/svelte/svelte#ComponentEvents","content":"The new Component type does not have a dedicated Events type. Use ComponentProps instead.\n\ntype ComponentEvents<Comp extends SvelteComponent> =\n\tComp extends SvelteComponent<any, infer Events>\n\t\t? Events\n\t\t: never;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","ComponentInternals"],"href":"/docs/svelte/svelte#ComponentInternals","content":"Internal implementation details that vary between environments\ntype ComponentInternals = Branded<{}, 'ComponentInternals'>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","ComponentProps"],"href":"/docs/svelte/svelte#ComponentProps","content":"Convenience type to get the props the given component expects.Example: Ensure a variable contains the props expected by MyComponent:import type { ComponentProps } from 'svelte';\nimport MyComponent from './MyComponent.svelte';\n\n// Errors if these aren't the correct props expected by MyComponent.\nconst props: ComponentProps<typeof MyComponent> = { foo: 'bar' };[!NOTE] In Svelte 4, you would do `ComponentProps<MyComponent>` because `MyComponent` was a class.Example: A generic function that accepts some component and infers the type of its props:import type { Component, ComponentProps } from 'svelte';\nimport MyComponent from './MyComponent.svelte';\n\nfunction withProps<TComponent extends Component<any>>(\n\tcomponent: TComponent,\n\tprops: ComponentProps<TComponent>\n) {};\n\n// Errors if the second argument is not the correct props expected by the component in the first argument.\nwithProps(MyComponent, { foo: 'bar' });\ntype ComponentProps<\n\tComp extends SvelteComponent | Component<any, any>\n> =\n\tComp extends SvelteComponent<infer Props>\n\t\t? Props\n\t\t: Comp extends Component<infer Props, any>\n\t\t\t? Props\n\t\t\t: never;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","ComponentType"],"href":"/docs/svelte/svelte#ComponentType","content":"This type is obsolete when working with the new Component type.\n\ntype ComponentType<\n\tComp extends SvelteComponent = SvelteComponent\n> = (new (\n\toptions: ComponentConstructorOptions<\n\t\tComp extends SvelteComponent<infer Props>\n\t\t\t? Props\n\t\t\t: Record<string, any>\n\t>\n) => Comp) & {\n\t/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */\n\telement?: typeof HTMLElement;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","EventDispatcher"],"href":"/docs/svelte/svelte#EventDispatcher","content":"interface EventDispatcher<\n\tEventMap extends Record<string, any>\n> {/*…*/}\n<Type extends keyof EventMap>(\n\t...args: null extends EventMap[Type]\n\t\t? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]\n\t\t: undefined extends EventMap[Type]\n\t\t\t? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]\n\t\t\t: [type: Type, parameter: EventMap[Type], options?: DispatchOptions]\n): boolean;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","Fork"],"href":"/docs/svelte/svelte#Fork","content":"Available since 5.42\nRepresents work that is happening off-screen, such as data being preloaded\nin anticipation of the user navigating\ninterface Fork {/*…*/}\ncommit(): Promise<void>;\nCommit the fork. The promise will resolve once the state change has been applied\n\ndiscard(): void;\nDiscard the fork","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","MountOptions"],"href":"/docs/svelte/svelte#MountOptions","content":"Defines the options accepted by the mount() function.\ntype MountOptions<\n\tProps extends Record<string, any> = Record<string, any>\n> = {\n\t/**\n\t * Target element where the component will be mounted.\n\t */\n\ttarget: Document | Element | ShadowRoot;\n\t/**\n\t * Optional node inside `target`. When specified, it is used to render the component immediately before it.\n\t */\n\tanchor?: Node;\n\t/**\n\t * Allows the specification of events.\n\t * @deprecated Use callback props instead.\n\t */\n\tevents?: Record<string, (e: any) => any>;\n\t/**\n\t * Can be accessed via `getContext()` at the component level.\n\t */\n\tcontext?: Map<any, any>;\n\t/**\n\t * Whether or not to play transitions on initial render.\n\t * @default true\n\t */\n\tintro?: boolean;\n\t/**\n\t * A function that transforms errors caught by error boundaries before they are passed to the `failed` snippet.\n\t * Defaults to the identity function.\n\t */\n\ttransformError?: (\n\t\terror: unknown\n\t) => unknown | Promise<unknown>;\n} & ({} extends Props\n\t? {\n\t\t\t/**\n\t\t\t * Component properties.\n\t\t\t */\n\t\t\tprops?: Props;\n\t\t}\n\t: {\n\t\t\t/**\n\t\t\t * Component properties.\n\t\t\t */\n\t\t\tprops: Props;\n\t\t});","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte","Snippet"],"href":"/docs/svelte/svelte#Snippet","content":"The type of a #snippet block. You can use it to (for example) express that your component expects a snippet of a certain type:let { banner }: { banner: Snippet<[{ text: string }]> } = $props();You can only call a snippet through the {@render ...} tag.See the snippet documentation for more info.\ninterface Snippet<Parameters extends unknown[] = []> {/*…*/}\n(\n\tthis: void,\n\t// this conditional allows tuples but not arrays. Arrays would indicate a\n\t// rest parameter type, which is not supported. If rest parameters are added\n\t// in the future, the condition can be removed.\n\t...args: number extends Parameters['length'] ? never : Parameters\n): {\n\t'{@render ...} must be called with a Snippet': \"import type { Snippet } from 'svelte'\";\n} & typeof SnippetReturn;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/action"],"href":"/docs/svelte/svelte-action","content":"This module provides types for actions, which have been superseded by attachments.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/action","Action"],"href":"/docs/svelte/svelte-action#Action","content":"Actions are functions that are called when an element is created.\nYou can use this interface to type such actions.\nThe following example defines an action that only works on <div> elements\nand optionally accepts a parameter which it has a default value for:export const myAction: Action<HTMLDivElement, { someProperty: boolean } | undefined> = (node, param = { someProperty: true }) => {\n\t// ...\n}Action<HTMLDivElement> and Action<HTMLDivElement, undefined> both signal that the action accepts no parameters.You can return an object with methods update and destroy from the function and type which additional attributes and events it has.\nSee interface ActionReturn for more details.\ninterface Action<\n\tElement = HTMLElement,\n\tParameter = undefined,\n\tAttributes extends Record<string, any> = Record<\n\t\tnever,\n\t\tany\n\t>\n> {/*…*/}\n<Node extends Element>(\n\t...args: undefined extends Parameter\n\t\t? [node: Node, parameter?: Parameter]\n\t\t: [node: Node, parameter: Parameter]\n): void | ActionReturn<Parameter, Attributes>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/action","ActionReturn"],"href":"/docs/svelte/svelte-action#ActionReturn","content":"Actions can return an object containing the two properties defined in this interface. Both are optional.update: An action can have a parameter. This method will be called whenever that parameter changes,\n  immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<undefined>` both\n  mean that the action accepts no parameters.\ndestroy: Method that is called after the element is unmountedAdditionally, you can specify which additional attributes and events the action enables on the applied element.\nThis applies to TypeScript typings only and has no effect at runtime.Example usage:interface Attributes {\n\tnewprop?: string;\n\t'on:event': (e: CustomEvent<boolean>) => void;\n}\n\nexport function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> {\n\t// ...\n\treturn {\n\t\tupdate: (updatedParameter) => {...},\n\t\tdestroy: () => {...}\n\t};\n}\ninterface ActionReturn<\n\tParameter = undefined,\n\tAttributes extends Record<string, any> = Record<\n\t\tnever,\n\t\tany\n\t>\n> {/*…*/}\nupdate?: (parameter: Parameter) => void;\n\ndestroy?: () => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/animate"],"href":"/docs/svelte/svelte-animate","content":"import { flip } from 'svelte/animate';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/animate","flip"],"href":"/docs/svelte/svelte-animate#flip","content":"The flip function calculates the start and end position of an element and animates between them, translating the x and y values.\nflip stands for First, Last, Invert, Play.\nfunction flip(\n\tnode: Element,\n\t{\n\t\tfrom,\n\t\tto\n\t}: {\n\t\tfrom: DOMRect;\n\t\tto: DOMRect;\n\t},\n\tparams?: FlipParams\n): AnimationConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/animate","AnimationConfig"],"href":"/docs/svelte/svelte-animate#AnimationConfig","content":"interface AnimationConfig {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: (t: number) => number;\n\ncss?: (t: number, u: number) => string;\n\ntick?: (t: number, u: number) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/animate","FlipParams"],"href":"/docs/svelte/svelte-animate#FlipParams","content":"interface FlipParams {/*…*/}\ndelay?: number;\n\nduration?: number | ((len: number) => number);\n\neasing?: (t: number) => number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/attachments"],"href":"/docs/svelte/svelte-attachments","content":"import { createAttachmentKey, fromAction } from 'svelte/attachments';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/attachments","createAttachmentKey"],"href":"/docs/svelte/svelte-attachments#createAttachmentKey","content":"Available since 5.29\nCreates an object key that will be recognised as an attachment when the object is spread onto an element,\nas a programmatic alternative to using {@attach ...}. This can be useful for library authors, though\nis generally not needed when building an app.<script>\n\timport { createAttachmentKey } from 'svelte/attachments';\n\n\tconst props = {\n\t\tclass: 'cool',\n\t\tonclick: () => alert('clicked'),\n\t\t[createAttachmentKey()]: (node) => {\n\t\t\tnode.textContent = 'attached!';\n\t\t}\n\t};\n</script>\n\n<button {...props}>click me</button>\nfunction createAttachmentKey(): symbol;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/attachments","fromAction"],"href":"/docs/svelte/svelte-attachments#fromAction","content":"Converts an action into an attachment keeping the same behavior.\nIt's useful if you want to start using attachments on components but you have actions provided by a library.Note that the second argument, if provided, must be a function that returns the argument to the\naction function, not the argument itself.<!-- with an action -->\n<div use:foo={bar}>...</div>\n\n<!-- with an attachment -->\n<div {@attach fromAction(foo, () => bar)}>...</div>\nfunction fromAction<\n\tE extends EventTarget,\n\tT extends unknown\n>(\n\taction:\n\t\t| Action<E, T>\n\t\t| ((element: E, arg: T) => void | ActionReturn<T>),\n\tfn: () => T\n): Attachment<E>;\n\nfunction fromAction<E extends EventTarget>(\n\taction:\n\t\t| Action<E, void>\n\t\t| ((element: E) => void | ActionReturn<void>)\n): Attachment<E>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/attachments","Attachment"],"href":"/docs/svelte/svelte-attachments#Attachment","content":"An attachment is a function that runs when an element is mounted\nto the DOM, and optionally returns a function that is called when the element is later removed.It can be attached to an element with an {@attach ...} tag, or by spreading an object containing\na property created with `createAttachmentKey`.\ninterface Attachment<T extends EventTarget = Element> {/*…*/}\n(element: T): void | (() => void);","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler"],"href":"/docs/svelte/svelte-compiler","content":"import {\n\tVERSION,\n\tcompile,\n\tcompileModule,\n\tmigrate,\n\tparse,\n\tparseCss,\n\tpreprocess,\n\tprint,\n\twalk\n} from 'svelte/compiler';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","VERSION"],"href":"/docs/svelte/svelte-compiler#VERSION","content":"The current version, as set in package.json.\nconst VERSION: string;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","compile"],"href":"/docs/svelte/svelte-compiler#compile","content":"compile converts your .svelte source code into a JavaScript module that exports a component\nfunction compile(\n\tsource: string,\n\toptions: CompileOptions\n): CompileResult;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","compileModule"],"href":"/docs/svelte/svelte-compiler#compileModule","content":"compileModule takes your JavaScript source code containing runes, and turns it into a JavaScript module.\nfunction compileModule(\n\tsource: string,\n\toptions: ModuleCompileOptions\n): CompileResult;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","migrate"],"href":"/docs/svelte/svelte-compiler#migrate","content":"Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.\nMay throw an error if the code is too complex to migrate automatically.\nfunction migrate(\n\tsource: string,\n\t{\n\t\tfilename,\n\t\tuse_ts\n\t}?:\n\t\t| {\n\t\t\t\tfilename?: string;\n\t\t\t\tuse_ts?: boolean;\n\t\t  }\n\t\t| undefined\n): {\n\tcode: string;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","parse"],"href":"/docs/svelte/svelte-compiler#parse","content":"The parse function parses a component, returning only its abstract syntax tree.The modern option (false by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.\nmodern will become true by default in Svelte 6, and the option will be removed in Svelte 7.\nfunction parse(\n\tsource: string,\n\toptions: {\n\t\tfilename?: string;\n\t\tmodern: true;\n\t\tloose?: boolean;\n\t}\n): AST.Root;\n\nfunction parse(\n\tsource: string,\n\toptions?:\n\t\t| {\n\t\t\t\tfilename?: string;\n\t\t\t\tmodern?: false;\n\t\t\t\tloose?: boolean;\n\t\t  }\n\t\t| undefined\n): Record<string, any>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","parseCss"],"href":"/docs/svelte/svelte-compiler#parseCss","content":"The parseCss function parses a CSS stylesheet, returning its abstract syntax tree.\nfunction parseCss(source: string): AST.CSS.StyleSheetFile;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","preprocess"],"href":"/docs/svelte/svelte-compiler#preprocess","content":"The preprocess function provides convenient hooks for arbitrarily transforming component source code.\nFor example, it can be used to convert a <style lang=\"sass\"> block into vanilla CSS.\nfunction preprocess(\n\tsource: string,\n\tpreprocessor: PreprocessorGroup | PreprocessorGroup[],\n\toptions?:\n\t\t| {\n\t\t\t\tfilename?: string;\n\t\t  }\n\t\t| undefined\n): Promise<Processed>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","print"],"href":"/docs/svelte/svelte-compiler#print","content":"print converts a Svelte AST node back into Svelte source code.\nIt is primarily intended for tools that parse and transform components using the compiler’s modern AST representation.print(ast) requires an AST node produced by parse with modern: true, or any sub-node within that modern AST.\nThe result contains the generated source and a corresponding source map.\nThe output is valid Svelte, but formatting details such as whitespace or quoting may differ from the original.\nfunction print(\n\tast: AST.SvelteNode,\n\toptions?: Options | undefined\n): {\n\tcode: string;\n\tmap: any;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","walk"],"href":"/docs/svelte/svelte-compiler#walk","content":"Replace this with import { walk } from 'estree-walker'\n\nfunction walk(): never;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","AST"],"href":"/docs/svelte/svelte-compiler#AST","content":"namespace AST {\n\texport interface BaseNode {\n\t\ttype: string;\n\t\tstart: number;\n\t\tend: number;\n\t}\n\n\texport interface Fragment {\n\t\ttype: 'Fragment';\n\t\tnodes: Array<\n\t\t\tText | Tag | ElementLike | Block | Comment\n\t\t>;\n\t}\n\n\texport interface Root extends BaseNode {\n\t\ttype: 'Root';\n\t\t/**\n\t\t * Inline options provided by `<svelte:options>` — these override options passed to `compile(...)`\n\t\t */\n\t\toptions: SvelteOptions | null;\n\t\tfragment: Fragment;\n\t\t/** The parsed `<style>` element, if exists */\n\t\tcss: AST.CSS.StyleSheet | null;\n\t\t/** The parsed `<script>` element, if exists */\n\t\tinstance: Script | null;\n\t\t/** The parsed `<script module>` element, if exists */\n\t\tmodule: Script | null;\n\t\t/** Comments found in <script> and {expressions} */\n\t\tcomments: JSComment[];\n\t}\n\n\texport interface SvelteOptions {\n\t\t// start/end info (needed for warnings and for our Prettier plugin)\n\t\tstart: number;\n\t\tend: number;\n\t\t// options\n\t\trunes?: boolean;\n\t\timmutable?: boolean;\n\t\taccessors?: boolean;\n\t\tpreserveWhitespace?: boolean;\n\t\tnamespace?: Namespace;\n\t\tcss?: 'injected';\n\t\tcustomElement?: {\n\t\t\ttag?: string;\n\t\t\tshadow?:\n\t\t\t\t| 'open'\n\t\t\t\t| 'none'\n\t\t\t\t| ObjectExpression\n\t\t\t\t| undefined;\n\t\t\tprops?: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\tattribute?: string;\n\t\t\t\t\treflect?: boolean;\n\t\t\t\t\ttype?:\n\t\t\t\t\t\t| 'Array'\n\t\t\t\t\t\t| 'Boolean'\n\t\t\t\t\t\t| 'Number'\n\t\t\t\t\t\t| 'Object'\n\t\t\t\t\t\t| 'String';\n\t\t\t\t}\n\t\t\t>;\n\t\t\t/**\n\t\t\t * Is of type\n\t\t\t * ```ts\n\t\t\t * (ceClass: new () => HTMLElement) => new () => HTMLElement\n\t\t\t * ```\n\t\t\t */\n\t\t\textend?: ArrowFunctionExpression | Identifier;\n\t\t};\n\t\tattributes: Attribute[];\n\t}\n\n\t/** Static text */\n\texport interface Text extends BaseNode {\n\t\ttype: 'Text';\n\t\t/** Text with decoded HTML entities */\n\t\tdata: string;\n\t\t/** The original text, with undecoded HTML entities */\n\t\traw: string;\n\t}\n\n\t/** A (possibly reactive) template expression — `{...}` */\n\texport interface ExpressionTag extends BaseNode {\n\t\ttype: 'ExpressionTag';\n\t\texpression: Expression;\n\t}\n\n\t/** A (possibly reactive) HTML template expression — `{@html ...}` */\n\texport interface HtmlTag extends BaseNode {\n\t\ttype: 'HtmlTag';\n\t\texpression: Expression;\n\t}\n\n\t/** An HTML comment */\n\t// TODO rename to disambiguate\n\texport interface Comment extends BaseNode {\n\t\ttype: 'Comment';\n\t\t/** the contents of the comment */\n\t\tdata: string;\n\t}\n\n\t/** A `{@const ...}` tag */\n\texport interface ConstTag extends BaseNode {\n\t\ttype: 'ConstTag';\n\t\tdeclaration: VariableDeclaration & {\n\t\t\tdeclarations: [\n\t\t\t\tVariableDeclarator & {\n\t\t\t\t\tid: Pattern;\n\t\t\t\t\tinit: Expression;\n\t\t\t\t}\n\t\t\t];\n\t\t};\n\t}\n\n\t/** A `{let ...}` or `{const ...}` tag */\n\texport interface DeclarationTag extends BaseNode {\n\t\ttype: 'DeclarationTag';\n\t\tdeclaration: VariableDeclaration;\n\t}\n\n\t/** A `{@debug ...}` tag */\n\texport interface DebugTag extends BaseNode {\n\t\ttype: 'DebugTag';\n\t\tidentifiers: Identifier[];\n\t}\n\n\t/** A `{@render foo(...)} tag */\n\texport interface RenderTag extends BaseNode {\n\t\ttype: 'RenderTag';\n\t\texpression:\n\t\t\t| SimpleCallExpression\n\t\t\t| (ChainExpression & {\n\t\t\t\t\texpression: SimpleCallExpression;\n\t\t\t  });\n\t}\n\n\t/** A `{@attach foo(...)} tag */\n\texport interface AttachTag extends BaseNode {\n\t\ttype: 'AttachTag';\n\t\texpression: Expression;\n\t}\n\n\t/** An `animate:` directive */\n\texport interface AnimateDirective extends BaseAttribute {\n\t\ttype: 'AnimateDirective';\n\t\t/** The 'x' in `animate:x` */\n\t\tname: string;\n\t\t/** The y in `animate:x={y}` */\n\t\texpression: null | Expression;\n\t}\n\n\t/** A `bind:` directive */\n\texport interface BindDirective extends BaseAttribute {\n\t\ttype: 'BindDirective';\n\t\t/** The 'x' in `bind:x` */\n\t\tname: string;\n\t\t/** The y in `bind:x={y}` */\n\t\texpression:\n\t\t\t| Identifier\n\t\t\t| MemberExpression\n\t\t\t| SequenceExpression;\n\t}\n\n\t/** A `class:` directive */\n\texport interface ClassDirective extends BaseAttribute {\n\t\ttype: 'ClassDirective';\n\t\t/** The 'x' in `class:x` */\n\t\tname: 'class';\n\t\t/** The 'y' in `class:x={y}`, or the `x` in `class:x` */\n\t\texpression: Expression;\n\t}\n\n\t/** A `let:` directive */\n\texport interface LetDirective extends BaseAttribute {\n\t\ttype: 'LetDirective';\n\t\t/** The 'x' in `let:x` */\n\t\tname: string;\n\t\t/** The 'y' in `let:x={y}` */\n\t\texpression:\n\t\t\t| null\n\t\t\t| Identifier\n\t\t\t| ArrayExpression\n\t\t\t| ObjectExpression;\n\t}\n\n\t/** An `on:` directive */\n\texport interface OnDirective extends BaseAttribute {\n\t\ttype: 'OnDirective';\n\t\t/** The 'x' in `on:x` */\n\t\tname: string;\n\t\t/** The 'y' in `on:x={y}` */\n\t\texpression: null | Expression;\n\t\tmodifiers: Array<\n\t\t\t| 'capture'\n\t\t\t| 'nonpassive'\n\t\t\t| 'once'\n\t\t\t| 'passive'\n\t\t\t| 'preventDefault'\n\t\t\t| 'self'\n\t\t\t| 'stopImmediatePropagation'\n\t\t\t| 'stopPropagation'\n\t\t\t| 'trusted'\n\t\t>;\n\t}\n\n\t/** A `style:` directive */\n\texport interface StyleDirective extends BaseAttribute {\n\t\ttype: 'StyleDirective';\n\t\t/** The 'x' in `style:x` */\n\t\tname: string;\n\t\t/** The 'y' in `style:x={y}` */\n\t\tvalue:\n\t\t\t| true\n\t\t\t| ExpressionTag\n\t\t\t| Array<ExpressionTag | Text>;\n\t\tmodifiers: Array<'important'>;\n\t}\n\n\t// TODO have separate in/out/transition directives\n\t/** A `transition:`, `in:` or `out:` directive */\n\texport interface TransitionDirective extends BaseAttribute {\n\t\ttype: 'TransitionDirective';\n\t\t/** The 'x' in `transition:x` */\n\t\tname: string;\n\t\t/** The 'y' in `transition:x={y}` */\n\t\texpression: null | Expression;\n\t\tmodifiers: Array<'local' | 'global'>;\n\t\t/** True if this is a `transition:` or `in:` directive */\n\t\tintro: boolean;\n\t\t/** True if this is a `transition:` or `out:` directive */\n\t\toutro: boolean;\n\t}\n\n\t/** A `use:` directive */\n\texport interface UseDirective extends BaseAttribute {\n\t\ttype: 'UseDirective';\n\t\t/** The 'x' in `use:x` */\n\t\tname: string;\n\t\t/** The 'y' in `use:x={y}` */\n\t\texpression: null | Expression;\n\t}\n\n\texport interface BaseElement extends BaseNode {\n\t\tname: string;\n\t\tname_loc: SourceLocation;\n\t\tattributes: Array<\n\t\t\tAttribute | SpreadAttribute | Directive | AttachTag\n\t\t>;\n\t\tfragment: Fragment;\n\t}\n\n\texport interface Component extends BaseElement {\n\t\ttype: 'Component';\n\t}\n\n\texport interface TitleElement extends BaseElement {\n\t\ttype: 'TitleElement';\n\t\tname: 'title';\n\t}\n\n\texport interface SlotElement extends BaseElement {\n\t\ttype: 'SlotElement';\n\t\tname: 'slot';\n\t}\n\n\texport interface RegularElement extends BaseElement {\n\t\ttype: 'RegularElement';\n\t}\n\n\texport interface SvelteBody extends BaseElement {\n\t\ttype: 'SvelteBody';\n\t\tname: 'svelte:body';\n\t}\n\n\texport interface SvelteComponent extends BaseElement {\n\t\ttype: 'SvelteComponent';\n\t\tname: 'svelte:component';\n\t\texpression: Expression;\n\t}\n\n\texport interface SvelteDocument extends BaseElement {\n\t\ttype: 'SvelteDocument';\n\t\tname: 'svelte:document';\n\t}\n\n\texport interface SvelteElement extends BaseElement {\n\t\ttype: 'SvelteElement';\n\t\tname: 'svelte:element';\n\t\ttag: Expression;\n\t}\n\n\texport interface SvelteFragment extends BaseElement {\n\t\ttype: 'SvelteFragment';\n\t\tname: 'svelte:fragment';\n\t}\n\n\texport interface SvelteBoundary extends BaseElement {\n\t\ttype: 'SvelteBoundary';\n\t\tname: 'svelte:boundary';\n\t}\n\n\texport interface SvelteHead extends BaseElement {\n\t\ttype: 'SvelteHead';\n\t\tname: 'svelte:head';\n\t}\n\n\t/** This is only an intermediate representation while parsing, it doesn't exist in the final AST */\n\texport interface SvelteOptionsRaw extends BaseElement {\n\t\ttype: 'SvelteOptions';\n\t\tname: 'svelte:options';\n\t}\n\n\texport interface SvelteSelf extends BaseElement {\n\t\ttype: 'SvelteSelf';\n\t\tname: 'svelte:self';\n\t}\n\n\texport interface SvelteWindow extends BaseElement {\n\t\ttype: 'SvelteWindow';\n\t\tname: 'svelte:window';\n\t}\n\n\t/** An `{#each ...}` block */\n\texport interface EachBlock extends BaseNode {\n\t\ttype: 'EachBlock';\n\t\texpression: Expression;\n\t\t/** The `entry` in `{#each item as entry}`. `null` if `as` part is omitted */\n\t\tcontext: Pattern | null;\n\t\tbody: Fragment;\n\t\tfallback?: Fragment;\n\t\tindex?: string;\n\t\tkey?: Expression;\n\t}\n\n\t/** An `{#if ...}` block */\n\texport interface IfBlock extends BaseNode {\n\t\ttype: 'IfBlock';\n\t\telseif: boolean;\n\t\ttest: Expression;\n\t\tconsequent: Fragment;\n\t\talternate: Fragment | null;\n\t}\n\n\t/** An `{#await ...}` block */\n\texport interface AwaitBlock extends BaseNode {\n\t\ttype: 'AwaitBlock';\n\t\texpression: Expression;\n\t\t// TODO can/should we move these inside the ThenBlock and CatchBlock?\n\t\t/** The resolved value inside the `then` block */\n\t\tvalue: Pattern | null;\n\t\t/** The rejection reason inside the `catch` block */\n\t\terror: Pattern | null;\n\t\tpending: Fragment | null;\n\t\tthen: Fragment | null;\n\t\tcatch: Fragment | null;\n\t}\n\n\texport interface KeyBlock extends BaseNode {\n\t\ttype: 'KeyBlock';\n\t\texpression: Expression;\n\t\tfragment: Fragment;\n\t}\n\n\texport interface SnippetBlock extends BaseNode {\n\t\ttype: 'SnippetBlock';\n\t\texpression: Identifier;\n\t\tparameters: Pattern[];\n\t\ttypeParams?: string;\n\t\tbody: Fragment;\n\t}\n\n\texport interface BaseAttribute extends BaseNode {\n\t\tname: string;\n\t\tname_loc: SourceLocation | null;\n\t}\n\n\texport interface Attribute extends BaseAttribute {\n\t\ttype: 'Attribute';\n\t\t/**\n\t\t * Quoted/string values are represented by an array, even if they contain a single expression like `\"{x}\"`\n\t\t */\n\t\tvalue:\n\t\t\t| true\n\t\t\t| ExpressionTag\n\t\t\t| Array<Text | ExpressionTag>;\n\t}\n\n\texport interface SpreadAttribute extends BaseNode {\n\t\ttype: 'SpreadAttribute';\n\t\texpression: Expression;\n\t}\n\n\texport interface Script extends BaseNode {\n\t\ttype: 'Script';\n\t\tcontext: 'default' | 'module';\n\t\tcontent: Program;\n\t\tattributes: Attribute[];\n\t}\n\n\texport interface JSComment {\n\t\ttype: 'Line' | 'Block';\n\t\tvalue: string;\n\t\tstart: number;\n\t\tend: number;\n\t\tloc: {\n\t\t\tstart: { line: number; column: number };\n\t\t\tend: { line: number; column: number };\n\t\t};\n\t}\n\n\texport type AttributeLike =\n\t\t| Attribute\n\t\t| SpreadAttribute\n\t\t| Directive;\n\n\texport type Directive =\n\t\t| AST.AnimateDirective\n\t\t| AST.BindDirective\n\t\t| AST.ClassDirective\n\t\t| AST.LetDirective\n\t\t| AST.OnDirective\n\t\t| AST.StyleDirective\n\t\t| AST.TransitionDirective\n\t\t| AST.UseDirective;\n\n\texport type Block =\n\t\t| AST.EachBlock\n\t\t| AST.IfBlock\n\t\t| AST.AwaitBlock\n\t\t| AST.KeyBlock\n\t\t| AST.SnippetBlock;\n\n\texport type ElementLike =\n\t\t| AST.Component\n\t\t| AST.TitleElement\n\t\t| AST.SlotElement\n\t\t| AST.RegularElement\n\t\t| AST.SvelteBody\n\t\t| AST.SvelteBoundary\n\t\t| AST.SvelteComponent\n\t\t| AST.SvelteDocument\n\t\t| AST.SvelteElement\n\t\t| AST.SvelteFragment\n\t\t| AST.SvelteHead\n\t\t| AST.SvelteOptionsRaw\n\t\t| AST.SvelteSelf\n\t\t| AST.SvelteWindow\n\t\t| AST.SvelteBoundary;\n\n\texport type Tag =\n\t\t| AST.AttachTag\n\t\t| AST.ConstTag\n\t\t| AST.DeclarationTag\n\t\t| AST.DebugTag\n\t\t| AST.ExpressionTag\n\t\t| AST.HtmlTag\n\t\t| AST.RenderTag;\n\n\texport type TemplateNode =\n\t\t| AST.Root\n\t\t| AST.Text\n\t\t| Tag\n\t\t| ElementLike\n\t\t| AST.Attribute\n\t\t| AST.SpreadAttribute\n\t\t| Directive\n\t\t| AST.AttachTag\n\t\t| AST.Comment\n\t\t| Block;\n\n\texport type SvelteNode =\n\t\t| Node\n\t\t| TemplateNode\n\t\t| AST.Fragment\n\t\t| _CSS.Node\n\t\t| Script;\n\n\texport type { _CSS as CSS };\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","CompileError"],"href":"/docs/svelte/svelte-compiler#CompileError","content":"interface CompileError extends ICompileDiagnostic {}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","CompileOptions"],"href":"/docs/svelte/svelte-compiler#CompileOptions","content":"interface CompileOptions extends ModuleCompileOptions {/*…*/}\nname?: string;\nSets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope).\nIf unspecified, will be inferred from filename\n\ncustomElement?: boolean | ((options: { filename: string }) => boolean);\n\n<span class=\"tag\">default</span> `false`\nIf true, tells the compiler to generate a custom element constructor instead of a regular Svelte component.You can also pass a function that receives { filename } and returns a boolean.\n\naccessors?: boolean;\n\n<span class=\"tag\">default</span> `false`\n<span class=\"tag deprecated\">deprecated</span> This will have no effect in runes mode\nIf true, getters and setters will be created for the component's props. If false, they will only be created for readonly exported values (i.e. those declared with const, class and function). If compiling with customElement: true this option defaults to true.\n\nnamespace?: Namespace;\n\n<span class=\"tag\">default</span> `'html'`\nThe namespace of the element; e.g., \"html\", \"svg\", \"mathml\".\n\nimmutable?: boolean;\n\n<span class=\"tag\">default</span> `false`\n<span class=\"tag deprecated\">deprecated</span> This will have no effect in runes mode\nIf true, tells the compiler that you promise not to mutate any objects.\nThis allows it to be less conservative about checking whether values have changed.\n\ncss?: 'injected' | 'external' | ((options: { filename: string }) => 'injected' | 'external');\n`'injected'`: styles will be included in the `head` when using `render(...)`, and injected into the document (if not already present) when the component mounts. For components compiled as custom elements, styles are injected to the shadow root.\n`'external'`: the CSS will only be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `'external'` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files.\nThis is always `'injected'` when compiling with `customElement` mode.You can also pass a function that receives { filename } and returns either 'injected' or 'external'.\n\ncssHash?: CssHashGetter;\n\n<span class=\"tag\">default</span> `undefined`\nA function that takes a { hash, css, name, filename } argument and returns the string that is used as a classname for scoped CSS.\nIt defaults to returning svelte-${hash(filename ?? css)}.\n\npreserveComments?: boolean;\n\n<span class=\"tag\">default</span> `false`\nIf true, your HTML comments will be preserved in the output. By default, they are stripped out.\n\npreserveWhitespace?: boolean;\n\n<span class=\"tag\">default</span> `false`\nIf true, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.\n\nfragments?: 'html' | 'tree';\n\n<span class=\"tag\">default</span> `'html'`\n<span class=\"tag since\">available since</span> v5.33\nWhich strategy to use when cloning DOM fragments:`html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)\n`tree` creates the fragment one element at a time and _then_ clones it. This is slower, but works everywhere\n\nrunes?: boolean | undefined | ((options: { filename: string }) => boolean | undefined);\n\n<span class=\"tag\">default</span> `undefined`\nSet to true to force the compiler into runes mode, even if there are no indications of runes usage.\nSet to false to force the compiler into ignoring runes, even if there are indications of runes usage.\nSet to undefined (the default) to infer runes mode from the component code.\nIs always true for JS/TS modules compiled with Svelte.\nWill be true by default in Svelte 6.\nNote that setting this to true in your svelte.config.js will force runes mode for your entire project, including components in node_modules,\nwhich is likely not what you want. If you're using Vite, consider using dynamicCompileOptions instead.\n\ndiscloseVersion?: boolean;\n\n<span class=\"tag\">default</span> `true`\nIf true, exposes the Svelte major version in the browser by adding it to a Set stored in the global window.__svelte.v.\n\ncompatibility?: {/*…*/}\n\n<span class=\"tag deprecated\">deprecated</span> Use these only as a temporary solution before migrating your code\n\ncomponentApi?: 4 | 5;\n\n<span class=\"tag\">default</span> `5`\nApplies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 —\nas a class when compiling for the browser (as though using createClassComponent(MyComponent, {...}) from svelte/legacy)\nor as an object with a .render(...) method when compiling for the server\n\n\nsourcemap?: object | string;\n\n<span class=\"tag\">default</span> `null`\nAn initial sourcemap that will be merged into the final output sourcemap.\nThis is usually the preprocessor sourcemap.\n\noutputFilename?: string;\n\n<span class=\"tag\">default</span> `null`\nUsed for your JavaScript sourcemap.\n\ncssOutputFilename?: string;\n\n<span class=\"tag\">default</span> `null`\nUsed for your CSS sourcemap.\n\nhmr?: boolean;\n\n<span class=\"tag\">default</span> `false`\nIf true, compiles components with hot reloading support.\n\nmodernAst?: boolean;\n\n<span class=\"tag\">default</span> `false`\nIf true, returns the modern version of the AST.\nWill become true by default in Svelte 6, and the option will be removed in Svelte 7.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","CompileResult"],"href":"/docs/svelte/svelte-compiler#CompileResult","content":"The return value of compile from svelte/compiler\ninterface CompileResult {/*…*/}\njs: {/*…*/}\nThe compiled JavaScript\ncode: string;\nThe generated code\nmap: SourceMap;\nA source map\n\n\ncss: null | {\n\t/** The generated code */\n\tcode: string;\n\t/** A source map */\n\tmap: SourceMap;\n\t/** Whether or not the CSS includes global rules */\n\thasGlobal: boolean;\n};\nThe compiled CSS\n\nwarnings: Warning[];\nAn array of warning objects that were generated during compilation. Each warning has several properties:`code` is a string identifying the category of warning\n`message` describes the issue in human-readable terms\n`start` and `end`, if the warning relates to a specific location, are objects with `line`, `column` and `character` properties\n\nmetadata: {/*…*/}\nMetadata about the compiled component\nrunes: boolean;\nWhether the file was compiled in runes mode, either because of an explicit option or inferred from usage.\nFor compileModule, this is always true\n\n\nast: any;\nThe AST","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","MarkupPreprocessor"],"href":"/docs/svelte/svelte-compiler#MarkupPreprocessor","content":"A markup preprocessor that takes a string of code and returns a processed version.\ntype MarkupPreprocessor = (options: {\n\t/**\n\t * The whole Svelte file content\n\t */\n\tcontent: string;\n\t/**\n\t * The filename of the Svelte file\n\t */\n\tfilename?: string;\n}) => Processed | void | Promise<Processed | void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","ModuleCompileOptions"],"href":"/docs/svelte/svelte-compiler#ModuleCompileOptions","content":"interface ModuleCompileOptions {/*…*/}\ndev?: boolean;\n\n<span class=\"tag\">default</span> `false`\nIf true, causes extra code to be added that will perform runtime checks and provide debugging information during development.\n\ngenerate?: 'client' | 'server' | false;\n\n<span class=\"tag\">default</span> `'client'`\nIf \"client\", Svelte emits code designed to run in the browser.\nIf \"server\", Svelte emits code suitable for server-side rendering.\nIf false, nothing is generated. Useful for tooling that is only interested in warnings.\n\nfilename?: string;\nUsed for debugging hints and sourcemaps. Your bundler plugin will set it automatically.\n\nrootDir?: string;\n\n<span class=\"tag\">default</span> `process.cwd() on node-like environments, undefined elsewhere`\nUsed for ensuring filenames don't leak filesystem information. Your bundler plugin will set it automatically.\n\nwarningFilter?: (warning: Warning) => boolean;\nA function that gets a Warning as an argument and returns a boolean.\nUse this to filter out warnings. Return true to keep the warning, false to discard it.\n\nexperimental?: {/*…*/}\n\n<span class=\"tag since\">available since</span> v5.36\nExperimental options\nasync?: boolean;\n\n<span class=\"tag since\">available since</span> v5.36\nAllow await keyword in deriveds, template expressions, and the top level of components","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","Preprocessor"],"href":"/docs/svelte/svelte-compiler#Preprocessor","content":"A script/style preprocessor that takes a string of code and returns a processed version.\ntype Preprocessor = (options: {\n\t/**\n\t * The script/style tag content\n\t */\n\tcontent: string;\n\t/**\n\t * The attributes on the script/style tag\n\t */\n\tattributes: Record<string, string | boolean>;\n\t/**\n\t * The whole Svelte file content\n\t */\n\tmarkup: string;\n\t/**\n\t * The filename of the Svelte file\n\t */\n\tfilename?: string;\n}) => Processed | void | Promise<Processed | void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","PreprocessorGroup"],"href":"/docs/svelte/svelte-compiler#PreprocessorGroup","content":"A preprocessor group is a set of preprocessors that are applied to a Svelte file.\ninterface PreprocessorGroup {/*…*/}\nname?: string;\nName of the preprocessor. Will be a required option in the next major version\n\nmarkup?: MarkupPreprocessor;\n\nstyle?: Preprocessor;\n\nscript?: Preprocessor;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","Processed"],"href":"/docs/svelte/svelte-compiler#Processed","content":"The result of a preprocessor run. If the preprocessor does not return a result, it is assumed that the code is unchanged.\ninterface Processed {/*…*/}\ncode: string;\nThe new code\n\nmap?: string | object;\nA source map mapping back to the original code\n\ndependencies?: string[];\nA list of additional files to watch for changes\n\nattributes?: Record<string, string | boolean>;\nOnly for script/style preprocessors: The updated attributes to set on the tag. If undefined, attributes stay unchanged.\n\ntoString?: () => string;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/compiler","Warning"],"href":"/docs/svelte/svelte-compiler#Warning","content":"interface Warning extends ICompileDiagnostic {}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing"],"href":"/docs/svelte/svelte-easing","content":"import {\n\tbackIn,\n\tbackInOut,\n\tbackOut,\n\tbounceIn,\n\tbounceInOut,\n\tbounceOut,\n\tcircIn,\n\tcircInOut,\n\tcircOut,\n\tcubicIn,\n\tcubicInOut,\n\tcubicOut,\n\telasticIn,\n\telasticInOut,\n\telasticOut,\n\texpoIn,\n\texpoInOut,\n\texpoOut,\n\tlinear,\n\tquadIn,\n\tquadInOut,\n\tquadOut,\n\tquartIn,\n\tquartInOut,\n\tquartOut,\n\tquintIn,\n\tquintInOut,\n\tquintOut,\n\tsineIn,\n\tsineInOut,\n\tsineOut\n} from 'svelte/easing';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","backIn"],"href":"/docs/svelte/svelte-easing#backIn","content":"function backIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","backInOut"],"href":"/docs/svelte/svelte-easing#backInOut","content":"function backInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","backOut"],"href":"/docs/svelte/svelte-easing#backOut","content":"function backOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","bounceIn"],"href":"/docs/svelte/svelte-easing#bounceIn","content":"function bounceIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","bounceInOut"],"href":"/docs/svelte/svelte-easing#bounceInOut","content":"function bounceInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","bounceOut"],"href":"/docs/svelte/svelte-easing#bounceOut","content":"function bounceOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","circIn"],"href":"/docs/svelte/svelte-easing#circIn","content":"function circIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","circInOut"],"href":"/docs/svelte/svelte-easing#circInOut","content":"function circInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","circOut"],"href":"/docs/svelte/svelte-easing#circOut","content":"function circOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","cubicIn"],"href":"/docs/svelte/svelte-easing#cubicIn","content":"function cubicIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","cubicInOut"],"href":"/docs/svelte/svelte-easing#cubicInOut","content":"function cubicInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","cubicOut"],"href":"/docs/svelte/svelte-easing#cubicOut","content":"function cubicOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","elasticIn"],"href":"/docs/svelte/svelte-easing#elasticIn","content":"function elasticIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","elasticInOut"],"href":"/docs/svelte/svelte-easing#elasticInOut","content":"function elasticInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","elasticOut"],"href":"/docs/svelte/svelte-easing#elasticOut","content":"function elasticOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","expoIn"],"href":"/docs/svelte/svelte-easing#expoIn","content":"function expoIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","expoInOut"],"href":"/docs/svelte/svelte-easing#expoInOut","content":"function expoInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","expoOut"],"href":"/docs/svelte/svelte-easing#expoOut","content":"function expoOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","linear"],"href":"/docs/svelte/svelte-easing#linear","content":"function linear(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quadIn"],"href":"/docs/svelte/svelte-easing#quadIn","content":"function quadIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quadInOut"],"href":"/docs/svelte/svelte-easing#quadInOut","content":"function quadInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quadOut"],"href":"/docs/svelte/svelte-easing#quadOut","content":"function quadOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quartIn"],"href":"/docs/svelte/svelte-easing#quartIn","content":"function quartIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quartInOut"],"href":"/docs/svelte/svelte-easing#quartInOut","content":"function quartInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quartOut"],"href":"/docs/svelte/svelte-easing#quartOut","content":"function quartOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quintIn"],"href":"/docs/svelte/svelte-easing#quintIn","content":"function quintIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quintInOut"],"href":"/docs/svelte/svelte-easing#quintInOut","content":"function quintInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","quintOut"],"href":"/docs/svelte/svelte-easing#quintOut","content":"function quintOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","sineIn"],"href":"/docs/svelte/svelte-easing#sineIn","content":"function sineIn(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","sineInOut"],"href":"/docs/svelte/svelte-easing#sineInOut","content":"function sineInOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/easing","sineOut"],"href":"/docs/svelte/svelte-easing#sineOut","content":"function sineOut(t: number): number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/events"],"href":"/docs/svelte/svelte-events","content":"import { on } from 'svelte/events';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/events","on"],"href":"/docs/svelte/svelte-events#on","content":"Attaches an event handler to the window and returns a function that removes the handler. Using this\nrather than addEventListener will preserve the correct order relative to handlers added declaratively\n(with attributes like onclick), which use event delegation for performance reasons\nfunction on<Type extends keyof WindowEventMap>(\n\twindow: Window,\n\ttype: Type,\n\thandler: (\n\t\tthis: Window,\n\t\tevent: WindowEventMap[Type] & { currentTarget: Window }\n\t) => any,\n\toptions?: AddEventListenerOptions | undefined\n): () => void;\n\nfunction on<Type extends keyof DocumentEventMap>(\n\tdocument: Document,\n\ttype: Type,\n\thandler: (\n\t\tthis: Document,\n\t\tevent: DocumentEventMap[Type] & {\n\t\t\tcurrentTarget: Document;\n\t\t}\n\t) => any,\n\toptions?: AddEventListenerOptions | undefined\n): () => void;\n\nfunction on<\n\tElement extends HTMLElement,\n\tType extends keyof HTMLElementEventMap\n>(\n\telement: Element,\n\ttype: Type,\n\thandler: (\n\t\tthis: Element,\n\t\tevent: HTMLElementEventMap[Type] & {\n\t\t\tcurrentTarget: Element;\n\t\t}\n\t) => any,\n\toptions?: AddEventListenerOptions | undefined\n): () => void;\n\nfunction on<\n\tElement extends MediaQueryList,\n\tType extends keyof MediaQueryListEventMap\n>(\n\telement: Element,\n\ttype: Type,\n\thandler: (\n\t\tthis: Element,\n\t\tevent: MediaQueryListEventMap[Type] & {\n\t\t\tcurrentTarget: Element;\n\t\t}\n\t) => any,\n\toptions?: AddEventListenerOptions | undefined\n): () => void;\n\nfunction on(\n\telement: EventTarget,\n\ttype: string,\n\thandler: EventListener,\n\toptions?: AddEventListenerOptions | undefined\n): () => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy"],"href":"/docs/svelte/svelte-legacy","content":"This module provides various functions for use during the migration, since some features can't be replaced one to one with new features. All imports are marked as deprecated and should be migrated away from over time. \nimport {\n\tasClassComponent,\n\tcreateBubbler,\n\tcreateClassComponent,\n\thandlers,\n\tnonpassive,\n\tonce,\n\tpassive,\n\tpreventDefault,\n\trun,\n\tself,\n\tstopImmediatePropagation,\n\tstopPropagation,\n\ttrusted\n} from 'svelte/legacy';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","asClassComponent"],"href":"/docs/svelte/svelte-legacy#asClassComponent","content":"Use this only as a temporary solution to migrate your imperative component code to Svelte 5.\nTakes the component function and returns a Svelte 4 compatible component constructor.\nfunction asClassComponent<\n\tProps extends Record<string, any>,\n\tExports extends Record<string, any>,\n\tEvents extends Record<string, any>,\n\tSlots extends Record<string, any>\n>(\n\tcomponent:\n\t\t| SvelteComponent<Props, Events, Slots>\n\t\t| Component<Props>\n): ComponentType<\n\tSvelteComponent<Props, Events, Slots> & Exports\n>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","createBubbler"],"href":"/docs/svelte/svelte-legacy#createBubbler","content":"Use this only as a temporary solution to migrate your automatically delegated events in Svelte 5.\nFunction to create a bubble function that mimic the behavior of on:click without handler available in svelte 4.\nfunction createBubbler(): (\n\ttype: string\n) => (event: Event) => boolean;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","createClassComponent"],"href":"/docs/svelte/svelte-legacy#createClassComponent","content":"Use this only as a temporary solution to migrate your imperative component code to Svelte 5.\nTakes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.\nfunction createClassComponent<\n\tProps extends Record<string, any>,\n\tExports extends Record<string, any>,\n\tEvents extends Record<string, any>,\n\tSlots extends Record<string, any>\n>(\n\toptions: ComponentConstructorOptions<Props> & {\n\t\tcomponent:\n\t\t\t| ComponentType<SvelteComponent<Props, Events, Slots>>\n\t\t\t| Component<Props>;\n\t}\n): SvelteComponent<Props, Events, Slots> & Exports;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","handlers"],"href":"/docs/svelte/svelte-legacy#handlers","content":"Function to mimic the multiple listeners available in svelte 4\nfunction handlers(\n\t...handlers: EventListener[]\n): EventListener;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","nonpassive"],"href":"/docs/svelte/svelte-legacy#nonpassive","content":"Substitute for the nonpassive event modifier, implemented as an action\nfunction nonpassive(\n\tnode: HTMLElement,\n\t[event, handler]: [\n\t\tevent: string,\n\t\thandler: () => EventListener\n\t]\n): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","once"],"href":"/docs/svelte/svelte-legacy#once","content":"Substitute for the once event modifier\nfunction once(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","passive"],"href":"/docs/svelte/svelte-legacy#passive","content":"Substitute for the passive event modifier, implemented as an action\nfunction passive(\n\tnode: HTMLElement,\n\t[event, handler]: [\n\t\tevent: string,\n\t\thandler: () => EventListener\n\t]\n): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","preventDefault"],"href":"/docs/svelte/svelte-legacy#preventDefault","content":"Substitute for the preventDefault event modifier\nfunction preventDefault(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","run"],"href":"/docs/svelte/svelte-legacy#run","content":"Use this only as a temporary solution to migrate your component code to Svelte 5.\nRuns the given function once immediately on the server, and works like $effect.pre on the client.\nfunction run(fn: () => void | (() => void)): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","self"],"href":"/docs/svelte/svelte-legacy#self","content":"Substitute for the self event modifier\nfunction self(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","stopImmediatePropagation"],"href":"/docs/svelte/svelte-legacy#stopImmediatePropagation","content":"Substitute for the stopImmediatePropagation event modifier\nfunction stopImmediatePropagation(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","stopPropagation"],"href":"/docs/svelte/svelte-legacy#stopPropagation","content":"Substitute for the stopPropagation event modifier\nfunction stopPropagation(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","trusted"],"href":"/docs/svelte/svelte-legacy#trusted","content":"Substitute for the trusted event modifier\nfunction trusted(\n\tfn: (event: Event, ...args: Array<unknown>) => void\n): (event: Event, ...args: unknown[]) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/legacy","LegacyComponentType"],"href":"/docs/svelte/svelte-legacy#LegacyComponentType","content":"Support using the component as both a class and function during the transition period\ntype LegacyComponentType = {\n\tnew (o: ComponentConstructorOptions): SvelteComponent;\n\t(\n\t\t...args: Parameters<Component<Record<string, any>>>\n\t): ReturnType<\n\t\tComponent<Record<string, any>, Record<string, any>>\n\t>;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion"],"href":"/docs/svelte/svelte-motion","content":"import {\n\tSpring,\n\tTween,\n\tprefersReducedMotion,\n\tspring,\n\ttweened\n} from 'svelte/motion';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","Spring"],"href":"/docs/svelte/svelte-motion#Spring","content":"Available since 5.8.0\nA wrapper for a value that behaves in a spring-like fashion. Changes to spring.target will cause spring.current to\nmove towards it over time, taking account of the spring.stiffness and spring.damping parameters.<script>\n\timport { Spring } from 'svelte/motion';\n\n\tconst spring = new Spring(0);\n</script>\n\n<input type=\"range\" bind:value={spring.target} />\n<input type=\"range\" bind:value={spring.current} disabled />\nclass Spring<T> {/*…*/}\nconstructor(value: T, options?: SpringOptions);\n\nstatic of<U>(fn: () => U, options?: SpringOptions): Spring<U>;\nCreate a spring whose value is bound to the return value of fn. This must be called\ninside an effect root (for example, during component initialisation).<script>\n\timport { Spring } from 'svelte/motion';\n\n\tlet { number } = $props();\n\n\tconst spring = Spring.of(() => number);\n</script>\n\nset(value: T, options?: SpringUpdateOptions): Promise<void>;\nSets spring.target to value and returns a Promise that resolves if and when spring.current catches up to it.If options.instant is true, spring.current immediately matches spring.target.If options.preserveMomentum is provided, the spring will continue on its current trajectory for\nthe specified number of milliseconds. This is useful for things like 'fling' gestures.\n\ndamping: number;\n\nprecision: number;\n\nstiffness: number;\n\ntarget: T;\nThe end value of the spring.\nThis property only exists on the Spring class, not the legacy spring store.\n\nget current(): T;\nThe current value of the spring.\nThis property only exists on the Spring class, not the legacy spring store.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","Tween"],"href":"/docs/svelte/svelte-motion#Tween","content":"Available since 5.8.0\nA wrapper for a value that tweens smoothly to its target value. Changes to tween.target will cause tween.current to\nmove towards it over time, taking account of the delay, duration and easing options.<script>\n\timport { Tween } from 'svelte/motion';\n\n\tconst tween = new Tween(0);\n</script>\n\n<input type=\"range\" bind:value={tween.target} />\n<input type=\"range\" bind:value={tween.current} disabled />\nclass Tween<T> {/*…*/}\nstatic of<U>(fn: () => U, options?: TweenOptions<U> | undefined): Tween<U>;\nCreate a tween whose value is bound to the return value of fn. This must be called\ninside an effect root (for example, during component initialisation).<script>\n\timport { Tween } from 'svelte/motion';\n\n\tlet { number } = $props();\n\n\tconst tween = Tween.of(() => number);\n</script>\n\nconstructor(value: T, options?: TweenOptions<T>);\n\nset(value: T, options?: TweenOptions<T> | undefined): Promise<void>;\nSets tween.target to value and returns a Promise that resolves if and when tween.current catches up to it.If options are provided, they will override the tween's defaults.\n\nget current(): T;\n\nset target(v: T);\n\nget target(): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","prefersReducedMotion"],"href":"/docs/svelte/svelte-motion#prefersReducedMotion","content":"Available since 5.7.0\nA media query that matches if the user prefers reduced motion.<script>\n\timport { prefersReducedMotion } from 'svelte/motion';\n\timport { fly } from 'svelte/transition';\n\n\tlet visible = $state(false);\n</script>\n\n<button onclick={() => visible = !visible}>\n\ttoggle\n</button>\n\n{#if visible}\n\t<p transition:fly={{ y: prefersReducedMotion.current ? 0 : 200 }}>\n\t\tflies in, unless the user prefers reduced motion\n\t</p>\n{/if}\nconst prefersReducedMotion: MediaQuery;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","spring"],"href":"/docs/svelte/svelte-motion#spring","content":"Use `Spring` instead\nThe spring function in Svelte creates a store whose value is animated, with a motion that simulates the behavior of a spring. This means when the value changes, instead of transitioning at a steady rate, it \"bounces\" like a spring would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user experience.\nfunction spring<T = any>(\n\tvalue?: T | undefined,\n\topts?: SpringOptions | undefined\n): Spring<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","tweened"],"href":"/docs/svelte/svelte-motion#tweened","content":"Use `Tween` instead\nA tweened store in Svelte is a special type of store that provides smooth transitions between state values over time.\nfunction tweened<T>(\n\tvalue?: T | undefined,\n\tdefaults?: TweenOptions<T> | undefined\n): Tweened<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","Spring"],"href":"/docs/svelte/svelte-motion#Spring","content":"interface Spring<T> extends Readable<T> {/*…*/}\nset(new_value: T, opts?: SpringUpdateOptions): Promise<void>;\n\nupdate: (fn: Updater<T>, opts?: SpringUpdateOptions) => Promise<void>;\n\n<span class=\"tag deprecated\">deprecated</span> Only exists on the legacy `spring` store, not the `Spring` class\n\n\nsubscribe(fn: (value: T) => void): Unsubscriber;\n\n<span class=\"tag deprecated\">deprecated</span> Only exists on the legacy `spring` store, not the `Spring` class\n\n\nprecision: number;\n\ndamping: number;\n\nstiffness: number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","SpringOptions"],"href":"/docs/svelte/svelte-motion#SpringOptions","content":"interface SpringOptions {/*…*/}\nstiffness?: number;\n\ndamping?: number;\n\nprecision?: number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","SpringUpdateOptions"],"href":"/docs/svelte/svelte-motion#SpringUpdateOptions","content":"interface SpringUpdateOptions {/*…*/}\nhard?: any;\n\n<span class=\"tag deprecated\">deprecated</span> Only use this for the spring store; does nothing when set on the Spring class\n\n\nsoft?: string | number | boolean;\n\n<span class=\"tag deprecated\">deprecated</span> Only use this for the spring store; does nothing when set on the Spring class\n\n\ninstant?: boolean;\nOnly use this for the Spring class; does nothing when set on the spring store\n\npreserveMomentum?: number;\nOnly use this for the Spring class; does nothing when set on the spring store","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","TweenOptions"],"href":"/docs/svelte/svelte-motion#TweenOptions","content":"interface TweenOptions<T> {/*…*/}\ndelay?: number;\n\nduration?: number | ((from: T, to: T) => number);\n\neasing?: (t: number) => number;\n\ninterpolate?: (a: T, b: T) => (t: number) => T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","Tweened"],"href":"/docs/svelte/svelte-motion#Tweened","content":"interface Tweened<T> extends Readable<T> {/*…*/}\nset(value: T, opts?: TweenOptions<T>): Promise<void>;\n\nupdate(updater: Updater<T>, opts?: TweenOptions<T>): Promise<void>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/motion","Updater"],"href":"/docs/svelte/svelte-motion#Updater","content":"type Updater<T> = (target_value: T, value: T) => T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window"],"href":"/docs/svelte/svelte-reactivity-window","content":"This module exports reactive versions of various window values, each of which has a reactive current property that you can reference in reactive contexts (templates, deriveds and effects) without using `<svelte:window>` bindings or manually creating your own event listeners.<script>\n\timport { innerWidth, innerHeight } from 'svelte/reactivity/window';\n</script>\n\n<p>{innerWidth.current}x{innerHeight.current}</p> \nimport {\n\tdevicePixelRatio,\n\tinnerHeight,\n\tinnerWidth,\n\tonline,\n\touterHeight,\n\touterWidth,\n\tscreenLeft,\n\tscreenTop,\n\tscrollX,\n\tscrollY\n} from 'svelte/reactivity/window';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","devicePixelRatio"],"href":"/docs/svelte/svelte-reactivity-window#devicePixelRatio","content":"Available since 5.11.0\ndevicePixelRatio.current is a reactive view of window.devicePixelRatio. On the server it is undefined.\nNote that behaviour differs between browsers — on Chrome it will respond to the current zoom level,\non Firefox and Safari it won't.\nconst devicePixelRatio: {\n\tget current(): number | undefined;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","innerHeight"],"href":"/docs/svelte/svelte-reactivity-window#innerHeight","content":"Available since 5.11.0\ninnerHeight.current is a reactive view of window.innerHeight. On the server it is undefined.\nconst innerHeight: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","innerWidth"],"href":"/docs/svelte/svelte-reactivity-window#innerWidth","content":"Available since 5.11.0\ninnerWidth.current is a reactive view of window.innerWidth. On the server it is undefined.\nconst innerWidth: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","online"],"href":"/docs/svelte/svelte-reactivity-window#online","content":"Available since 5.11.0\nonline.current is a reactive view of navigator.onLine. On the server it is undefined.\nconst online: ReactiveValue<boolean | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","outerHeight"],"href":"/docs/svelte/svelte-reactivity-window#outerHeight","content":"Available since 5.11.0\nouterHeight.current is a reactive view of window.outerHeight. On the server it is undefined.\nconst outerHeight: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","outerWidth"],"href":"/docs/svelte/svelte-reactivity-window#outerWidth","content":"Available since 5.11.0\nouterWidth.current is a reactive view of window.outerWidth. On the server it is undefined.\nconst outerWidth: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","screenLeft"],"href":"/docs/svelte/svelte-reactivity-window#screenLeft","content":"Available since 5.11.0\nscreenLeft.current is a reactive view of window.screenLeft. It is updated inside a requestAnimationFrame callback. On the server it is undefined.\nconst screenLeft: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","screenTop"],"href":"/docs/svelte/svelte-reactivity-window#screenTop","content":"Available since 5.11.0\nscreenTop.current is a reactive view of window.screenTop. It is updated inside a requestAnimationFrame callback. On the server it is undefined.\nconst screenTop: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","scrollX"],"href":"/docs/svelte/svelte-reactivity-window#scrollX","content":"Available since 5.11.0\nscrollX.current is a reactive view of window.scrollX. On the server it is undefined.\nconst scrollX: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity/window","scrollY"],"href":"/docs/svelte/svelte-reactivity-window#scrollY","content":"Available since 5.11.0\nscrollY.current is a reactive view of window.scrollY. On the server it is undefined.\nconst scrollY: ReactiveValue<number | undefined>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity"],"href":"/docs/svelte/svelte-reactivity","content":"Svelte provides reactive versions of various built-ins like `Map`, `Set` and `URL` that can be used just like their native counterparts, as well as a handful of additional utilities for handling reactivity. \nimport {\n\tMediaQuery,\n\tSvelteDate,\n\tSvelteMap,\n\tSvelteSet,\n\tSvelteURL,\n\tSvelteURLSearchParams,\n\tcreateSubscriber\n} from 'svelte/reactivity';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","MediaQuery"],"href":"/docs/svelte/svelte-reactivity#MediaQuery","content":"Available since 5.7.0\nCreates a media query and provides a current property that reflects whether or not it matches.Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration.\nIf you can use the media query in CSS to achieve the same effect, do that.<script>\n\timport { MediaQuery } from 'svelte/reactivity';\n\n\tconst large = new MediaQuery('min-width: 800px');\n</script>\n\n<h1>{large.current ? 'large screen' : 'small screen'}</h1>\nclass MediaQuery extends ReactiveValue<boolean> {/*…*/}\nconstructor(query: string, fallback?: boolean | undefined);\n\n`query` A media query string\n`fallback` Fallback value for the server","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","SvelteDate"],"href":"/docs/svelte/svelte-reactivity#SvelteDate","content":"A reactive version of the built-in `Date` object.\nReading the date (whether with methods like date.getTime() or date.toString(), or via things like `Intl.DateTimeFormat`)\nin an effect or derived\nwill cause it to be re-evaluated when the value of the date changes.<script>\n\timport { SvelteDate } from 'svelte/reactivity';\n\n\tconst date = new SvelteDate();\n\n\tconst formatter = new Intl.DateTimeFormat(undefined, {\n\t  hour: 'numeric',\n\t  minute: 'numeric',\n\t  second: 'numeric'\n\t});\n\n\t$effect(() => {\n\t\tconst interval = setInterval(() => {\n\t\t\tdate.setTime(Date.now());\n\t\t}, 1000);\n\n\t\treturn () => {\n\t\t\tclearInterval(interval);\n\t\t};\n\t});\n</script>\n\n<p>The time is {formatter.format(date)}</p>\nclass SvelteDate extends Date {/*…*/}\nconstructor(...params: any[]);","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","SvelteMap"],"href":"/docs/svelte/svelte-reactivity#SvelteMap","content":"A reactive version of the built-in `Map` object.\nReading contents of the map (by iterating, or by reading map.size or calling map.get(...) or map.has(...) as in the tic-tac-toe example below) in an effect or derived\nwill cause it to be re-evaluated as necessary when the map is updated.Note that values in a reactive map are not made deeply reactive.<script>\n\timport { SvelteMap } from 'svelte/reactivity';\n\timport { result } from './game.js';\n\n\tlet board = new SvelteMap();\n\tlet player = $state('x');\n\tlet winner = $derived(result(board));\n\n\tfunction reset() {\n\t\tplayer = 'x';\n\t\tboard.clear();\n\t}\n</script>\n\n<div class=\"board\">\n\t{#each Array(9), i}\n\t\t<button\n\t\t\tdisabled={board.has(i) || winner}\n\t\t\tonclick={() => {\n\t\t\t\tboard.set(i, player);\n\t\t\t\tplayer = player === 'x' ? 'o' : 'x';\n\t\t\t}}\n\t\t>{board.get(i)}</button>\n\t{/each}\n</div>\n\n{#if winner}\n\t<p>{winner} wins!</p>\n\t<button onclick={reset}>reset</button>\n{:else}\n\t<p>{player} is next</p>\n{/if}\nclass SvelteMap<K, V> extends Map<K, V> {/*…*/}\nconstructor(value?: Iterable<readonly [K, V]> | null | undefined);\n\nset(key: K, value: V): this;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","SvelteSet"],"href":"/docs/svelte/svelte-reactivity#SvelteSet","content":"A reactive version of the built-in `Set` object.\nReading contents of the set (by iterating, or by reading set.size or calling set.has(...) as in the example below) in an effect or derived\nwill cause it to be re-evaluated as necessary when the set is updated.Note that values in a reactive set are not made deeply reactive.<script>\n\timport { SvelteSet } from 'svelte/reactivity';\n\tlet monkeys = new SvelteSet();\n\n\tfunction toggle(monkey) {\n\t\tif (monkeys.has(monkey)) {\n\t\t\tmonkeys.delete(monkey);\n\t\t} else {\n\t\t\tmonkeys.add(monkey);\n\t\t}\n\t}\n</script>\n\n{#each ['🙈', '🙉', '🙊'] as monkey}\n\t<button onclick={() => toggle(monkey)}>{monkey}</button>\n{/each}\n\n<button onclick={() => monkeys.clear()}>clear</button>\n\n{#if monkeys.has('🙈')}<p>see no evil</p>{/if}\n{#if monkeys.has('🙉')}<p>hear no evil</p>{/if}\n{#if monkeys.has('🙊')}<p>speak no evil</p>{/if}\nclass SvelteSet<T> extends Set<T> {/*…*/}\nconstructor(value?: Iterable<T> | null | undefined);\n\nadd(value: T): this;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","SvelteURL"],"href":"/docs/svelte/svelte-reactivity#SvelteURL","content":"A reactive version of the built-in `URL` object.\nReading properties of the URL (such as url.href or url.pathname) in an effect or derived\nwill cause it to be re-evaluated as necessary when the URL changes.The searchParams property is an instance of SvelteURLSearchParams.Example:<script>\n\timport { SvelteURL } from 'svelte/reactivity';\n\n\tconst url = new SvelteURL('https://example.com/path');\n</script>\n\n<!-- changes to these... -->\n<input bind:value={url.protocol} />\n<input bind:value={url.hostname} />\n<input bind:value={url.pathname} />\n\n<hr />\n\n<!-- will update `href` and vice versa -->\n<input bind:value={url.href} size=\"65\" />\nclass SvelteURL extends URL {/*…*/}\nget searchParams(): SvelteURLSearchParams;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","SvelteURLSearchParams"],"href":"/docs/svelte/svelte-reactivity#SvelteURLSearchParams","content":"A reactive version of the built-in `URLSearchParams` object.\nReading its contents (by iterating, or by calling params.get(...) or params.getAll(...) as in the example below) in an effect or derived\nwill cause it to be re-evaluated as necessary when the params are updated.<script>\n\timport { SvelteURLSearchParams } from 'svelte/reactivity';\n\n\tconst params = new SvelteURLSearchParams('message=hello');\n\n\tlet key = $state('key');\n\tlet value = $state('value');\n</script>\n\n<input bind:value={key} />\n<input bind:value={value} />\n<button onclick={() => params.append(key, value)}>append</button>\n\n<p>?{params.toString()}</p>\n\n{#each params as [key, value]}\n\t<p>{key}: {value}</p>\n{/each}\nclass SvelteURLSearchParams extends URLSearchParams {/*…*/}\n[REPLACE](params: URLSearchParams): void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/reactivity","createSubscriber"],"href":"/docs/svelte/svelte-reactivity#createSubscriber","content":"Available since 5.7.0\nReturns a subscribe function that integrates external event-based systems with Svelte's reactivity.\nIt's particularly useful for integrating with web APIs like MediaQuery, IntersectionObserver, or WebSocket.If subscribe is called inside an effect (including indirectly, for example inside a getter),\nthe start callback will be called with an update function. Whenever update is called, the effect re-runs.If start returns a cleanup function, it will be called when the effect is destroyed.If subscribe is called in multiple effects, start will only be called once as long as the effects\nare active, and the returned teardown function will only be called when all effects are destroyed.It's best understood with an example. Here's an implementation of `MediaQuery`: \nimport { createSubscriber } from 'svelte/reactivity';\nimport { on } from 'svelte/events';\n\nexport class MediaQuery {\n\t#query;\n\t#subscribe;\n\n\tconstructor(query) {\n\t\tthis.#query = window.matchMedia(`(${query})`);\n\n\t\tthis.#subscribe = createSubscriber((update) => {\n\t\t\t// when the `change` event occurs, re-run any effects that read `this.current`\n\t\t\tconst off = on(this.#query, 'change', update);\n\n\t\t\t// stop listening when all the effects are destroyed\n\t\t\treturn () => off();\n\t\t});\n\t}\n\n\tget current() {\n\t\t// This makes the getter reactive, if read in an effect\n\t\tthis.#subscribe();\n\n\t\t// Return the current state of the query, whether or not we're in an effect\n\t\treturn this.#query.matches;\n\t}\n}\nfunction createSubscriber(\n\tstart: (update: () => void) => (() => void) | void\n): () => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/server"],"href":"/docs/svelte/svelte-server","content":"import { render } from 'svelte/server';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/server","render"],"href":"/docs/svelte/svelte-server#render","content":"Only available on the server and when compiling with the server option.\nTakes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.\nfunction render<\n\tComp extends SvelteComponent<any> | Component<any>,\n\tProps extends ComponentProps<Comp> = ComponentProps<Comp>\n>(\n\t...args: {} extends Props\n\t\t? [\n\t\t\t\tcomponent: Comp extends SvelteComponent<any>\n\t\t\t\t\t? ComponentType<Comp>\n\t\t\t\t\t: Comp,\n\t\t\t\toptions?: {\n\t\t\t\t\tprops?: Omit<Props, '$$slots' | '$$events'>;\n\t\t\t\t\tcontext?: Map<any, any>;\n\t\t\t\t\tidPrefix?: string;\n\t\t\t\t\tcsp?: Csp;\n\t\t\t\t\ttransformError?: (\n\t\t\t\t\t\terror: unknown\n\t\t\t\t\t) => unknown | Promise<unknown>;\n\t\t\t\t}\n\t\t\t]\n\t\t: [\n\t\t\t\tcomponent: Comp extends SvelteComponent<any>\n\t\t\t\t\t? ComponentType<Comp>\n\t\t\t\t\t: Comp,\n\t\t\t\toptions: {\n\t\t\t\t\tprops: Omit<Props, '$$slots' | '$$events'>;\n\t\t\t\t\tcontext?: Map<any, any>;\n\t\t\t\t\tidPrefix?: string;\n\t\t\t\t\tcsp?: Csp;\n\t\t\t\t\ttransformError?: (\n\t\t\t\t\t\terror: unknown\n\t\t\t\t\t) => unknown | Promise<unknown>;\n\t\t\t\t}\n\t\t\t]\n): RenderOutput;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store"],"href":"/docs/svelte/svelte-store","content":"import {\n\tderived,\n\tfromStore,\n\tget,\n\treadable,\n\treadonly,\n\ttoStore,\n\twritable\n} from 'svelte/store';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","derived"],"href":"/docs/svelte/svelte-store#derived","content":"Derived value store by synchronizing one or more readable stores and\napplying an aggregation function over its input values.\nfunction derived<S extends Stores, T>(\n\tstores: S,\n\tfn: (\n\t\tvalues: StoresValues<S>,\n\t\tset: (value: T) => void,\n\t\tupdate: (fn: Updater<T>) => void\n\t) => Unsubscriber | void,\n\tinitial_value?: T | undefined\n): Readable<T>;\n\nfunction derived<S extends Stores, T>(\n\tstores: S,\n\tfn: (values: StoresValues<S>) => T,\n\tinitial_value?: T | undefined\n): Readable<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","fromStore"],"href":"/docs/svelte/svelte-store#fromStore","content":"function fromStore<V>(store: Writable<V>): {\n\tcurrent: V;\n};\n\nfunction fromStore<V>(store: Readable<V>): {\n\treadonly current: V;\n};","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","get"],"href":"/docs/svelte/svelte-store#get","content":"Get the current value from a store by subscribing and immediately unsubscribing.\nfunction get<T>(store: Readable<T>): T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","readable"],"href":"/docs/svelte/svelte-store#readable","content":"Creates a Readable store that allows reading by subscription.\nfunction readable<T>(\n\tvalue?: T | undefined,\n\tstart?: StartStopNotifier<T> | undefined\n): Readable<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","readonly"],"href":"/docs/svelte/svelte-store#readonly","content":"Takes a store and returns a new one derived from the old one that is readable.\nfunction readonly<T>(store: Readable<T>): Readable<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","toStore"],"href":"/docs/svelte/svelte-store#toStore","content":"function toStore<V>(\n\tget: () => V,\n\tset: (v: V) => void\n): Writable<V>;\n\nfunction toStore<V>(get: () => V): Readable<V>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","writable"],"href":"/docs/svelte/svelte-store#writable","content":"Create a Writable store that allows both updating and reading by subscription.\nfunction writable<T>(\n\tvalue?: T | undefined,\n\tstart?: StartStopNotifier<T> | undefined\n): Writable<T>;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","Readable"],"href":"/docs/svelte/svelte-store#Readable","content":"Readable interface for subscribing.\ninterface Readable<T> {/*…*/}\nsubscribe(this: void, run: Subscriber<T>, invalidate?: () => void): Unsubscriber;\n\n`run` subscription callback\n`invalidate` cleanup callback\nSubscribe on value changes.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","StartStopNotifier"],"href":"/docs/svelte/svelte-store#StartStopNotifier","content":"Start and stop notification callbacks.\nThis function is called when the first subscriber subscribes.\ntype StartStopNotifier<T> = (\n\tset: (value: T) => void,\n\tupdate: (fn: Updater<T>) => void\n) => void | (() => void);","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","Subscriber"],"href":"/docs/svelte/svelte-store#Subscriber","content":"Callback to inform of a value updates.\ntype Subscriber<T> = (value: T) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","Unsubscriber"],"href":"/docs/svelte/svelte-store#Unsubscriber","content":"Unsubscribes from value updates.\ntype Unsubscriber = () => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","Updater"],"href":"/docs/svelte/svelte-store#Updater","content":"Callback to update a value.\ntype Updater<T> = (value: T) => T;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/store","Writable"],"href":"/docs/svelte/svelte-store#Writable","content":"Writable interface for both updating and subscribing.\ninterface Writable<T> extends Readable<T> {/*…*/}\nset(this: void, value: T): void;\n\n`value` to set\nSet value and inform subscribers.\n\nupdate(this: void, updater: Updater<T>): void;\n\n`updater` callback\nUpdate value using callback and inform subscribers.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition"],"href":"/docs/svelte/svelte-transition","content":"import {\n\tblur,\n\tcrossfade,\n\tdraw,\n\tfade,\n\tfly,\n\tscale,\n\tslide\n} from 'svelte/transition';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","blur"],"href":"/docs/svelte/svelte-transition#blur","content":"Animates a blur filter alongside an element's opacity.\nfunction blur(\n\tnode: Element,\n\t{\n\t\tdelay,\n\t\tduration,\n\t\teasing,\n\t\tamount,\n\t\topacity\n\t}?: BlurParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","crossfade"],"href":"/docs/svelte/svelte-transition#crossfade","content":"The crossfade function creates a pair of transitions called send and receive. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the fallback transition is used.\nfunction crossfade({\n\tfallback,\n\t...defaults\n}: CrossfadeParams & {\n\tfallback?: (\n\t\tnode: Element,\n\t\tparams: CrossfadeParams,\n\t\tintro: boolean\n\t) => TransitionConfig;\n}): [\n\t(\n\t\tnode: any,\n\t\tparams: CrossfadeParams & {\n\t\t\tkey: any;\n\t\t}\n\t) => () => TransitionConfig,\n\t(\n\t\tnode: any,\n\t\tparams: CrossfadeParams & {\n\t\t\tkey: any;\n\t\t}\n\t) => () => TransitionConfig\n];","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","draw"],"href":"/docs/svelte/svelte-transition#draw","content":"Animates the stroke of an SVG element, like a snake in a tube. in transitions begin with the path invisible and draw the path to the screen over time. out transitions start in a visible state and gradually erase the path. draw only works with elements that have a getTotalLength method, like <path> and <polyline>.\nfunction draw(\n\tnode: SVGElement & {\n\t\tgetTotalLength(): number;\n\t},\n\t{\n\t\tdelay,\n\t\tspeed,\n\t\tduration,\n\t\teasing\n\t}?: DrawParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","fade"],"href":"/docs/svelte/svelte-transition#fade","content":"Animates the opacity of an element from 0 to the current opacity for in transitions and from the current opacity to 0 for out transitions.\nfunction fade(\n\tnode: Element,\n\t{ delay, duration, easing }?: FadeParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","fly"],"href":"/docs/svelte/svelte-transition#fly","content":"Animates the x and y positions and the opacity of an element. in transitions animate from the provided values, passed as parameters to the element's default values. out transitions animate from the element's default values to the provided values.\nfunction fly(\n\tnode: Element,\n\t{\n\t\tdelay,\n\t\tduration,\n\t\teasing,\n\t\tx,\n\t\ty,\n\t\topacity\n\t}?: FlyParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","scale"],"href":"/docs/svelte/svelte-transition#scale","content":"Animates the opacity and scale of an element. in transitions animate from the provided values, passed as parameters, to an element's current (default) values. out transitions animate from an element's default values to the provided values.\nfunction scale(\n\tnode: Element,\n\t{\n\t\tdelay,\n\t\tduration,\n\t\teasing,\n\t\tstart,\n\t\topacity\n\t}?: ScaleParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","slide"],"href":"/docs/svelte/svelte-transition#slide","content":"Slides an element in and out.\nfunction slide(\n\tnode: Element,\n\t{\n\t\tdelay,\n\t\tduration,\n\t\teasing,\n\t\taxis\n\t}?: SlideParams | undefined\n): TransitionConfig;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","BlurParams"],"href":"/docs/svelte/svelte-transition#BlurParams","content":"interface BlurParams {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;\n\namount?: number | string;\n\nopacity?: number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","CrossfadeParams"],"href":"/docs/svelte/svelte-transition#CrossfadeParams","content":"interface CrossfadeParams {/*…*/}\ndelay?: number;\n\nduration?: number | ((len: number) => number);\n\neasing?: EasingFunction;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","DrawParams"],"href":"/docs/svelte/svelte-transition#DrawParams","content":"interface DrawParams {/*…*/}\ndelay?: number;\n\nspeed?: number;\n\nduration?: number | ((len: number) => number);\n\neasing?: EasingFunction;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","EasingFunction"],"href":"/docs/svelte/svelte-transition#EasingFunction","content":"type EasingFunction = (t: number) => number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","FadeParams"],"href":"/docs/svelte/svelte-transition#FadeParams","content":"interface FadeParams {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","FlyParams"],"href":"/docs/svelte/svelte-transition#FlyParams","content":"interface FlyParams {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;\n\nx?: number | string;\n\ny?: number | string;\n\nopacity?: number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","ScaleParams"],"href":"/docs/svelte/svelte-transition#ScaleParams","content":"interface ScaleParams {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;\n\nstart?: number;\n\nopacity?: number;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","SlideParams"],"href":"/docs/svelte/svelte-transition#SlideParams","content":"interface SlideParams {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;\n\naxis?: 'x' | 'y';","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","svelte/transition","TransitionConfig"],"href":"/docs/svelte/svelte-transition#TransitionConfig","content":"interface TransitionConfig {/*…*/}\ndelay?: number;\n\nduration?: number;\n\neasing?: EasingFunction;\n\ncss?: (t: number, u: number) => string;\n\ntick?: (t: number, u: number) => void;","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Compiler errors"],"href":"/docs/svelte/compiler-errors","content":"animation_duplicate\nAn element can only have one 'animate' directiveanimation_invalid_placement\nAn element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` blockanimation_missing_key\nAn element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block. Did you forget to add a key to your each block?attribute_contenteditable_dynamic\n'contenteditable' attribute cannot be dynamic if element uses two-way bindingattribute_contenteditable_missing\n'contenteditable' attribute is required for textContent, innerHTML and innerText two-way bindingsattribute_duplicate\nAttributes need to be uniqueattribute_empty_shorthand\nAttribute shorthand cannot be emptyattribute_invalid_event_handler\nEvent attribute must be a JavaScript expression, not a stringattribute_invalid_multiple\n'multiple' attribute must be static if select uses two-way bindingattribute_invalid_name\n'%name%' is not a valid attribute nameattribute_invalid_sequence_expression\nComma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parenthesesAn attribute value cannot be a comma-separated sequence of expressions — in other words this is disallowed:<div class={size, color}>...</div>Instead, make sure that the attribute value contains a single expression. In the example above it's likely that this was intended (see the class documentation for more details):<div class={[size, color]}>...</div>If you do need to use the comma operator for some reason, wrap the sequence in parentheses:<div class={(size, color)}>...</div>Note that this will evaluate to color, ignoring size.attribute_invalid_type\n'type' attribute must be a static text value if input uses two-way bindingattribute_unquoted_sequence\nAttribute values containing `{...}` must be enclosed in quote marks, unless the value only contains the expressionbind_group_invalid_expression\n`bind:group` can only bind to an Identifier or MemberExpressionbind_group_invalid_snippet_parameter\nCannot `bind:group` to a snippet parameterbind_invalid_expression\nCan only bind to an Identifier or MemberExpression or a `{get, set}` pairbind_invalid_name\n`bind:%name%` is not a valid binding`bind:%name%` is not a valid binding. %explanation%bind_invalid_parens\n`bind:%name%={get, set}` must not have surrounding parenthesesbind_invalid_target\n`bind:%name%` can only be used with %elements%bind_invalid_value\nCan only bind to state or propsbindable_invalid_location\n`$bindable()` can only be used inside a `$props()` declarationblock_duplicate_clause\n%name% cannot appear more than once within a blockblock_invalid_continuation_placement\n{:...} block is invalid at this position (did you forget to close the preceding element or block?)block_invalid_elseif\n'elseif' should be 'else if'block_invalid_placement\n{#%name% ...} block cannot be %location%block_unclosed\nBlock was left openblock_unexpected_character\nExpected a `%character%` character immediately following the opening bracketblock_unexpected_close\nUnexpected block closing tagcomponent_invalid_directive\nThis type of directive is not valid on componentsconst_tag_cycle\nCyclical dependency detected: %cycle%const_tag_invalid_expression\n{@const ...} must consist of a single variable declarationconst_tag_invalid_placement\n`{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, `<svelte:fragment>`, `<svelte:boundary>` or `<Component>`const_tag_invalid_reference\nThe `{@const %name% = ...}` declaration is not available in this snippetThe following is an error:<svelte:boundary>\n    {@const foo = 'bar'}\n\n    {#snippet failed()}\n        {foo}\n    {/snippet}\n</svelte:boundary>Here, foo is not available inside failed. The top level code inside <svelte:boundary> becomes part of the implicit children snippet, in other words the above code is equivalent to this:<svelte:boundary>\n    {#snippet children()}\n        {@const foo = 'bar'}\n    {/snippet}\n\n    {#snippet failed()}\n        {foo}\n    {/snippet}\n</svelte:boundary>The same applies to components:<Component>\n    {@const foo = 'bar'}\n\n    {#snippet someProp()}\n        <!-- error -->\n        {foo}\n    {/snippet}\n</Component>constant_assignment\nCannot assign to %thing%constant_binding\nCannot bind to %thing%css_empty_declaration\nDeclaration cannot be emptycss_expected_identifier\nExpected a valid CSS identifiercss_global_block_invalid_combinator\nA `:global` selector cannot follow a `%name%` combinatorcss_global_block_invalid_declaration\nA top-level `:global {...}` block can only contain rules, not declarationscss_global_block_invalid_list\nA `:global` selector cannot be part of a selector list with entries that don't contain `:global`The following CSS is invalid::global, x {\n    y {\n        color: red;\n    }\n}This is mixing a :global block, which means \"everything in here is unscoped\", with a scoped selector (x in this case). As a result it's not possible to transform the inner selector (y in this case) into something that satisfies both requirements. You therefore have to split this up into two selectors::global {\n    y {\n        color: red;\n    }\n}\n\nx y {\n    color: red;\n}css_global_block_invalid_modifier\nA `:global` selector cannot modify an existing selectorcss_global_block_invalid_modifier_start\nA `:global` selector can only be modified if it is a descendant of other selectorscss_global_block_invalid_placement\nA `:global` selector cannot be inside a pseudoclasscss_global_invalid_placement\n`:global(...)` can be at the start or end of a selector sequence, but not in the middlecss_global_invalid_selector\n`:global(...)` must contain exactly one selectorcss_global_invalid_selector_list\n`:global(...)` must not contain type or universal selectors when used in a compound selectorcss_nesting_selector_invalid_placement\nNesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`css_selector_invalid\nInvalid selectorcss_type_selector_invalid_placement\n`:global(...)` must not be followed by a type selectordebug_tag_invalid_arguments\n{@debug ...} arguments must be identifiers, not arbitrary expressionsdeclaration_duplicate\n`%name%` has already been declareddeclaration_duplicate_module_import\nCannot declare a variable with the same name as an import from `<script module>`declaration_tag_invalid_type\nDeclaration tags must be `let` or `const` declarationsdeclaration_tag_no_legacy_mode\nDeclaration tags cannot be used in legacy modederived_invalid_export\nCannot export derived state from a module. To expose the current derived value, export a function returning its valuedirective_invalid_value\nDirective value must be a JavaScript expression enclosed in curly bracesdirective_missing_name\n`%type%` name cannot be emptydollar_binding_invalid\nThe $ name is reserved, and cannot be used for variables and importsdollar_prefix_invalid\nThe $ prefix is reserved, and cannot be used for variables and importsduplicate_class_field\n`%name%` has already been declaredeach_item_invalid_assignment\nCannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. `array[i] = value` instead of `entry = value`, or `bind:value={array[i]}` instead of `bind:value={entry}`)In legacy mode, it was possible to reassign or bind to the each block argument itself:<script>\n\tlet array = [1, 2, 3];\n</script>\n\n{#each array as entry}\n\t<!-- reassignment -->\n\t<button on:click={() => entry = 4}>change</button>\n\n\t<!-- binding -->\n\t<input bind:value={entry}>\n{/each}This turned out to be buggy and unpredictable, particularly when working with derived values (such as array.map(...)), and as such is forbidden in runes mode. You can achieve the same outcome by using the index instead:<script>\n\tlet array = $state([1, 2, 3]);\n</script>\n\n{#each array as entry, i}\n\t<!-- reassignment -->\n\t<button onclick={() => array[i] = 4}>change</button>\n\n\t<!-- binding -->\n\t<input bind:value={array[i]}>\n{/each}each_key_without_as\nAn `{#each ...}` block without an `as` clause cannot have a keyeffect_invalid_placement\n`$effect()` can only be used as an expression statementelement_invalid_closing_tag\n`</%name%>` attempted to close an element that was not openelement_invalid_closing_tag_autoclosed\n`</%name%>` attempted to close element that was already automatically closed by `<%reason%>` (cannot nest `<%reason%>` inside `<%name%>`)element_unclosed\n`<%name%>` was left openevent_handler_invalid_component_modifier\nEvent modifiers other than 'once' can only be used on DOM elementsevent_handler_invalid_modifier\nValid event modifiers are %list%event_handler_invalid_modifier_combination\nThe '%modifier1%' and '%modifier2%' modifiers cannot be used togetherexpected_attribute_value\nExpected attribute valueexpected_block_type\nExpected 'if', 'each', 'await', 'key' or 'snippet'expected_identifier\nExpected an identifierexpected_pattern\nExpected identifier or destructure patternexpected_tag\nExpected 'html', 'render', 'attach', 'const', or 'debug'expected_token\nExpected token %token%expected_whitespace\nExpected whitespaceexperimental_async\nCannot use `await` in deriveds and template expressions, or at the top level of a component, unless the `experimental.async` compiler option is `true`export_undefined\n`%name%` is not definedglobal_reference_invalid\n`%name%` is an illegal variable name. To reference a global variable called `%name%`, use `globalThis.%name%`host_invalid_placement\n`$host()` can only be used inside custom element component instancesillegal_await_expression\n`use:`, `transition:` and `animate:` directives, attachments and bindings do not support await expressionsillegal_element_attribute\n`<%name%>` does not support non-event attributes or spread attributesimport_svelte_internal_forbidden\nImports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use caseinspect_trace_generator\n`$inspect.trace(...)` cannot be used inside a generator functioninspect_trace_invalid_placement\n`$inspect.trace(...)` must be the first statement of a function bodyinvalid_arguments_usage\nThe arguments keyword cannot be used within the template or at the top level of a componentjs_parse_error\n%message%legacy_await_invalid\nCannot use `await` in deriveds and template expressions, or at the top level of a component, unless in runes modelegacy_export_invalid\nCannot use `export let` in runes mode — use `$props()` insteadlegacy_props_invalid\nCannot use `$$props` in runes modelegacy_reactive_statement_invalid\n`$:` is not allowed in runes mode, use `$derived` or `$effect` insteadlegacy_rest_props_invalid\nCannot use `$$restProps` in runes modelet_directive_invalid_placement\n`let:` directive at invalid positionmixed_event_handler_syntaxes\nMixing old (on:%name%) and new syntaxes for event handling is not allowed. Use only the on%name% syntaxmodule_illegal_default_export\nA component cannot have a default exportnode_invalid_placement\n%message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:`<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)\n`<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)\n`<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)options_invalid_value\nInvalid compiler option: %details%options_removed\nInvalid compiler option: %details%options_unrecognised\nUnrecognised compiler option %keypath%props_duplicate\nCannot use `%rune%()` more than onceprops_id_invalid_placement\n`$props.id()` can only be used at the top level of components as a variable declaration initializerprops_illegal_name\nDeclaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)props_invalid_identifier\n`$props()` can only be used with an object destructuring patternprops_invalid_pattern\n`$props()` assignment must not contain nested properties or computed keysprops_invalid_placement\n`$props()` can only be used at the top level of components as a variable declaration initializerreactive_declaration_cycle\nCyclical dependency detected: %cycle%render_tag_invalid_call_expression\nCalling a snippet function using apply, bind or call is not allowedrender_tag_invalid_expression\n`{@render ...}` tags can only contain call expressionsrender_tag_invalid_spread_argument\ncannot use spread arguments in `{@render ...}` tagsrune_invalid_arguments\n`%rune%` cannot be called with argumentsrune_invalid_arguments_length\n`%rune%` must be called with %args%rune_invalid_computed_property\nCannot access a computed property of a runerune_invalid_name\n`%name%` is not a valid runerune_invalid_spread\n`%rune%` cannot be called with a spread argumentrune_invalid_usage\nCannot use `%rune%` rune in non-runes moderune_missing_parentheses\nCannot use rune without parenthesesrune_removed\nThe `%name%` rune has been removedrune_renamed\n`%name%` is now `%replacement%`runes_mode_invalid_import\n%name% cannot be used in runes modescript_duplicate\nA component can have a single top-level `<script>` element and/or a single top-level `<script module>` elementscript_invalid_attribute_value\nIf the `%name%` attribute is supplied, it must be a boolean attributescript_invalid_context\nIf the context attribute is supplied, its value must be \"module\"script_reserved_attribute\nThe `%name%` attribute is reserved and cannot be usedslot_attribute_duplicate\nDuplicate slot name '%name%' in <%component%>slot_attribute_invalid\nslot attribute must be a static valueslot_attribute_invalid_placement\nElement with a slot='...' attribute must be a child of a component or a descendant of a custom elementslot_default_duplicate\nFound default slot content alongside an explicit slot=\"default\"slot_element_invalid_attribute\n`<slot>` can only receive attributes and (optionally) let directivesslot_element_invalid_name\nslot attribute must be a static valueslot_element_invalid_name_default\n`default` is a reserved word — it cannot be used as a slot nameslot_snippet_conflict\nCannot use `<slot>` syntax and `{@render ...}` tags in the same component. Migrate towards `{@render ...}` tags completelysnippet_conflict\nCannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet blocksnippet_invalid_export\nAn exported snippet can only reference things declared in a `<script module>`, or other exportable snippetsIt's possible to export a snippet from a <script module> block, but only if it doesn't reference anything defined inside a non-module-level <script>. For example you can't do this...<script module>\n\texport { greeting };\n</script>\n\n<script>\n\tlet message = 'hello';\n</script>\n\n{#snippet greeting(name)}\n\t<p>{message} {name}!</p>\n{/snippet}...because greeting references message, which is defined in the second <script>.snippet_invalid_rest_parameter\nSnippets do not support rest parameters; use an array insteadsnippet_parameter_assignment\nCannot reassign or bind to snippet parametersnippet_shadowing_prop\nThis snippet is shadowing the prop `%prop%` with the same namestate_field_duplicate\n`%name%` has already been declared on this classAn assignment to a class field that uses a $state or $derived rune is considered a state field declaration. The declaration can happen in the class body...class Counter {\n\tcount = $state(0);\n}...or inside the constructor...class Counter {\n\tconstructor() {\n\t\tthis.count = $state(0);\n\t}\n}...but it can only happen once.state_field_invalid_assignment\nCannot assign to a state field before its declarationstate_invalid_export\nCannot export state from a module if it is reassigned. Either export a function returning the state value or only mutate the state value's propertiesstate_invalid_placement\n`%rune%(...)` can only be used as a variable declaration initializer, a class field declaration, or the first assignment to a class field at the top level of the constructor.store_invalid_scoped_subscription\nCannot subscribe to stores that are not declared at the top level of the componentstore_invalid_subscription\nCannot reference store value inside `<script module>`store_invalid_subscription_module\nCannot reference store value outside a `.svelte` fileUsing a $ prefix to refer to the value of a store is only possible inside .svelte files, where Svelte can automatically create subscriptions when a component is mounted and unsubscribe when the component is unmounted. Consider migrating to runes instead.style_directive_invalid_modifier\n`style:` directive can only use the `important` modifierstyle_duplicate\nA component can have a single top-level `<style>` elementsvelte_body_illegal_attribute\n`<svelte:body>` does not support non-event attributes or spread attributessvelte_boundary_invalid_attribute\nValid attributes on `<svelte:boundary>` are `onerror` and `failed`svelte_boundary_invalid_attribute_value\nAttribute value must be a non-string expressionsvelte_component_invalid_this\nInvalid component definition — must be an `{expression}`svelte_component_missing_this\n`<svelte:component>` must have a 'this' attributesvelte_element_missing_this\n`<svelte:element>` must have a 'this' attribute with a valuesvelte_fragment_invalid_attribute\n`<svelte:fragment>` can only have a slot attribute and (optionally) a let: directivesvelte_fragment_invalid_placement\n`<svelte:fragment>` must be the direct child of a componentsvelte_head_illegal_attribute\n`<svelte:head>` cannot have attributes nor directivessvelte_meta_duplicate\nA component can only have one `<%name%>` elementsvelte_meta_invalid_content\n<%name%> cannot have childrensvelte_meta_invalid_placement\n`<%name%>` tags cannot be inside elements or blockssvelte_meta_invalid_tag\nValid `<svelte:...>` tag names are %list%svelte_options_deprecated_tag\n\"tag\" option is deprecated — use \"customElement\" insteadsvelte_options_invalid_attribute\n`<svelte:options>` can only receive static attributessvelte_options_invalid_attribute_value\nValue must be %list%, if specifiedsvelte_options_invalid_customelement\n\"customElement\" must be a string literal defining a valid custom element name or an object of the form { tag?: string; shadow?: \"open\" | \"none\" | `ShadowRootInit`; props?: { [key: string]: { attribute?: string; reflect?: boolean; type: .. } } }svelte_options_invalid_customelement_props\n\"props\" must be a statically analyzable object literal of the form \"{ [key: string]: { attribute?: string; reflect?: boolean; type?: \"String\" | \"Boolean\" | \"Number\" | \"Array\" | \"Object\" }\"svelte_options_invalid_customelement_shadow\n\"shadow\" must be either \"open\", \"none\" or `ShadowRootInit` object.See https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options for more information on valid shadow root constructor optionssvelte_options_invalid_tagname\nTag name must be lowercase and hyphenatedSee https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name for more information on valid tag namessvelte_options_reserved_tagname\nTag name is reservedSee https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name for more information on valid tag namessvelte_options_unknown_attribute\n`<svelte:options>` unknown attribute '%name%'svelte_self_invalid_placement\n`<svelte:self>` components can only exist inside `{#if}` blocks, `{#each}` blocks, `{#snippet}` blocks or slots passed to componentstag_invalid_name\nExpected a valid element or component name. Components must have a valid variable name or dot notation expressiontag_invalid_placement\n{@%name% ...} tag cannot be %location%textarea_invalid_content\nA `<textarea>` can have either a value attribute or (equivalently) child content, but not bothtitle_illegal_attribute\n`<title>` cannot have attributes nor directivestitle_invalid_content\n`<title>` can only contain text and {tags}transition_conflict\nCannot use `%type%:` alongside existing `%existing%:` directivetransition_duplicate\nCannot use multiple `%type%:` directives on a single elementtypescript_invalid_feature\nTypeScript language features like %feature% are not natively supported, and their use is generally discouraged. Outside of `<script>` tags, these features are not supported. For use within `<script>` tags, you will need to use a preprocessor to convert it to JavaScript before it gets passed to the Svelte compiler. If you are using `vitePreprocess`, make sure to specifically enable preprocessing script tags (`vitePreprocess({ script: true })`)unexpected_eof\nUnexpected end of inputunexpected_reserved_word\n'%word%' is a reserved word in JavaScript and cannot be used hereunterminated_string_constant\nUnterminated string constantvoid_element_invalid_content\nVoid elements cannot have children or closing tags","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Compiler warnings"],"href":"/docs/svelte/compiler-warnings","content":"Svelte warns you at compile time if it catches potential mistakes, such as writing inaccessible markup.Some warnings may be incorrect in your concrete use case. You can disable such false positives by placing a <!-- svelte-ignore <code> --> comment above the line that causes the warning. Example:<!-- svelte-ignore a11y_autofocus -->\n<input autofocus />You can list multiple rules in a single comment (separated by commas), and add an explanatory note (in parentheses) alongside them:<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions (because of reasons) -->\n<div onclick>...</div>\na11y_accesskey\nAvoid using accesskeyEnforce no accesskey on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.\n<!-- A11y: Avoid using accesskey -->\n<div accesskey=\"z\"></div>a11y_aria_activedescendant_has_tabindex\nAn element with an aria-activedescendant attribute should have a tabindex valueAn element with aria-activedescendant must be tabbable, so it must either have an inherent tabindex or declare tabindex as an attribute.<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->\n<div aria-activedescendant=\"some-id\"></div>a11y_aria_attributes\n`<%name%>` should not have aria-* attributesCertain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example meta, html, script, style. This rule enforces that these DOM elements do not contain the aria-* props.<!-- A11y: <meta> should not have aria-* attributes -->\n<meta aria-hidden=\"false\" />a11y_autocomplete_valid\n'%value%' is an invalid value for 'autocomplete' on `<input type=\"%type%\">`a11y_autofocus\nAvoid using autofocusEnforce that autofocus is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.<!-- A11y: Avoid using autofocus -->\n<input autofocus />a11y_click_events_have_key_events\nVisible, non-interactive element `<%element%>` with a click event must be accompanied by a keyboard event handler. Consider whether an interactive element such as `<button type=\"button\">` or `<a>` might be more appropriateEnforce that visible, non-interactive elements with an onclick event are accompanied by a keyboard event handler.Users should first consider whether an interactive element might be more appropriate such as a <button type=\"button\"> element for actions or <a> element for navigations. These elements are more semantically meaningful and will have built-in key handling. E.g. Space and Enter will trigger a <button> and Enter will trigger an <a> element.If a non-interactive element is required then onclick should be accompanied by an onkeyup or onkeydown handler that enables the user to perform equivalent actions via the keyboard. In order for the user to be able to trigger a key press, the element will also need to be focusable by adding a `tabindex`. While an onkeypress handler will also silence this warning, it should be noted that the keypress event is deprecated.<!-- A11y: visible, non-interactive elements with an onclick event must be accompanied by a keyboard event handler. -->\n<div onclick={() => {}}></div>Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.a11y_consider_explicit_label\nButtons and links should either contain text or have an `aria-label`, `aria-labelledby` or `title` attributea11y_distracting_elements\nAvoid `<%name%>` elementsEnforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.The following elements are visually distracting: <marquee> and <blink>.<!-- A11y: Avoid <marquee> elements -->\n<marquee></marquee>a11y_figcaption_index\n`<figcaption>` must be first or last child of `<figure>`a11y_figcaption_parent\n`<figcaption>` must be an immediate child of `<figure>`Enforce that certain DOM elements have the correct structure.<!-- A11y: <figcaption> must be an immediate child of <figure> -->\n<div>\n\t<figcaption>Image caption</figcaption>\n</div>a11y_hidden\n`<%name%>` element should not be hiddenCertain DOM elements are useful for screen reader navigation and should not be hidden.\n<!-- A11y: <h2> element should not be hidden -->\n<h2 aria-hidden=\"true\">invisible header</h2>a11y_img_redundant_alt\nScreenreaders already announce `<img>` elements as an imageEnforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce img elements as an image. There is no need to use words such as image, photo, and/or picture.<img src=\"foo\" alt=\"Foo eating a sandwich.\" />\n\n<!-- aria-hidden, won't be announced by screen reader -->\n<img src=\"bar\" aria-hidden=\"true\" alt=\"Picture of me taking a photo of an image\" />\n\n<!-- A11y: Screen readers already announce <img> elements as an image. -->\n<img src=\"foo\" alt=\"Photo of foo being weird.\" />\n\n<!-- A11y: Screen readers already announce <img> elements as an image. -->\n<img src=\"bar\" alt=\"Image of me at a bar!\" />\n\n<!-- A11y: Screen readers already announce <img> elements as an image. -->\n<img src=\"foo\" alt=\"Picture of baz fixing a bug.\" />a11y_incorrect_aria_attribute_type\nThe value of '%attribute%' must be a %type%Enforce that only the correct type of value is used for aria attributes. For example, aria-hidden\nshould only receive a boolean.<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->\n<div aria-hidden=\"yes\"></div>a11y_incorrect_aria_attribute_type_boolean\nThe value of '%attribute%' must be either 'true' or 'false'. It cannot be emptya11y_incorrect_aria_attribute_type_id\nThe value of '%attribute%' must be a string that represents a DOM element IDa11y_incorrect_aria_attribute_type_idlist\nThe value of '%attribute%' must be a space-separated list of strings that represent DOM element IDsa11y_incorrect_aria_attribute_type_integer\nThe value of '%attribute%' must be an integera11y_incorrect_aria_attribute_type_token\nThe value of '%attribute%' must be exactly one of %values%a11y_incorrect_aria_attribute_type_tokenlist\nThe value of '%attribute%' must be a space-separated list of one or more of %values%a11y_incorrect_aria_attribute_type_tristate\nThe value of '%attribute%' must be exactly one of true, false, or mixeda11y_interactive_supports_focus\nElements with the '%role%' interactive role must have a tabindex valueEnforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->\n<div role=\"button\" onkeypress={() => {}} />a11y_invalid_attribute\n'%href_value%' is not a valid %href_attribute% attributeEnforce that attributes important for accessibility have a valid value. For example, href should not be empty, '#', or javascript:.<!-- A11y: '' is not a valid href attribute -->\n<a href=\"\">invalid</a>a11y_label_has_associated_control\nA form label must be associated with a controlEnforce that a label tag has a text label and an associated control.There are two supported ways to associate a label with a control:Wrapping a control in a label tag.\nAdding `for` to a label and assigning it the ID of an input on the page.<label for=\"id\">B</label>\n\n<label>C <input type=\"text\" /></label>\n\n<!-- A11y: A form label must be associated with a control. -->\n<label>A</label>a11y_media_has_caption\n`<video>` elements must have a `<track kind=\"captions\">`Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to alt text on an image when an image is unable to load).The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the muted attribute.<video><track kind=\"captions\" /></video>\n\n<audio muted></audio>\n\n<!-- A11y: Media elements must have a <track kind=\\\"captions\\\"> -->\n<video></video>\n\n<!-- A11y: Media elements must have a <track kind=\\\"captions\\\"> -->\n<video><track /></video>a11y_misplaced_role\n`<%name%>` should not have role attributeCertain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example meta, html, script, style. This rule enforces that these DOM elements do not contain the role props.<!-- A11y: <meta> should not have role attribute -->\n<meta role=\"tooltip\" />a11y_misplaced_scope\nThe scope attribute should only be used with `<th>` elementsThe scope attribute should only be used on <th> elements.\n<!-- A11y: The scope attribute should only be used with <th> elements -->\n<div scope=\"row\" />a11y_missing_attribute\n`<%name%>` element should have %article% %sequence% attributeEnforce that attributes required for accessibility are present on an element. This includes the following checks:`<a>` should have an href (unless it's a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))\n`<area>` should have alt, aria-label, or aria-labelledby\n`<html>` should have lang\n`<iframe>` should have title\n`<img>` should have alt\n`<object>` should have title, aria-label, or aria-labelledby\n`<input type=\"image\">` should have alt, aria-label, or aria-labelledby<!-- A11y: <input type=\\\"image\\\"> element should have an alt, aria-label or aria-labelledby attribute -->\n<input type=\"image\" />\n\n<!-- A11y: <html> element should have a lang attribute -->\n<html></html>\n\n<!-- A11y: <a> element should have an href attribute -->\n<a>text</a>a11y_missing_content\n`<%name%>` element should contain textEnforce that heading elements (h1, h2, etc.) and anchors have content and that the content is accessible to screen readers<!-- A11y: <a> element should have child content -->\n<a href=\"/foo\"></a>\n\n<!-- A11y: <h1> element should have child content -->\n<h1></h1>a11y_mouse_events_have_key_events\n'%event%' event must be accompanied by '%accompanied_by%' eventEnforce that onmouseover and onmouseout are accompanied by onfocus and onblur, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.<!-- A11y: onmouseover must be accompanied by onfocus -->\n<div onmouseover={handleMouseover} />\n\n<!-- A11y: onmouseout must be accompanied by onblur -->\n<div onmouseout={handleMouseout} />a11y_no_abstract_role\nAbstract role '%role%' is forbiddena11y_no_interactive_element_to_noninteractive_role\n`<%element%>` cannot have role '%role%'WAI-ARIA roles should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include article, banner, complementary, img, listitem, main, region and tooltip.<!-- A11y: <textarea> cannot have role 'listitem' -->\n<textarea role=\"listitem\"></textarea>a11y_no_noninteractive_element_interactions\nNon-interactive element `<%element%>` should not be assigned mouse or keyboard event listenersA non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include <main>, <area>, <h1> (,<h2>, etc), <p>, <img>, <li>, <ul> and <ol>. Non-interactive WAI-ARIA roles include article, banner, complementary, img, listitem, main, region and tooltip.<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->\n<li onclick={() => {}}></li>\n\n<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->\n<div role=\"listitem\" onclick={() => {}}></div>a11y_no_noninteractive_element_to_interactive_role\nNon-interactive element `<%element%>` cannot have interactive role '%role%'WAI-ARIA roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include button, link, checkbox, menuitem, menuitemcheckbox, menuitemradio, option, radio, searchbox, switch and textbox.<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->\n<h3 role=\"searchbox\">Button</h3>a11y_no_noninteractive_tabindex\nnoninteractive element cannot have nonnegative tabIndex valueTab key navigation should be limited to elements on the page that can be interacted with.\n<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->\n<div tabindex=\"0\"></div>a11y_no_redundant_roles\nRedundant role '%role%'Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser has no effect and is redundant.<!-- A11y: Redundant role 'button' -->\n<button role=\"button\">...</button>\n\n<!-- A11y: Redundant role 'img' -->\n<img role=\"img\" src=\"foo.jpg\" />a11y_no_static_element_interactions\n`<%element%>` with a %handler% handler must have an ARIA roleElements like <div> with interactive handlers like click must have an ARIA role.\n<!-- A11y: <div> with click handler must have an ARIA role -->\n<div onclick={() => ''}></div>a11y_positive_tabindex\nAvoid tabindex values above zeroAvoid positive tabindex property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.\n<!-- A11y: avoid tabindex values above zero -->\n<div tabindex=\"1\"></div>a11y_role_has_required_aria_props\nElements with the ARIA role \"%role%\" must have the following attributes defined: %props%Elements with ARIA roles must have all required attributes for that role.<!-- A11y: A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: \"aria-checked\" -->\n<span role=\"checkbox\" aria-labelledby=\"foo\" tabindex=\"0\"></span>a11y_role_supports_aria_props\nThe attribute '%attribute%' is not supported by the role '%role%'Elements with explicit or implicit roles defined contain only aria-* properties supported by that role.<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->\n<div role=\"link\" aria-multiline></div>\n\n<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->\n<li aria-required></li>a11y_role_supports_aria_props_implicit\nThe attribute '%attribute%' is not supported by the role '%role%'. This role is implicit on the element `<%name%>`Elements with explicit or implicit roles defined contain only aria-* properties supported by that role.<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->\n<div role=\"link\" aria-multiline></div>\n\n<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->\n<li aria-required></li>a11y_unknown_aria_attribute\nUnknown aria attribute 'aria-%attribute%'Unknown aria attribute 'aria-%attribute%'. Did you mean '%suggestion%'?Enforce that only known ARIA attributes are used. This is based on the WAI-ARIA States and Properties spec.<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->\n<input type=\"image\" aria-labeledby=\"foo\" />a11y_unknown_role\nUnknown role '%role%'Unknown role '%role%'. Did you mean '%suggestion%'?Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at WAI-ARIA site.\n<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->\n<div role=\"toooltip\"></div>attribute_avoid_is\nThe \"is\" attribute is not supported cross-browser and should be avoidedattribute_global_event_reference\nYou are referencing `globalThis.%name%`. Did you forget to declare a variable with that name?attribute_illegal_colon\nAttributes should not contain ':' characters to prevent ambiguity with Svelte directivesattribute_invalid_property_name\n'%wrong%' is not a valid HTML attribute. Did you mean '%right%'?attribute_quoted\nQuoted attributes on components and custom elements will be stringified in a future version of Svelte. If this isn't what you want, remove the quotesbidirectional_control_characters\nA bidirectional control character was detected in your code. These characters can be used to alter the visual direction of your code and could have unintended consequencesBidirectional control characters can alter the direction in which text appears to be in. For example, via control characters, you can make defabc look like abcdef. As a result, if you were to unknowingly copy and paste some code that has these control characters, they may alter the behavior of your code in ways you did not intend. See trojansource.codes for more information.bind_invalid_each_rest\nThe rest operator (...) will create a new object and binding '%name%' with the original object will not workblock_empty\nEmpty blockcomponent_name_lowercase\n`<%name%>` will be treated as an HTML element unless it begins with a capital lettercss_unused_selector\nUnused CSS selector \"%name%\"Svelte traverses both the template and the <style> tag to find out which of the CSS selectors are not used within the template, so it can remove them.In some situations a selector may target an element that is not 'visible' to the compiler, for example because it is part of an {@html ...} tag or you're overriding styles in a child component. In these cases, use `:global` to preserve the selector as-is:<div class=\"post\">{@html content}</div>\n\n<style>\n  .post :global {\n    p {...}\n  }\n</style>custom_element_props_identifier\nUsing a rest element or a non-destructured declaration with `$props()` means that Svelte can't infer what properties to expose when creating a custom element. Consider destructuring all the props or explicitly specifying the `customElement.props` option.element_implicitly_closed\nThis element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises.In HTML, some elements are implicitly closed by another element. For example, you cannot nest a <p> inside another <p>:<!-- this HTML... -->\n<p><p>hello</p>\n\n<!-- results in this DOM structure -->\n<p></p>\n<p>hello</p>Similarly, a parent element's closing tag will implicitly close all child elements, even if the </ was a typo and you meant to create a new element. To avoid ambiguity, it's always a good idea to have an explicit closing tag.element_invalid_self_closing_tag\nSelf-closing HTML tags for non-void elements are ambiguous — use `<%name% ...></%name%>` rather than `<%name% ... />`In HTML, there's no such thing as a self-closing tag. While this looks like a self-contained element with some text next to it...<div>\n\t<span class=\"icon\" /> some text!\n</div>...a spec-compliant HTML parser (such as a browser) will in fact parse it like this, with the text inside the icon:<div>\n\t<span class=\"icon\"> some text! </span>\n</div>Some templating languages (including Svelte) will 'fix' HTML by turning <span /> into <span></span>. Others adhere to the spec. Both result in ambiguity and confusion when copy-pasting code between different contexts, so Svelte prompts you to resolve the ambiguity directly by having an explicit closing tag.To automate this, run the dedicated migration:npx sv migrate self-closing-tagsIn a future version of Svelte, self-closing tags may be upgraded from a warning to an error.event_directive_deprecated\nUsing `on:%name%` to listen to the %name% event is deprecated. Use the event attribute `on%name%` insteadSee the migration guide for more info.export_let_unused\nComponent has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`legacy_code\n`%code%` is no longer valid — please use `%suggestion%` insteadlegacy_component_creation\nSvelte 5 components are no longer classes. Instantiate them using `mount` or `hydrate` (imported from 'svelte') instead.See the migration guide for more info.node_invalid_placement_ssr\n%message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warningHTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:`<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)\n`<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)\n`<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)This code will work when the component is rendered on the client (which is why this is a warning rather than an error), but if you use server rendering it will cause hydration to fail.non_reactive_update\n`%name%` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updatesThis warning is thrown when the compiler detects the following:a variable was declared without `$state` or `$state.raw`\nthe variable is reassigned\nthe variable is read in a reactive contextIn this case, changing the value will not correctly trigger updates. Example:<script>\n\tlet reactive = $state('reactive');\n\tlet stale = 'stale';\n</script>\n\n<p>This value updates: {reactive}</p>\n<p>This value does not update: {stale}</p>\n\n<button onclick={() => {\n\tstale = 'updated';\n\treactive = 'updated';\n}}>update</button>To fix this, wrap your variable declaration with $state.options_deprecated_accessors\nThe `accessors` option has been deprecated. It will have no effect in runes modeoptions_deprecated_immutable\nThe `immutable` option has been deprecated. It will have no effect in runes modeoptions_missing_custom_element\nThe `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?options_removed_enable_sourcemap\nThe `enableSourcemap` option has been removed. Source maps are always generated now, and tooling can choose to ignore themoptions_removed_hydratable\nThe `hydratable` option has been removed. Svelte components are always hydratable nowoptions_removed_loop_guard_timeout\nThe `loopGuardTimeout` option has been removedoptions_renamed_ssr_dom\n`generate: \"dom\"` and `generate: \"ssr\"` options have been renamed to \"client\" and \"server\" respectivelyperf_avoid_inline_class\nAvoid 'new class' — instead, declare the class at the top level scopeperf_avoid_nested_class\nAvoid declaring classes below the top level scopereactive_declaration_invalid_placement\nReactive declarations only exist at the top level of the instance scriptreactive_declaration_module_script_dependency\nReassignments of module-level declarations will not cause reactive statements to updatescript_context_deprecated\n`context=\"module\"` is deprecated, use the `module` attribute instead<script ---context=\"module\"--- +++module+++>\n\tlet foo = 'bar';\n</script>script_unknown_attribute\nUnrecognised attribute — should be one of `generics`, `lang` or `module`. If this exists for a preprocessor, ensure that the preprocessor removes itslot_element_deprecated\nUsing `<slot>` to render parent content is deprecated. Use `{@render ...}` tags insteadSee the migration guide for more info.state_referenced_locally\nThis reference only captures the initial value of `%name%`. Did you mean to reference it inside a %type% instead?This warning is thrown when the compiler detects the following:A reactive variable is declared\n...and later reassigned...\n...and referenced in the same scopeThis 'breaks the link' to the original state declaration. For example, if you pass the state to a function, the function loses access to the state once it is reassigned:<!--- file: Parent.svelte --->\n<script>\n\timport { setContext } from 'svelte';\n\n\tlet count = $state(0);\n\n\t// warning: state_referenced_locally\n\tsetContext('count', count);\n</script>\n\n<button onclick={() => count++}>\n\tincrement\n</button><!--- file: Child.svelte --->\n<script>\n\timport { getContext } from 'svelte';\n\n\tconst count = getContext('count');\n</script>\n\n<!-- This will never update -->\n<p>The count is {count}</p>To fix this, reference the variable such that it is lazily evaluated. For the above example, this can be achieved by wrapping count in a function:<!--- file: Parent.svelte --->\n<script>\n\timport { setContext } from 'svelte';\n\n\tlet count = $state(0);\n\tsetContext('count', +++() => count+++);\n</script>\n\n<button onclick={() => count++}>\n\tincrement\n</button><!--- file: Child.svelte --->\n<script>\n\timport { getContext } from 'svelte';\n\n\tconst count = getContext('count');\n</script>\n\n<!-- This will update -->\n<p>The count is {+++count()+++}</p>For more info, see Passing state into functions.store_rune_conflict\nIt looks like you're using the `$%name%` rune, but there is a local binding called `%name%`. Referencing a local variable with a `$` prefix will create a store subscription. Please rename `%name%` to avoid the ambiguitysvelte_component_deprecated\n`<svelte:component>` is deprecated in runes mode — components are dynamic by defaultIn previous versions of Svelte, the component constructor was fixed when the component was rendered. In other words, if you wanted <X> to re-render when X changed, you would either have to use <svelte:component this={X}> or put the component inside a {#key X}...{/key} block.In Svelte 5 this is no longer true — if X changes, <X> re-renders.In some cases <object.property> syntax can be used as a replacement; a lowercased variable with property access is recognized as a component in Svelte 5.For complex component resolution logic, an intermediary, capitalized variable may be necessary. E.g. in places where @const can be used:\n{#each items as item}\n\t---<svelte:component this={item.condition ? Y : Z} />---\n\t+++{@const Component = item.condition ? Y : Z}+++\n\t+++<Component />+++\n{/each}A derived value may be used in other contexts:\n<script>\n\t// ...\n\tlet condition = $state(false);\n\t+++const Component = $derived(condition ? Y : Z);+++\n</script>\n\n---<svelte:component this={condition ? Y : Z} />---\n+++<Component />+++svelte_element_invalid_this\n`this` should be an `{expression}`. Using a string attribute value will cause an error in future versions of Sveltesvelte_self_deprecated\n`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) insteadSee the note in the docs for more info.unknown_code\n`%code%` is not a recognised code`%code%` is not a recognised code (did you mean `%suggestion%`?)","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors"],"href":"/docs/svelte/runtime-errors","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors"],"href":"/docs/svelte/runtime-errors#Client-errors","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","async_derived_orphan"],"href":"/docs/svelte/runtime-errors#Client-errors-async_derived_orphan","content":"Cannot create a `$derived(...)` with an `await` expression outside of an effect treeIn Svelte there are two types of reaction — `$derived` and `$effect`. Deriveds can be created anywhere, because they run lazily and can be garbage collected if nothing references them. Effects, by contrast, keep running eagerly whenever their dependencies change, until they are destroyed.Because of this, effects can only be created inside other effects (or effect roots, such as the one that is created when you first mount a component) so that Svelte knows when to destroy them.Some sleight of hand occurs when a derived contains an await expression: Since waiting until we read {await getPromise()} to call getPromise would be too late, we use an effect to instead call it proactively, notifying Svelte when the value is available. But since we're using an effect, we can only create asynchronous deriveds inside another effect.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","bind_invalid_checkbox_value"],"href":"/docs/svelte/runtime-errors#Client-errors-bind_invalid_checkbox_value","content":"Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","bind_invalid_export"],"href":"/docs/svelte/runtime-errors#Client-errors-bind_invalid_export","content":"Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`)","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","bind_not_bindable"],"href":"/docs/svelte/runtime-errors#Client-errors-bind_not_bindable","content":"A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","component_api_changed"],"href":"/docs/svelte/runtime-errors#Client-errors-component_api_changed","content":"Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5See the migration guide for more information.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","component_api_invalid_new"],"href":"/docs/svelte/runtime-errors#Client-errors-component_api_invalid_new","content":"Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working.See the migration guide for more information.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","derived_references_self"],"href":"/docs/svelte/runtime-errors#Client-errors-derived_references_self","content":"A derived value cannot reference itself recursively","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","each_key_duplicate"],"href":"/docs/svelte/runtime-errors#Client-errors-each_key_duplicate","content":"Keyed each block has duplicate key at indexes %a% and %b%Keyed each block has duplicate key `%value%` at indexes %a% and %b%","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","each_key_volatile"],"href":"/docs/svelte/runtime-errors#Client-errors-each_key_volatile","content":"Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given itemThe key expression in a keyed each block must return the same value when called multiple times for the same item. Using expressions like [item.a, item.b] creates a new array each time, which will never be equal to itself. Instead, use a primitive value or create a stable key like item.a + '-' + item.b.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","effect_in_teardown"],"href":"/docs/svelte/runtime-errors#Client-errors-effect_in_teardown","content":"`%rune%` cannot be used inside an effect cleanup function","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","effect_in_unowned_derived"],"href":"/docs/svelte/runtime-errors#Client-errors-effect_in_unowned_derived","content":"Effect cannot be created inside a `$derived` value that was not itself created inside an effect","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","effect_orphan"],"href":"/docs/svelte/runtime-errors#Client-errors-effect_orphan","content":"`%rune%` can only be used inside an effect (e.g. during component initialisation)Effects can only be created while a parent effect is running. This means that they cannot, for example, be created inside an event handler or after an await expression (unless the await occurs directly inside a component's <script> tag, and not inside an async function).In very rare cases, it is appropriate to use `$effect.root` so that you can create effects outside the normal component lifecycle.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","effect_pending_outside_reaction"],"href":"/docs/svelte/runtime-errors#Client-errors-effect_pending_outside_reaction","content":"`$effect.pending()` can only be called inside an effect or derived","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","effect_update_depth_exceeded"],"href":"/docs/svelte/runtime-errors#Client-errors-effect_update_depth_exceeded","content":"Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of stateIf an effect updates some state that it also depends on, it will re-run, potentially in a loop:let count = $state(0);\n\n$effect(() => {\n\t// this both reads and writes `count`,\n\t// so will run in an infinite loop\n\tcount += 1;\n});(Svelte intervenes before this can crash your browser tab.)The same applies to array mutations, since these both read and write to the array:let array = $state(['hello']);\n\n$effect(() => {\n\tarray.push('goodbye');\n});Note that it's fine for an effect to re-run itself as long as it 'settles':$effect(() => {\n\t// this is okay, because sorting an already-sorted array\n\t// won't result in a mutation\n\tarray.sort();\n});Often when encountering this issue, the value in question shouldn't be state (for example, if you are pushing to a logs array in an effect, make logs a normal array rather than $state([])). In the rare cases where you really do need to write to state in an effect — which you should avoid — you can read the state with untrack to avoid adding it as a dependency.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","flush_sync_in_effect"],"href":"/docs/svelte/runtime-errors#Client-errors-flush_sync_in_effect","content":"Cannot use `flushSync` inside an effectThe flushSync() function can be used to flush any pending effects synchronously. It cannot be used if effects are currently being flushed — in other words, you can call it after a state change but not inside an effect.This restriction only applies when using the experimental.async option, which will be active by default in Svelte 6.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","fork_discarded"],"href":"/docs/svelte/runtime-errors#Client-errors-fork_discarded","content":"Cannot commit a fork that was already discarded","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","fork_timing"],"href":"/docs/svelte/runtime-errors#Client-errors-fork_timing","content":"Cannot create a fork inside an effect or when state changes are pending","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","get_abort_signal_outside_reaction"],"href":"/docs/svelte/runtime-errors#Client-errors-get_abort_signal_outside_reaction","content":"`getAbortSignal()` can only be called inside an effect or derived","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","hydratable_missing_but_required"],"href":"/docs/svelte/runtime-errors#Client-errors-hydratable_missing_but_required","content":"Expected to find a hydratable with key `%key%` during hydration, but did not.This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.<script>\n  import { hydratable } from 'svelte';\n\n\tif (BROWSER) {\n\t\t// bad! nothing can become interactive until this asynchronous work is done\n\t\tawait hydratable('foo', get_slow_random_number);\n\t}\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","hydration_failed"],"href":"/docs/svelte/runtime-errors#Client-errors-hydration_failed","content":"Failed to hydrate the application","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","invalid_snippet"],"href":"/docs/svelte/runtime-errors#Client-errors-invalid_snippet","content":"Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","lifecycle_legacy_only"],"href":"/docs/svelte/runtime-errors#Client-errors-lifecycle_legacy_only","content":"`%name%(...)` cannot be used in runes mode","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","props_invalid_value"],"href":"/docs/svelte/runtime-errors#Client-errors-props_invalid_value","content":"Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","props_rest_readonly"],"href":"/docs/svelte/runtime-errors#Client-errors-props_rest_readonly","content":"Rest element properties of `$props()` such as `%property%` are readonly","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","rune_outside_svelte"],"href":"/docs/svelte/runtime-errors#Client-errors-rune_outside_svelte","content":"The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","set_context_after_init"],"href":"/docs/svelte/runtime-errors#Client-errors-set_context_after_init","content":"`setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expressionThis restriction only applies when using the experimental.async option, which will be active by default in Svelte 6.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","state_descriptors_fixed"],"href":"/docs/svelte/runtime-errors#Client-errors-state_descriptors_fixed","content":"Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","state_prototype_fixed"],"href":"/docs/svelte/runtime-errors#Client-errors-state_prototype_fixed","content":"Cannot set prototype of `$state` object","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","state_unsafe_mutation"],"href":"/docs/svelte/runtime-errors#Client-errors-state_unsafe_mutation","content":"Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`This error occurs when state is updated while evaluating a $derived. You might encounter it while trying to 'derive' two pieces of state in one go:<script>\n\tlet count = $state(0);\n\n\tlet even = $state(true);\n\n\tlet odd = $derived.by(() => {\n\t\teven = count % 2 === 0;\n\t\treturn !even;\n\t});\n</script>\n\n<button onclick={() => count++}>{count}</button>\n\n<p>{count} is even: {even}</p>\n<p>{count} is odd: {odd}</p>This is forbidden because it introduces instability: if <p>{count} is even: {even}</p> is updated before odd is recalculated, even will be stale. In most cases the solution is to make everything derived:let even = $derived(count % 2 === 0);\nlet odd = $derived(!even);If side-effects are unavoidable, use `$effect` instead.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Client errors","svelte_boundary_reset_onerror"],"href":"/docs/svelte/runtime-errors#Client-errors-svelte_boundary_reset_onerror","content":"A `<svelte:boundary>` `reset` function cannot be called while an error is still being handledIf a `<svelte:boundary>` has an onerror function, it must not call the provided reset function synchronously since the boundary is still in a broken state. Typically, reset() is called later, once the error has been resolved.If it's possible to resolve the error inside the onerror callback, you must at least wait for the boundary to settle before calling reset(), for example using `tick`:<svelte:boundary onerror={async (error, reset) => {\n\tfixTheError();\n\t+++await tick();+++\n\treset();\n}}>\n\n</svelte:boundary>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors"],"href":"/docs/svelte/runtime-errors#Server-errors","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","async_local_storage_unavailable"],"href":"/docs/svelte/runtime-errors#Server-errors-async_local_storage_unavailable","content":"The node API `AsyncLocalStorage` is not available, but is required to use async server rendering.Some platforms require configuration flags to enable this API. Consult your platform's documentation.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","await_invalid"],"href":"/docs/svelte/runtime-errors#Server-errors-await_invalid","content":"Encountered asynchronous work while rendering synchronously.You (or the framework you're using) called `render(...)` with a component containing an await expression. Either await the result of render or wrap the await (or the component containing it) in a `<svelte:boundary>` with a pending snippet.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","dynamic_element_invalid_tag"],"href":"/docs/svelte/runtime-errors#Server-errors-dynamic_element_invalid_tag","content":"`<svelte:element this=\"%tag%\">` is not a valid element name — the element will not be renderedThe value passed to the this prop of <svelte:element> must be a valid HTML element, SVG element, MathML element, or custom element name. A value containing invalid characters (such as whitespace or special characters) was provided, which could be a security risk. Ensure only valid tag names are passed.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","html_deprecated"],"href":"/docs/svelte/runtime-errors#Server-errors-html_deprecated","content":"The `html` property of server render results has been deprecated. Use `body` instead.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","hydratable_clobbering"],"href":"/docs/svelte/runtime-errors#Server-errors-hydratable_clobbering","content":"Attempted to set `hydratable` with key `%key%` twice with different values.\n\n%stack%This error occurs when using hydratable multiple times with the same key. To avoid this, you can:Ensure all invocations with the same key result in the same value\nUpdate the keys to make both instances unique<script>\n  import { hydratable } from 'svelte';\n\n  // which one should \"win\" and be serialized in the rendered response?\n  const one = hydratable('not-unique', () => 1);\n  const two = hydratable('not-unique', () => 2);\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","hydratable_serialization_failed"],"href":"/docs/svelte/runtime-errors#Server-errors-hydratable_serialization_failed","content":"Failed to serialize `hydratable` data for key `%key%`.\n\n`hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises.\n\nCause:\n%stack%","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","invalid_csp"],"href":"/docs/svelte/runtime-errors#Server-errors-invalid_csp","content":"`csp.nonce` was set while `csp.hash` was `true`. These options cannot be used simultaneously.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","invalid_id_prefix"],"href":"/docs/svelte/runtime-errors#Server-errors-invalid_id_prefix","content":"The `idPrefix` option cannot include `--`.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","lifecycle_function_unavailable"],"href":"/docs/svelte/runtime-errors#Server-errors-lifecycle_function_unavailable","content":"`%name%(...)` is not available on the serverCertain methods such as mount cannot be invoked while running in a server context. Avoid calling them eagerly, i.e. not during render.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Server errors","server_context_required"],"href":"/docs/svelte/runtime-errors#Server-errors-server_context_required","content":"Could not resolve `render` context.Certain functions such as hydratable cannot be invoked outside of a render(...) call, such as at the top level of a module.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors"],"href":"/docs/svelte/runtime-errors#Shared-errors","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","experimental_async_required"],"href":"/docs/svelte/runtime-errors#Shared-errors-experimental_async_required","content":"Cannot use `%name%(...)` unless the `experimental.async` compiler option is `true`","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","invalid_default_snippet"],"href":"/docs/svelte/runtime-errors#Shared-errors-invalid_default_snippet","content":"Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet insteadThis error would be thrown in a setup like this:<!--- file: Parent.svelte --->\n<List {items} let:entry>\n    <span>{entry}</span>\n</List><!--- file: List.svelte --->\n<script>\n    let { items, children } = $props();\n</script>\n\n<ul>\n    {#each items as item}\n        <li>{@render children(item)}</li>\n    {/each}\n</ul>Here, List.svelte is using {@render children(item) which means it expects Parent.svelte to use snippets. Instead, Parent.svelte uses the deprecated let: directive. This combination of APIs is incompatible, hence the error.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","invalid_snippet_arguments"],"href":"/docs/svelte/runtime-errors#Shared-errors-invalid_snippet_arguments","content":"A snippet function was passed invalid arguments. Snippets should only be instantiated via `{@render ...}`","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","invariant_violation"],"href":"/docs/svelte/runtime-errors#Shared-errors-invariant_violation","content":"An invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: \"%message%\"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","lifecycle_outside_component"],"href":"/docs/svelte/runtime-errors#Shared-errors-lifecycle_outside_component","content":"`%name%(...)` can only be used during component initialisationCertain lifecycle methods can only be used during component initialisation. To fix this, make sure you're invoking the method inside the top level of the instance script of your component.<script>\n    import { onMount } from 'svelte';\n\n    function handleClick() {\n        // This is wrong\n        onMount(() => {})\n    }\n\n    // This is correct\n    onMount(() => {})\n</script>\n\n<button onclick={handleClick}>click me</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","missing_context"],"href":"/docs/svelte/runtime-errors#Shared-errors-missing_context","content":"Context was not set in a parent componentThe `createContext()` utility returns a [get, set] pair of functions. get will throw an error if set was not used to set the context in a parent component.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","snippet_without_render_tag"],"href":"/docs/svelte/runtime-errors#Shared-errors-snippet_without_render_tag","content":"Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`.A component throwing this error will look something like this (children is not being rendered):<script>\n    let { children } = $props();\n</script>\n\n{children}...or like this (a parent component is passing a snippet where a non-snippet value is expected):<!--- file: Parent.svelte --->\n<ChildComponent>\n  {#snippet label()}\n    <span>Hi!</span>\n  {/snippet}\n</ChildComponent><!--- file: Child.svelte --->\n<script>\n  let { label } = $props();\n</script>\n\n<!-- This component doesn't expect a snippet, but the parent provided one -->\n<p>{label}</p>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","store_invalid_shape"],"href":"/docs/svelte/runtime-errors#Shared-errors-store_invalid_shape","content":"`%name%` is not a store with a `subscribe` method","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime errors","Shared errors","svelte_element_invalid_this_value"],"href":"/docs/svelte/runtime-errors#Shared-errors-svelte_element_invalid_this_value","content":"The `this` prop on `<svelte:element>` must be a string, if defined","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings"],"href":"/docs/svelte/runtime-warnings","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings"],"href":"/docs/svelte/runtime-warnings#Client-warnings","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","assignment_value_stale"],"href":"/docs/svelte/runtime-warnings#Client-warnings-assignment_value_stale","content":"Assignment to `%property%` property (%location%) will evaluate to the right-hand side, not the value of `%property%` following the assignment. This may result in unexpected behaviour.Given a case like this...<script>\n\tlet object = $state({ array: null });\n\n\tfunction add() {\n\t\t(object.array ??= []).push(object.array.length);\n\t}\n</script>\n\n<button onclick={add}>add</button>\n<p>items: {JSON.stringify(object.items)}</p>...the array being pushed to when the button is first clicked is the [] on the right-hand side of the assignment, but the resulting value of object.array is an empty state proxy. As a result, the pushed value will be discarded.You can fix this by separating it into two statements:function add() {\n\tobject.array ??= [];\n\tobject.array.push(object.array.length);\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","await_reactivity_loss"],"href":"/docs/svelte/runtime-warnings#Client-warnings-await_reactivity_loss","content":"Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`Svelte's signal-based reactivity works by tracking which bits of state are read when a template or $derived(...) expression executes. If an expression contains an await, Svelte transforms it such that any state after the await is also tracked — in other words, in a case like this...let total = $derived(await a + b);...both a and b are tracked, even though b is only read once a has resolved, after the initial execution.This does not apply to an await that is not 'visible' inside the expression. In a case like this...async function sum() {\n\treturn await a + b;\n}\n\nlet total = $derived(await sum());...total will depend on a (which is read immediately) but not b (which is not). The solution is to pass the values into the function:/**\n * @param {Promise<number>} a\n * @param {number} b\n */\nasync function sum(a, b) {\n\treturn await a + b;\n}\n\nlet total = $derived(await sum(a, b));","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","await_waterfall"],"href":"/docs/svelte/runtime-warnings#Client-warnings-await_waterfall","content":"An async derived, `%name%` (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your appIn a case like this...let a = $derived(await one());\nlet b = $derived(await two());...the second $derived will not be created until the first one has resolved. Since await two() does not depend on the value of a, this delay, often described as a 'waterfall', is unnecessary.(Note that if the values of await one() and await two() subsequently change, they can do so concurrently — the waterfall only occurs when the deriveds are first created.)You can solve this by creating the promises first and then awaiting them:let aPromise = $derived(one());\nlet bPromise = $derived(two());\n\nlet a = $derived(await aPromise);\nlet b = $derived(await bPromise);","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","binding_property_non_reactive"],"href":"/docs/svelte/runtime-warnings#Client-warnings-binding_property_non_reactive","content":"`%binding%` is binding to a non-reactive property`%binding%` (%location%) is binding to a non-reactive property","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","console_log_state"],"href":"/docs/svelte/runtime-warnings#Client-warnings-console_log_state","content":"Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)` or `$state.snapshot(...)` insteadWhen logging a proxy, browser devtools will log the proxy itself rather than the value it represents. In the case of Svelte, the 'target' of a $state proxy might not resemble its current value, which can be confusing.The easiest way to log a value as it changes over time is to use the `$inspect` rune. Alternatively, to log things on a one-off basis (for example, inside an event handler) you can use `$state.snapshot` to take a snapshot of the current value.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","derived_inert"],"href":"/docs/svelte/runtime-warnings#Client-warnings-derived_inert","content":"Reading a derived belonging to a now-destroyed effect may result in stale valuesA $derived value created inside an effect will stop updating when the effect is destroyed. You should create the $derived outside the effect, or inside an $effect.root.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","event_handler_invalid"],"href":"/docs/svelte/runtime-warnings#Client-warnings-event_handler_invalid","content":"%handler% should be a function. Did you mean to %suggestion%?","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","hydratable_missing_but_expected"],"href":"/docs/svelte/runtime-warnings#Client-warnings-hydratable_missing_but_expected","content":"Expected to find a hydratable with key `%key%` during hydration, but did not.This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.<script>\n  import { hydratable } from 'svelte';\n\n\tif (BROWSER) {\n\t\t// bad! nothing can become interactive until this asynchronous work is done\n\t\tawait hydratable('foo', get_slow_random_number);\n\t}\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","hydration_attribute_changed"],"href":"/docs/svelte/runtime-warnings#Client-warnings-hydration_attribute_changed","content":"The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server valueCertain attributes like src on an <img> element will not be repaired during hydration, i.e. the server value will be kept. That's because updating these attributes can cause the image to be refetched (or in the case of an <iframe>, for the frame to be reloaded), even if they resolve to the same resource.To fix this, either silence the warning with a `svelte-ignore` comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:<script>\n\tlet { src } = $props();\n\n\tif (typeof window !== 'undefined') {\n\t\t// stash the value...\n\t\tconst initial = src;\n\n\t\t// unset it...\n\t\tsrc = undefined;\n\n\t\t$effect(() => {\n\t\t\t// ...and reset after we've mounted\n\t\t\tsrc = initial;\n\t\t});\n\t}\n</script>\n\n<img {src} />","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","hydration_html_changed"],"href":"/docs/svelte/runtime-warnings#Client-warnings-hydration_html_changed","content":"The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server valueThe value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server valueIf the {@html ...} value changes between the server and the client, it will not be repaired during hydration, i.e. the server value will be kept. That's because change detection during hydration is expensive and usually unnecessary.To fix this, either silence the warning with a `svelte-ignore` comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:<script>\n\tlet { markup } = $props();\n\n\tif (typeof window !== 'undefined') {\n\t\t// stash the value...\n\t\tconst initial = markup;\n\n\t\t// unset it...\n\t\tmarkup = undefined;\n\n\t\t$effect(() => {\n\t\t\t// ...and reset after we've mounted\n\t\t\tmarkup = initial;\n\t\t});\n\t}\n</script>\n\n{@html markup}","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","hydration_mismatch"],"href":"/docs/svelte/runtime-warnings#Client-warnings-hydration_mismatch","content":"Hydration failed because the initial UI does not match what was rendered on the serverHydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%This warning is thrown when Svelte encounters an error while hydrating the HTML from the server. During hydration, Svelte walks the DOM, expecting a certain structure. If that structure is different (for example because the HTML was repaired by the DOM because of invalid HTML), then Svelte will run into issues, resulting in this warning.During development, this error is often preceded by a console.error detailing the offending HTML, which needs fixing.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","invalid_raw_snippet_render"],"href":"/docs/svelte/runtime-warnings#Client-warnings-invalid_raw_snippet_render","content":"The `render` function passed to `createRawSnippet` should return HTML for a single element","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","legacy_recursive_reactive_block"],"href":"/docs/svelte/runtime-warnings#Client-warnings-legacy_recursive_reactive_block","content":"Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","lifecycle_double_unmount"],"href":"/docs/svelte/runtime-warnings#Client-warnings-lifecycle_double_unmount","content":"Tried to unmount a component that was not mounted","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","ownership_invalid_binding"],"href":"/docs/svelte/runtime-warnings#Client-warnings-ownership_invalid_binding","content":"%parent% passed property `%prop%` to %child% with `bind:`, but its parent component %owner% did not declare `%prop%` as a binding. Consider creating a binding between %owner% and %parent% (e.g. `bind:%prop%={...}` instead of `%prop%={...}`)Consider three components GrandParent, Parent and Child. If you do <GrandParent bind:value>, inside GrandParent pass on the variable via <Parent {value} /> (note the missing bind:) and then do <Child bind:value> inside Parent, this warning is thrown.To fix it, bind: to the value instead of just passing a property (i.e. in this example do <Parent bind:value />).","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","ownership_invalid_mutation"],"href":"/docs/svelte/runtime-warnings#Client-warnings-ownership_invalid_mutation","content":"Mutating unbound props (`%name%`, at %location%) is strongly discouraged. Consider using `bind:%prop%={...}` in %parent% (or using a callback) insteadConsider the following code:<!--- file: App.svelte --->\n<script>\n\timport Child from './Child.svelte';\n\tlet person = $state({ name: 'Florida', surname: 'Man' });\n</script>\n\n<Child {person} /><!--- file: Child.svelte --->\n<script>\n\tlet { person } = $props();\n</script>\n\n<input bind:value={person.name}>\n<input bind:value={person.surname}>Child is mutating person which is owned by App without being explicitly \"allowed\" to do so. This is strongly discouraged since it can create code that is hard to reason about at scale (\"who mutated this value?\"), hence the warning.To fix it, either create callback props to communicate changes, or mark person as `$bindable`.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","select_multiple_invalid_value"],"href":"/docs/svelte/runtime-warnings#Client-warnings-select_multiple_invalid_value","content":"The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.When using <select multiple value={...}>, Svelte will mark all selected <option> elements as selected by iterating over the array passed to value. If value is not an array, Svelte will emit this warning and keep the selected options as they are.To silence the warning, ensure that value:is an array for an explicit selection\nis `null` or `undefined` to keep the selection as is","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","state_proxy_equality_mismatch"],"href":"/docs/svelte/runtime-warnings#Client-warnings-state_proxy_equality_mismatch","content":"Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results$state(...) creates a proxy of the value it is passed. The proxy and the value have different identities, meaning equality checks will always return false:<script>\n\tlet value = { foo: 'bar' };\n\tlet proxy = $state(value);\n\n\tvalue === proxy; // always false\n</script>To resolve this, ensure you're comparing values where both values were created with $state(...), or neither were. Note that $state.raw(...) will not create a state proxy.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","state_proxy_unmount"],"href":"/docs/svelte/runtime-warnings#Client-warnings-state_proxy_unmount","content":"Tried to unmount a state proxy, rather than a componentunmount was called with a state proxy:let component = $state(mount(Component, { target }));\n\n// later...\nunmount(component);Avoid using $state here. If component does need to be reactive for some reason, use $state.raw instead.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","svelte_boundary_reset_noop"],"href":"/docs/svelte/runtime-warnings#Client-warnings-svelte_boundary_reset_noop","content":"A `<svelte:boundary>` `reset` function only resets the boundary the first time it is calledWhen an error occurs while rendering the contents of a `<svelte:boundary>`, the onerror handler is called with the error plus a reset function that attempts to re-render the contents.This reset function should only be called once. After that, it has no effect — in a case like this, where a reference to reset is stored outside the boundary, clicking the button while <Contents /> is rendered will not cause the contents to be rendered again.<script>\n\tlet reset;\n</script>\n\n<button onclick={reset}>reset</button>\n\n<svelte:boundary onerror={(e, r) => (reset = r)}>\n\t<!-- contents -->\n\n\t{#snippet failed(e)}\n\t\t<p>oops! {e.message}</p>\n\t{/snippet}\n</svelte:boundary>","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Client warnings","transition_slide_display"],"href":"/docs/svelte/runtime-warnings#Client-warnings-transition_slide_display","content":"The `slide` transition does not work correctly for elements with `display: %value%`The slide transition works by animating the height of the element, which requires a display style like block, flex or grid. It does not work for:`display: inline` (which is the default for elements like `<span>`), and its variants like `inline-block`, `inline-flex` and `inline-grid`\n`display: table` and `table-[name]`, which are the defaults for elements like `<table>` and `<tr>`\n`display: contents`","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Shared warnings"],"href":"/docs/svelte/runtime-warnings#Shared-warnings","content":"","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Shared warnings","dynamic_void_element_content"],"href":"/docs/svelte/runtime-warnings#Shared-warnings-dynamic_void_element_content","content":"`<svelte:element this=\"%tag%\">` is a void element — it cannot have contentElements such as <input> cannot have content, any children passed to these elements will be ignored.","rank":null},{"breadcrumbs":["Docs","Svelte","Reference","Runtime warnings","Shared warnings","state_snapshot_uncloneable"],"href":"/docs/svelte/runtime-warnings#Shared-warnings-state_snapshot_uncloneable","content":"Value cannot be cloned with `$state.snapshot` — the original value was returnedThe following properties cannot be cloned with `$state.snapshot` — the return value contains the originals:\n\n%properties%$state.snapshot tries to clone the given value in order to return a reference that no longer changes. Certain objects may not be cloneable, in which case the original value is returned. In the following example, property is cloned, but window is not, because DOM elements are uncloneable:const object = $state({ property: 'this is cloneable', window })\nconst snapshot = $state.snapshot(object);","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Overview"],"href":"/docs/svelte/legacy-overview","content":"Svelte 5 introduced some significant changes to Svelte's API, including runes, snippets and event attributes. As a result, some Svelte 3/4 features are deprecated (though supported for now, unless otherwise specified) and will eventually be removed. We recommend that you incrementally migrate your existing code.The following pages document these features forpeople still using Svelte 3/4\npeople using Svelte 5, but with components that haven't yet been migratedSince Svelte 3/4 syntax still works in Svelte 5, we will distinguish between legacy mode and runes mode. Once a component is in runes mode (which you can opt into by using runes, or by explicitly setting the runes: true compiler option), legacy mode features are no longer available.If you're exclusively interested in the Svelte 3/4 syntax, you can browse its documentation at v4.svelte.dev.","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Reactive let/var declarations"],"href":"/docs/svelte/legacy-let","content":"In runes mode, reactive state is explicitly declared with the `$state` rune.In legacy mode, variables declared at the top level of a component are automatically considered reactive. Reassigning or mutating these variables (count += 1 or object.x = y) will cause the UI to update.<script>\n\tlet count = 0;\n</script>\n\n<button on:click={() => count += 1}>\n\tclicks: {count}\n</button>Because Svelte's legacy mode reactivity is based on assignments, using array methods like .push() and .splice() won't automatically trigger updates. A subsequent assignment is required to 'tell' the compiler to update the UI:<script>\n\tlet numbers = [1, 2, 3, 4];\n\n\tfunction addNumber() {\n\t\t// this method call does not trigger an update\n\t\tnumbers.push(numbers.length + 1);\n\n\t\t// this assignment will update anything\n\t\t// that depends on `numbers`\n\t\tnumbers = numbers;\n\t}\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Reactive $: statements"],"href":"/docs/svelte/legacy-reactive-assignments","content":"In runes mode, reactions to state updates are handled with the `$derived` and `$effect` runes.In legacy mode, any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with a $: label. These statements run after other code in the <script> and before the component markup is rendered, then whenever the values that they depend on change.<script>\n\tlet a = 1;\n\tlet b = 2;\n\n\t// this is a 'reactive statement', and it will re-run\n\t// when `a`, `b` or `sum` change\n\t$: console.log(`${a} + ${b} = ${sum}`);\n\n\t// this is a 'reactive assignment' — `sum` will be\n\t// recalculated when `a` or `b` change. It is\n\t// not necessary to declare `sum` separately\n\t$: sum = a + b;\n</script>Statements are ordered topologically by their dependencies and their assignments: since the console.log statement depends on sum, sum is calculated first even though it appears later in the source.Multiple statements can be combined by putting them in a block: \n$: {\n\t// recalculate `total` when `items` changes\n\ttotal = 0;\n\n\tfor (const item of items) {\n\t\ttotal += item.value;\n\t}\n}The left-hand side of a reactive assignments can be an identifier, or it can be a destructuring assignment: \n$: ({ larry, moe, curly } = stooges);","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Reactive $: statements","Understanding dependencies"],"href":"/docs/svelte/legacy-reactive-assignments#Understanding-dependencies","content":"The dependencies of a $: statement are determined at compile time — they are whichever variables are referenced (but not assigned to) inside the statement.In other words, a statement like this will not re-run when count changes, because the compiler cannot 'see' the dependency: \nlet count = 0;\nlet double = () => count * 2;\n\n$: doubled = double();Similarly, topological ordering will fail if dependencies are referenced indirectly: z will never update, because y is not considered 'dirty' when the update occurs. Moving $: z = y below $: setY(x) will fix it:<script>\n\tlet x = 0;\n\tlet y = 0;\n\n\t$: z = y;\n\t$: setY(x);\n\n\tfunction setY(value) {\n\t\ty = value;\n\t}\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Reactive $: statements","Browser-only code"],"href":"/docs/svelte/legacy-reactive-assignments#Browser-only-code","content":"Reactive statements run during server-side rendering as well as in the browser. This means that any code that should only run in the browser must be wrapped in an if block: \n$: if (browser) {\n\tdocument.title = title;\n}","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","export let"],"href":"/docs/svelte/legacy-export-let","content":"In runes mode, component props are declared with the `$props` rune, allowing parent components to pass in data.In legacy mode, props are marked with the export keyword, and can have a default value:<script>\n\texport let foo;\n\texport let bar = 'default value';\n\n\t// Values that are passed in as props\n\t// are immediately available\n\tconsole.log({ foo });\n</script>The default value is used if it would otherwise be undefined when the component is created.[!NOTE] Unlike in runes mode, if the parent component changes a prop from a defined value to `undefined`, it does not revert to the initial value.Props without default values are considered required, and Svelte will print a warning during development if no value is provided, which you can squelch by specifying undefined as the default value:export let foo +++= undefined;+++","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","export let","Component exports"],"href":"/docs/svelte/legacy-export-let#Component-exports","content":"An exported const, class or function declaration is not considered a prop — instead, it becomes part of the component's API:<!--- file: Greeter.svelte--->\n<script>\n\texport function greet(name) {\n\t\talert(`hello ${name}!`);\n\t}\n</script><!--- file: App.svelte --->\n<script>\n\timport Greeter from './Greeter.svelte';\n\n\tlet greeter;\n</script>\n\n<Greeter bind:this={greeter} />\n\n<button on:click={() => greeter.greet('world')}>\n\tgreet\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","export let","Renaming props"],"href":"/docs/svelte/legacy-export-let#Renaming-props","content":"The export keyword can appear separately from the declaration. This is useful for renaming props, for example in the case of a reserved word:<!--- file: App.svelte --->\n<script>\n\t/** @type {string} */\n\tlet className;\n\n\t// creates a `class` property, even\n\t// though it is a reserved word\n\texport { className as class };\n</script>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","$$props and $$restProps"],"href":"/docs/svelte/legacy-$$props-and-$$restProps","content":"In runes mode, getting an object containing all the props that were passed in is easy, using the `$props` rune.In legacy mode, we use $$props and $$restProps:`$$props` contains all the props that were passed in, including ones that are not individually declared with the `export` keyword\n`$$restProps` contains all the props that were passed in _except_ the ones that were individually declaredFor example, a <Button> component might need to pass along all its props to its own <button> element, except the variant prop:<script>\n\texport let variant;\n</script>\n\n<button {...$$restProps} class=\"variant-{variant} {$$props.class ?? ''}\">\n\tclick me\n</button>\n\n<style>\n\t.variant-danger {\n\t\tbackground: red;\n\t}\n</style>In Svelte 3/4 using $$props and $$restProps creates a modest performance penalty, so they should only be used when needed.","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","on:"],"href":"/docs/svelte/legacy-on","content":"In runes mode, event handlers are just like any other attribute or prop.In legacy mode, we use the on: directive:<!--- file: App.svelte --->\n<script>\n\tlet count = 0;\n\n\t/** @param {MouseEvent} event */\n\tfunction handleClick(event) {\n\t\tcount += 1;\n\t}\n</script>\n\n<button on:click={handleClick}>\n\tcount: {count}\n</button>Handlers can be declared inline with no performance penalty:<button on:click={() => (count += 1)}>\n\tcount: {count}\n</button>Add modifiers to element event handlers with the | character.<form on:submit|preventDefault={handleSubmit}>\n\t<!-- the `submit` event's default is prevented,\n\t     so the page won't reload -->\n</form>The following modifiers are available:`preventDefault` — calls `event.preventDefault()` before running the handler\n`stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element\n`stopImmediatePropagation` — calls `event.stopImmediatePropagation()`, preventing other listeners of the same event from being fired.\n`passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)\n`nonpassive` — explicitly set `passive: false`\n`capture` — fires the handler during the _capture_ phase instead of the _bubbling_ phase\n`once` — remove the handler after the first time it runs\n`self` — only trigger handler if `event.target` is the element itself\n`trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.Modifiers can be chained together, e.g. on:click|once|capture={...}.If the on: directive is used without a value, the component will forward the event, meaning that a consumer of the component can listen for it.<button on:click>\n\tThe component itself will emit the click event\n</button>It's possible to have multiple event listeners for the same event:<!--- file: App.svelte --->\n<script>\n\tlet count = 0;\n\n\tfunction increment() {\n\t\tcount += 1;\n\t}\n\n\t/** @param {MouseEvent} event */\n\tfunction log(event) {\n\t\tconsole.log(event);\n\t}\n</script>\n\n<button on:click={increment} on:click={log}>\n\tclicks: {count}\n</button>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","on:","Component events"],"href":"/docs/svelte/legacy-on#Component-events","content":"Components can dispatch events by creating a dispatcher when they are initialised:<!--- file: Stepper.svelte -->\n<script>\n\timport { createEventDispatcher } from 'svelte';\n\tconst dispatch = createEventDispatcher();\n</script>\n\n<button on:click={() => dispatch('decrement')}>decrement</button>\n<button on:click={() => dispatch('increment')}>increment</button>dispatch creates a `CustomEvent`. If a second argument is provided, it becomes the detail property of the event object.A consumer of this component can listen for the dispatched events:<script>\n\timport Stepper from './Stepper.svelte';\n\n\tlet n = 0;\n</script>\n\n<Stepper\n\ton:decrement={() => n -= 1}\n\ton:increment={() => n += 1}\n/>\n\n<p>n: {n}</p>Component events do not bubble — a parent component can only listen for events on its immediate children.Other than once, modifiers are not valid on component event handlers.[!NOTE]\nIf you're planning an eventual migration to Svelte 5, use callback props instead. This will make upgrading easier as `createEventDispatcher` is deprecated:\n\n```svelte\n<!--- file: Stepper.svelte --->\n<script>\n\texport let decrement;\n\texport let increment;\n</script>\n\n<button on:click={decrement}>decrement</button>\n<button on:click={increment}>increment</button>\n```","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<slot>"],"href":"/docs/svelte/legacy-slots","content":"In Svelte 5, content can be passed to components in the form of snippets and rendered using render tags.In legacy mode, content inside component tags is considered slotted content, which can be rendered by the component using a <slot> element:<!--- file: App.svelte --->\n<script>\n\timport Modal from './Modal.svelte';\n</script>\n\n<Modal>This is some slotted content</Modal><!--- file: Modal.svelte --->\n<div class=\"modal\">\n\t<slot></slot>\n</div>[!NOTE] If you want to render a regular `<slot>` element, you can use `<svelte:element this={'slot'} />`.","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<slot>","Named slots"],"href":"/docs/svelte/legacy-slots#Named-slots","content":"A component can have named slots in addition to the default slot. On the parent side, add a slot=\"...\" attribute to an element, component or `<svelte:fragment>` directly inside the component tags.<!--- file: App.svelte --->\n<script>\n\timport Modal from './Modal.svelte';\n\n\tlet open = true;\n</script>\n\n{#if open}\n\t<Modal>\n\t\tThis is some slotted content\n\n\t\t+++<div slot=\"buttons\">+++\n\t\t\t<button on:click={() => open = false}>\n\t\t\t\tclose\n\t\t\t</button>\n\t\t+++</div>+++\n\t</Modal>\n{/if}On the child side, add a corresponding <slot name=\"...\"> element:<!--- file: Modal.svelte --->\n<div class=\"modal\">\n\t<slot></slot>\n\t<hr>\n\t+++<slot name=\"buttons\"></slot>+++\n</div>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<slot>","Fallback content"],"href":"/docs/svelte/legacy-slots#Fallback-content","content":"If no slotted content is provided, a component can define fallback content by putting it inside the <slot> element:<slot>\n\tThis will be rendered if no slotted content is provided\n</slot>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<slot>","Passing data to slotted content"],"href":"/docs/svelte/legacy-slots#Passing-data-to-slotted-content","content":"Slots can be rendered zero or more times and can pass values back to the parent using props. The parent exposes the values to the slot template using the let: directive.<!--- file: FancyList.svelte --->\n<ul>\n\t{#each items as data}\n\t\t<li class=\"fancy\">\n\t\t\t<!-- 'item' here... -->\n\t\t\t<slot item={process(data)} />\n\t\t</li>\n\t{/each}\n</ul><!--- file: App.svelte --->\n<!-- ...corresponds to 'item' here: -->\n<FancyList {items} let:item={processed}>\n\t<div>{processed.text}</div>\n</FancyList>The usual shorthand rules apply — let:item is equivalent to let:item={item}, and <slot {item}> is equivalent to <slot item={item}>.Named slots can also expose values. The let: directive goes on the element with the slot attribute.<!--- file: FancyList.svelte --->\n<ul>\n\t{#each items as item}\n\t\t<li class=\"fancy\">\n\t\t\t<slot name=\"item\" item={process(data)} />\n\t\t</li>\n\t{/each}\n</ul>\n\n<slot name=\"footer\" /><!--- file: App.svelte --->\n<FancyList {items}>\n\t<div slot=\"item\" let:item>{item.text}</div>\n\t<p slot=\"footer\">Copyright (c) 2019 Svelte Industries</p>\n</FancyList>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","$$slots"],"href":"/docs/svelte/legacy-$$slots","content":"In runes mode, we know which snippets were provided to a component, as they're just normal props.In legacy mode, the way to know if content was provided for a given slot is with the $$slots object, whose keys are the names of the slots passed into the component by the parent.<!--- file: Card.svelte --->\n<div>\n\t<slot name=\"title\" />\n\t{#if $$slots.description}\n\t\t<!-- This <hr> and slot will render only if `slot=\"description\"` is provided. -->\n\t\t<hr />\n\t\t<slot name=\"description\" />\n\t{/if}\n</div><!--- file: App.svelte --->\n<Card>\n\t<h1 slot=\"title\">Blog Post Title</h1>\n\t<!-- No slot named \"description\" was provided so the optional slot will not be rendered. -->\n</Card>","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<svelte:fragment>"],"href":"/docs/svelte/legacy-svelte-fragment","content":"The <svelte:fragment> element allows you to place content in a named slot without wrapping it in a container DOM element. This keeps the flow layout of your document intact.<!--- file: Widget.svelte --->\n<div>\n\t<slot name=\"header\">No header was provided</slot>\n\t<p>Some content between header and footer</p>\n\t<slot name=\"footer\" />\n</div><!--- file: App.svelte --->\n<script>\n\timport Widget from './Widget.svelte';\n</script>\n\n<Widget>\n\t<h1 slot=\"header\">Hello</h1>\n\t<svelte:fragment slot=\"footer\">\n\t\t<p>All rights reserved.</p>\n\t\t<p>Copyright (c) 2019 Svelte Industries</p>\n\t</svelte:fragment>\n</Widget>[!NOTE]\nIn Svelte 5+, this concept is obsolete, as snippets don't create a wrapping element","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<svelte:component>"],"href":"/docs/svelte/legacy-svelte-component","content":"In runes mode, <MyComponent> will re-render if the value of MyComponent changes. See the Svelte 5 migration guide for an example.In legacy mode, it won't — we must use <svelte:component>, which destroys and recreates the component instance when the value of its this expression changes:<svelte:component this={MyComponent} />If this is falsy, no component is rendered.","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","<svelte:self>"],"href":"/docs/svelte/legacy-svelte-self","content":"The <svelte:self> element allows a component to include itself, recursively.It cannot appear at the top level of your markup; it must be inside an if or each block or passed to a component's slot to prevent an infinite loop.<script>\n\texport let count;\n</script>\n\n{#if count > 0}\n\t<p>counting down... {count}</p>\n\t<svelte:self count={count - 1} />\n{:else}\n\t<p>lift-off!</p>\n{/if}[!NOTE]\nThis concept is obsolete, as components can import themselves:\n```svelte\n<!--- file: App.svelte --->\n<script>\n\timport Self from './App.svelte'\n\texport let count;\n</script>\n\n{#if count > 0}\n\t<p>counting down... {count}</p>\n\t<Self count={count - 1} />\n{:else}\n\t<p>lift-off!</p>\n{/if}\n```","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API"],"href":"/docs/svelte/legacy-component-api","content":"In Svelte 3 and 4, the API for interacting with a component is different than in Svelte 5. Note that this page does not apply to legacy mode components in a Svelte 5 application.","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","Creating a component"],"href":"/docs/svelte/legacy-component-api#Creating-a-component","content":"const component = new Component(options);A client-side component — that is, a component compiled with generate: 'dom' (or the generate option left unspecified) is a JavaScript class. \nimport App from './App.svelte';\n\nconst app = new App({\n\ttarget: document.body,\n\tprops: {\n\t\t// assuming App.svelte contains something like\n\t\t// `export let answer`:\n\t\tanswer: 42\n\t}\n});The following initialisation options can be provided:option ,default ,description \n`target` ,**none** ,An `HTMLElement` or `ShadowRoot` to render to. This option is required \n`anchor` ,`null` ,A child of `target` to render the component immediately before \n`props` ,`{}` ,An object of properties to supply to the component \n`context` ,`new Map()` ,A `Map` of root-level context key-value pairs to supply to the component \n`hydrate` ,`false` ,See below \n`intro` ,`false` ,If `true`, will play transitions on initial render, rather than waiting for subsequent state changes Existing children of target are left where they are.The hydrate option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the `hydratable: true` option. Hydration of <head> elements only works properly if the server-side rendering code was also compiled with hydratable: true, which adds a marker to each element in the <head> so that the component knows which elements it's responsible for removing during hydration.Whereas children of target are normally left alone, hydrate: true will cause any children to be removed. For that reason, the anchor option cannot be used alongside hydrate: true.The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes. \n \nimport App from './App.svelte';\n\nconst app = new App({\n\ttarget: document.querySelector('#server-rendered-html'),\n\thydrate: true\n});[!NOTE]\nIn Svelte 5+, use [`mount`](svelte#mount) instead","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","$set"],"href":"/docs/svelte/legacy-component-api#$set","content":"component.$set(props);Programmatically sets props on an instance. component.$set({ x: 1 }) is equivalent to x = 1 inside the component's <script> block.Calling this method schedules an update for the next microtask — the DOM is not updated synchronously. \ncomponent.$set({ answer: 42 });[!NOTE]\nIn Svelte 5+, use `$state` instead to create a component props and update that\n\n```js\n// @noErrors\nlet props = $state({ answer: 42 });\nconst component = mount(Component, { props });\n// ...\nprops.answer = 24;\n```","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","$on"],"href":"/docs/svelte/legacy-component-api#$on","content":"component.$on(ev, callback);Causes the callback function to be called whenever the component dispatches an event.A function is returned that will remove the event listener when called. \nconst off = component.$on('selected', (event) => {\n\tconsole.log(event.detail.selection);\n});\n\noff();[!NOTE]\nIn Svelte 5+, pass callback props instead","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","$destroy"],"href":"/docs/svelte/legacy-component-api#$destroy","content":"component.$destroy();Removes a component from the DOM and triggers any onDestroy handlers.[!NOTE]\nIn Svelte 5+, use [`unmount`](svelte#unmount) instead","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","Component props"],"href":"/docs/svelte/legacy-component-api#Component-props","content":"component.prop; \ncomponent.prop = value;If a component is compiled with accessors: true, each instance will have getters and setters corresponding to each of the component's props. Setting a value will cause a synchronous update, rather than the default async update caused by component.$set(...).By default, accessors is false, unless you're compiling as a custom element. \nconsole.log(component.count);\ncomponent.count += 1;[!NOTE]\nIn Svelte 5+, this concept is obsolete. If you want to make properties accessible from the outside, `export` them","rank":null},{"breadcrumbs":["Docs","Svelte","Legacy APIs","Imperative component API","Server-side component API"],"href":"/docs/svelte/legacy-component-api#Server-side-component-API","content":"const result = Component.render(...)Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.A server-side component exposes a render method that can be called with optional props. It returns an object with head, html, and css properties, where head contains the contents of any <svelte:head> elements encountered.You can import a Svelte component directly into Node using svelte/register. \nrequire('svelte/register');\n\nconst App = require('./App.svelte').default;\n\nconst { head, html, css } = App.render({\n\tanswer: 42\n});The .render() method accepts the following parameters:parameter ,default ,description \n`props` ,`{}` ,An object of properties to supply to the component \n`options` ,`{}` ,An object of options The options object takes in the following options:option ,default ,description \n`context` ,`new Map()` ,A `Map` of root-level context key-value pairs to supply to the component  \nconst { head, html, css } = App.render(\n\t// props\n\t{ answer: 42 },\n\t// options\n\t{\n\t\tcontext: new Map([['context-key', 'context-value']])\n\t}\n);[!NOTE]\nIn Svelte 5+, use [`render`](svelte-server#render) instead","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Welcome to Svelte"],"href":"/tutorial/svelte/welcome-to-svelte","content":"Welcome to the Svelte tutorial! This will teach you everything you need to know to easily build web applications of all sizes, with high performance and a small footprint.You can also consult the API docs and visit the playground, or — if you're impatient to start hacking on your machine locally — create a project with npx sv create.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Welcome to Svelte","What is Svelte?"],"href":"/tutorial/svelte/welcome-to-svelte#What-is-Svelte","content":"Svelte is a tool for building web applications. Like other user interface frameworks, it allows you to build your app declaratively out of components that combine markup, styles and behaviours.These components are compiled into small, efficient JavaScript modules that eliminate overhead traditionally associated with UI frameworks.You can build your entire app with Svelte (for example, using an application framework like SvelteKit, which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Welcome to Svelte","How to use this tutorial"],"href":"/tutorial/svelte/welcome-to-svelte#How-to-use-this-tutorial","content":"[!NOTE] You'll need to have basic familiarity with HTML, CSS and JavaScript to understand Svelte.This tutorial is split into four main parts:[Basic Svelte](/tutorial/svelte/welcome-to-svelte) (you are here)\n[Advanced Svelte](/tutorial/svelte/tweens)\n[Basic SvelteKit](/tutorial/kit/introducing-sveltekit)\n[Advanced SvelteKit](/tutorial/kit/optional-params)Each section will present an exercise designed to illustrate a feature. Later exercises build on the knowledge gained in earlier ones, so it's recommended that you go from start to finish. If necessary, you can navigate via the menu above.If you get stuck, you can click the solve button in the top right of the screen. (The solve button is disabled on sections like this one that don't include an exercise.) Try not to rely on it too much; you will learn faster by figuring out where to put each suggested code block and manually typing it in to the editor.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Your first component"],"href":"/tutorial/svelte/your-first-component","content":"In Svelte, an application is composed from one or more components. A component is a reusable self-contained block of code that encapsulates HTML, CSS and JavaScript that belong together, written into a .svelte file. The App.svelte file, open in the code editor to the right, is a simple component.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Your first component","Adding data"],"href":"/tutorial/svelte/your-first-component#Adding-data","content":"A component that just renders some static markup isn't very interesting. Let's add some data.First, add a script tag to your component and declare a name variable: \n+++<script>\n\tlet name = 'Svelte';\n</script>+++\n\n<h1>Hello world!</h1>Then, we can refer to name in the markup: \n<h1>Hello +++{name}+++!</h1>Inside the curly braces, we can put any JavaScript we want. Try changing name to name.toUpperCase() for a shoutier greeting. \n<h1>Hello {name+++.toUpperCase()+++}!</h1>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Dynamic attributes"],"href":"/tutorial/svelte/dynamic-attributes","content":"Just like you can use curly braces to control text, you can use them to control element attributes.Our image is missing a src — let's add one: \n<img +++src={src}+++ />That's better. But if you hover over the <img> in the editor, Svelte is giving us a warning:`<img>` element should have an alt attributeWhen building web apps, it's important to make sure that they're accessible to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.In this case, we're missing the alt attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one: \n<img src={src} +++alt=\"A man dances.\"+++ />We can use curly braces inside attributes. Try changing it to \"{name} dances.\" — remember to declare a name variable in the <script> block.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Dynamic attributes","Shorthand attributes"],"href":"/tutorial/svelte/dynamic-attributes#Shorthand-attributes","content":"It's not uncommon to have an attribute where the name and value are the same, like src={src}. Svelte gives us a convenient shorthand for these cases: \n<img +++{src}+++ alt=\"{name} dances.\" />","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Styling"],"href":"/tutorial/svelte/styling","content":"Just like in HTML, you can add a <style> tag to your component. Let's add some styles to the <p> element: \n<p>This is a paragraph.</p>\n\n<style>\n+++\tp {\n\t\tcolor: goldenrod;\n\t\tfont-family: 'Comic Sans MS', cursive;\n\t\tfont-size: 2em;\n\t}+++\n</style>Importantly, these rules are scoped to the component. You won't accidentally change the style of <p> elements elsewhere in your app, as we'll see in the next step.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","Nested components"],"href":"/tutorial/svelte/nested-components","content":"It would be impractical to put your entire app in a single component. Instead, we can import components from other files and include them in our markup.Add a <script> tag to the top of App.svelte that imports Nested.svelte... \n+++<script>\n\timport Nested from './Nested.svelte';\n</script>+++...and include a <Nested /> component: \n<p>This is a paragraph.</p>\n+++<Nested />+++Notice that even though Nested.svelte has a <p> element, the styles from App.svelte don't leak in.[!NOTE] Component names are capitalised, to distinguish them from HTML elements.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Introduction","HTML tags"],"href":"/tutorial/svelte/html-tags","content":"Ordinarily, strings are inserted as plain text, meaning that characters like < and > have no special meaning.But sometimes you need to render HTML directly into a component. For example, the words you're reading right now exist in a markdown file that gets included on this page as a blob of HTML.In Svelte, you do this with the special {@html ...} tag: \n<p>{+++@html+++ string}</p>[!NOTE] Important: Svelte doesn't perform any sanitization of the expression inside `{@html ...}` before it gets inserted into the DOM. This isn't an issue if the content is something you trust like an article you wrote yourself. However if it's some untrusted user content, e.g. a comment on an article, then it's critical that you manually escape it, otherwise you risk exposing your users to <a href=\"https://owasp.org/www-community/attacks/xss/\" target=\"_blank\">Cross-Site Scripting</a> (XSS) attacks.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","State"],"href":"/tutorial/svelte/state","content":"At the heart of Svelte is a powerful system of reactivity for keeping the DOM in sync with your application state — for example, in response to an event.Make the count declaration reactive by wrapping the value with $state(...): \nlet count = +++$state(0)+++;This is called a rune, and it's how you tell Svelte that count isn't an ordinary variable. Runes look like functions, but they're not — when you use Svelte, they're part of the language itself.All that's left is to implement increment: \nfunction increment() {\n\t+++count += 1;+++\n}","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","Deep state"],"href":"/tutorial/svelte/deep-state","content":"As we saw in the previous exercise, state reacts to reassignments. But it also reacts to mutations — we call this deep reactivity.Make numbers a reactive array: \nlet numbers = +++$state([1, 2, 3, 4])+++;Now, when we change the array... \nfunction addNumber() {\n\t+++numbers[numbers.length] = numbers.length + 1;+++\n}...the component updates. Or better still, we can push to the array instead: \nfunction addNumber() {\n\t+++numbers.push(numbers.length + 1);+++\n}[!NOTE] Deep reactivity is implemented using [proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and mutations to the proxy do not affect the original object.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","Derived state"],"href":"/tutorial/svelte/derived-state","content":"Often, you will need to derive state from other state. For this, we have the $derived rune: \nlet numbers = $state([1, 2, 3, 4]);\n+++let total = $derived(numbers.reduce((t, n) => t + n, 0));+++We can now use this in our markup: \n<p>{numbers.join(' + ')} = +++{total}+++</p>The expression inside the $derived declaration will be re-evaluated whenever its dependencies (in this case, just numbers) are updated.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","Inspecting state"],"href":"/tutorial/svelte/inspecting-state","content":"It's often useful to be able to track the value of a piece of state as it changes over time.Inside the addNumber function, we've added a console.log statement. But if you click the button and open the console drawer (using the button to the right of the URL bar), you'll see a warning, and a message saying the message could not be cloned.That's because numbers is a reactive proxy. There are a couple of things we can do. Firstly, we can create a non-reactive snapshot of the state with $state.snapshot(...): \nfunction addNumber() {\n\tnumbers.push(numbers.length + 1);\n\tconsole.log(+++$state.snapshot(numbers)+++);\n}Alternatively, we can use the $inspect rune to automatically log a snapshot of the state whenever it changes. This code will automatically be stripped out of your production build: \nfunction addNumber() {\n\tnumbers.push(numbers.length + 1);\n\t---console.log($state.snapshot(numbers));---\n}\n\n+++$inspect(numbers);+++You can customise how the information is displayed by using $inspect(...).with(fn) — for example, you can use console.trace to see where the state change originated from: \n$inspect(numbers)+++.with(console.trace)+++;","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","Effects"],"href":"/tutorial/svelte/effects","content":"So far we've talked about reactivity in terms of state. But that's only half of the equation — state is only reactive if something is reacting to it, otherwise it's just a sparkling variable.The thing that reacts is called an effect. You've already encountered effects — the ones that Svelte creates on your behalf to update the DOM in response to state changes — but you can also create your own with the $effect rune.[!NOTE] Most of the time, you shouldn't. `$effect` is best thought of as an escape hatch, rather than something to use frequently. If you can put your side effects in an [event handler](dom-events), for example, that's almost always preferable.Let's say we want to use setInterval to keep track of how long the component has been mounted. Create the effect: \n<script>\n\tlet elapsed = $state(0);\n\tlet interval = $state(1000);\n\n+++\t$effect(() => {\n\t\tsetInterval(() => {\n\t\t\telapsed += 1;\n\t\t}, interval);\n\t});+++\n</script>Click the 'speed up' button a few times and notice that elapsed ticks up faster, because we're calling setInterval each time interval gets smaller.If we then click the 'slow down' button... well, it doesn't work. That's because we're not clearing out the old intervals when the effect updates. We can fix that by returning a cleanup function: \n$effect(() => {\n\t+++const id =+++ setInterval(() => {\n\t\telapsed += 1;\n\t}, interval);\n\n+++\treturn () => {\n\t\tclearInterval(id);\n\t};+++\n});The cleanup function is called immediately before the effect function re-runs when interval changes, and also when the component is destroyed.If the effect function doesn't read any state when it runs, it will only run once, when the component mounts.[!NOTE] Effects do not run during server-side rendering.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Reactivity","Universal reactivity"],"href":"/tutorial/svelte/universal-reactivity","content":"In the preceding exercises, we used runes to add reactivity inside components. But we can also use runes outside components, for example to share some global state.The <Counter> components in this exercise are all importing the counter object from shared.js. But it's a normal object, and so nothing happens when you click the buttons. Wrap the object in $state(...): \nexport const counter = +++$state({+++\n\tcount: 0\n+++})+++;This causes an error, because you can't use runes in normal .js files, only .svelte.js files. Let's fix that — rename the file to shared.svelte.js.Then, update the import declaration in Counter.svelte: \n<script>\n\timport { counter } from './shared+++.svelte+++.js';\n</script>Now, when you click any button, all three update simultaneously.[!NOTE] You cannot export a `$state` declaration from a module if the declaration is reassigned (rather than just mutated), because the importers would have no way to know about it.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Props","Declaring props"],"href":"/tutorial/svelte/declaring-props","content":"So far, we've dealt exclusively with internal state — that is to say, the values are only accessible within a given component.In any real application, you'll need to pass data from one component down to its children. To do that, we need to declare properties, generally shortened to 'props'. In Svelte, we do that with the $props rune. Edit the Nested.svelte component: \n<script>\n\tlet { answer } = +++$props()+++;\n</script>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Props","Default values"],"href":"/tutorial/svelte/default-values","content":"We can easily specify default values for props in Nested.svelte: \n<script>\n\tlet { answer +++= 'a mystery'+++ } = $props();\n</script>If we now add a second component without an answer prop, it will fall back to the default: \n<Nested answer={42}/>\n+++<Nested />+++","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Props","Spread props"],"href":"/tutorial/svelte/spread-props","content":"In this exercise, in App.svelte we've forgotten to pass the name prop expected by PackageInfo.svelte, meaning the <code> element is empty and the npm link is broken.We could fix it by adding the prop... \n<PackageInfo\n\t+++name={pkg.name}+++\n\tversion={pkg.version}\n\tdescription={pkg.description}\n\twebsite={pkg.website}\n/>...but since the properties of pkg correspond to the component's expected props, we can 'spread' them onto the component instead: \n<PackageInfo +++{...pkg}+++ />[!NOTE] Conversely, in `PackageInfo.svelte` you can get an object containing all the props that were passed into a component using a rest property...\n\n```js\nlet { name, ...stuff } = $props();\n```\n\n...or by skipping [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) altogether:\n\n```js\nlet stuff = $props();\n```\n\n...in which case you can access the properties by their object paths:\n\n```js\nconsole.log(stuff.name, stuff.version, stuff.description, stuff.website);\n```","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","If blocks"],"href":"/tutorial/svelte/if-blocks","content":"HTML doesn't have a way of expressing logic, like conditionals and loops. Svelte does.To conditionally render some markup, we wrap it in an if block. Let's add some text that appears when count is greater than 10: \n<button onclick={increment}>\n\tClicked {count}\n\t{count === 1 ? 'time' : 'times'}\n</button>\n\n+++{#if count > 10}\n\t<p>{count} is greater than 10</p>\n{/if}+++Try it — update the component, and click on the button a few times.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","Else blocks"],"href":"/tutorial/svelte/else-blocks","content":"Just like in JavaScript, an if block can have an else block: \n{#if count > 10}\n\t<p>{count} is greater than 10</p>\n+++{:else}\n\t<p>{count} is between 0 and 10</p>+++\n{/if}{#...} opens a block. {/...} closes a block. {:...} continues a block. Congratulations — you've already learned almost all the syntax Svelte adds to HTML.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","Else-if blocks"],"href":"/tutorial/svelte/else-if-blocks","content":"Multiple conditions can be 'chained' together with else if: \n{#if count > 10}\n\t<p>{count} is greater than 10</p>\n+++{:else if count < 5}\n\t<p>{count} is less than 5</p>+++\n{:else}\n\t<p>{count} is between +++5+++ and 10</p>\n{/if}","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","Each blocks"],"href":"/tutorial/svelte/each-blocks","content":"When building user interfaces you'll often find yourself working with lists of data. In this exercise, we've repeated the <button> markup multiple times — changing the colour each time — but there's still more to add.Instead of laboriously copying, pasting and editing, we can get rid of all but the first button, then use an each block: \n<div>\n\t+++{#each colors as color}+++\n\t\t<button\n\t\t\tstyle=\"background: red\"\n\t\t\taria-label=\"red\"\n\t\t\taria-current={selected === 'red'}\n\t\t\tonclick={() => selected = 'red'}\n\t\t></button>\n\t+++{/each}+++\n</div>[!NOTE] The expression (`colors`, in this case) can be any iterable or array-like object — in other words, anything that works with [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from).Now we need to use the color variable in place of \"red\": \n<div>\n\t{#each colors as color}\n\t\t<button\n\t\t\tstyle=\"background: +++{color}+++\"\n\t\t\taria-label=+++{color}+++\n\t\t\taria-current={selected === +++color+++}\n\t\t\tonclick={() => selected = +++color+++}\n\t\t></button>\n\t{/each}\n</div>You can get the current index as a second argument, like so: \n<div>\n\t{#each colors as color, +++i}+++\n\t\t<button\n\t\t\tstyle=\"background: {color}\"\n\t\t\taria-label={color}\n\t\t\taria-current={selected === color}\n\t\t\tonclick={() => selected = color}\n\t\t>+++{i + 1}+++</button>\n\t{/each}\n</div>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","Keyed each blocks"],"href":"/tutorial/svelte/keyed-each-blocks","content":"By default, updating the value of an each block will add or remove DOM nodes at the end of the block if the size changes, and update the remaining DOM. That might not be what you want.It's easier to show why than to explain. Inside Thing.svelte, name is a dynamic prop but emoji is a constant.Click the 'Remove first thing' button a few times, and notice what happens:It removes the last component.\nIt then updates the `name` value in the remaining DOM nodes (the text node containing 'doughnut' now contains 'egg', and so on), but not the emoji.[!NOTE] If you're coming from React, this might seem strange, because you're used to the entire component re-rendering when state changes. Svelte works differently: the component 'runs' once, and subsequent updates are 'fine-grained'. This makes things faster and gives you more control.One way to fix it would be to make emoji a `$derived` value. But it makes more sense to remove the first <Thing> component altogether rather than remove the last one and update all the others.To do that, we specify a unique key for each iteration of the each block: \n{#each things as thing (+++thing.id+++)}\n\t<Thing name={thing.name}/>\n{/each}[!NOTE] You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(thing)` instead of `(thing.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Logic","Await blocks"],"href":"/tutorial/svelte/await-blocks","content":"Most web applications have to deal with asynchronous data at some point. Svelte makes it easy to await the value of promises directly in your markup: \n+++{#await promise}+++\n\t<p>...rolling</p>\n+++{:then number}\n\t<p>you rolled a {number}!</p>\n{:catch error}\n\t<p style=\"color: red\">{error.message}</p>\n{/await}+++[!NOTE] Only the most recent `promise` is considered, meaning you don't need to worry about race conditions.If you know that your promise can't reject, you can omit the catch block. You can also omit the first block if you don't want to show anything until the promise resolves:{#await promise then number}\n\t<p>you rolled a {number}!</p>\n{/await}","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Events","DOM events"],"href":"/tutorial/svelte/dom-events","content":"As we've briefly seen already, you can listen to any DOM event on an element (such as click or pointermove) with an on<name> function: \n<div +++onpointermove={onpointermove}+++ role=\"presentation\">\n\tThe pointer is at {Math.round(m.x)} x {Math.round(m.y)}\n</div>Like with any other property where the name matches the value, we can use the short form: \n<div +++{onpointermove}+++ role=\"presentation\">\n\tThe pointer is at {Math.round(m.x)} x {Math.round(m.y)}\n</div>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Events","Inline handlers"],"href":"/tutorial/svelte/inline-handlers","content":"You can also declare event handlers inline: \n<script>\n\tlet m = $state({ x: 0, y: 0 });\n\n\t---function onpointermove(event) {\n\t\tm.x = event.clientX;\n\t\tm.y = event.clientY;\n\t}---\n</script>\n\n<div\n\tonpointermove={+++(event) => {\n\t\tm.x = event.clientX;\n\t\tm.y = event.clientY;\n\t}+++}\n\trole=\"presentation\"\n>\n\tThe pointer is at {m.x} x {m.y}\n</div>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Events","Capturing"],"href":"/tutorial/svelte/capturing","content":"Normally, event handlers run during the _bubbling_ phase. Notice what happens if you type something into the <input> in this example — the inner handler runs first, as the event 'bubbles' from the target up to the document, followed by the outer handler.Sometimes, you want handlers to run during the capture phase instead. Add capture to the end of the event name: \n<div onkeydown+++capture+++={(e) => alert(`<div> ${e.key}`)} role=\"presentation\">\n\t<input onkeydown+++capture+++={(e) => alert(`<input> ${e.key}`)} />\n</div>Now, the relative order is reversed. If both capturing and non-capturing handlers exist for a given event, the capturing handlers will run first.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Events","Component events"],"href":"/tutorial/svelte/component-events","content":"You can pass event handlers to components like any other prop. In Stepper.svelte, add increment and decrement props... \n<script>\n\tlet +++{ increment, decrement }+++ = $props();\n</script>...and wire them up: \n<button +++onclick={decrement}+++>-1</button>\n<button +++onclick={increment}+++>+1</button>In App.svelte, define the handlers: \n<Stepper\n\t+++increment={() => value += 1}+++\n\t+++decrement={() => value -= 1}+++\n/>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Events","Spreading events"],"href":"/tutorial/svelte/spreading-events","content":"We can also spread event handlers directly onto elements. Here, we've defined an onclick handler in App.svelte — all we need to do is pass the props to the <button> in BigRedButton.svelte: \n<button +++{...props}+++>\n\tPush\n</button>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Text inputs"],"href":"/tutorial/svelte/text-inputs","content":"As a general rule, data flow in Svelte is top down — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.Sometimes it's useful to break that rule. Take the case of the <input> element in this component — we could add an oninput event handler that sets the value of name to event.target.value, but it's a bit... boilerplatey. It gets even worse with other form elements, as we'll see.Instead, we can use the bind:value directive: \n<input +++bind:+++value={name}>This means that as well as changes to name updating the <input>, changes to the <input> will update name.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Numeric inputs"],"href":"/tutorial/svelte/numeric-inputs","content":"In the DOM, every input value is a string. That's unhelpful when you're dealing with numeric inputs — type=\"number\" and type=\"range\" — as it means you have to remember to coerce input.value before using it.With bind:value, Svelte takes care of it for you: \n<label>\n\t<input type=\"number\" +++bind:+++value={a} min=\"0\" max=\"10\" />\n\t<input type=\"range\" +++bind:+++value={a} min=\"0\" max=\"10\" />\n</label>\n\n<label>\n\t<input type=\"number\" +++bind:+++value={b} min=\"0\" max=\"10\" />\n\t<input type=\"range\" +++bind:+++value={b} min=\"0\" max=\"10\" />\n</label>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Checkbox inputs"],"href":"/tutorial/svelte/checkbox-inputs","content":"Checkboxes are used for toggling between states. Instead of binding to input.value, we bind to input.checked: \n<input type=\"checkbox\" +++bind:+++checked={yes}>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Select bindings"],"href":"/tutorial/svelte/select-bindings","content":"We can also use bind:value with <select> elements: \n<select\n    +++bind:+++value={selected}\n    onchange={() => answer = ''}\n>Note that the <option> values are objects rather than strings. Svelte doesn't mind.[!NOTE] Because we haven't set an initial value of `selected`, the binding will set it to the default value (the first in the list) automatically. Be careful though — until the binding is initialised, `selected` remains undefined, so we can't blindly reference e.g. `selected.id` in the template.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Group inputs"],"href":"/tutorial/svelte/group-inputs","content":"If you have multiple type=\"radio\" or type=\"checkbox\" inputs relating to the same value, you can use bind:group along with the value attribute. Radio inputs in the same group are mutually exclusive; checkbox inputs in the same group form an array of selected values.Add bind:group={scoops} to the radio inputs... \n<input\n\ttype=\"radio\"\n\tname=\"scoops\"\n\tvalue={number}\n\t+++bind:group={scoops}+++\n/>...and bind:group={flavours} to the checkbox inputs: \n<input\n\ttype=\"checkbox\"\n\tname=\"flavours\"\n\tvalue={flavour}\n\t+++bind:group={flavours}+++\n/>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Select multiple"],"href":"/tutorial/svelte/multiple-select-bindings","content":"A <select> element can have a multiple attribute, in which case it will populate an array rather than selecting a single value.Replace the checkboxes with a <select multiple>: \n<h2>Flavours</h2>\n\n+++<select multiple bind:value={flavours}>+++\n\t{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}\n+++\t\t<option>{flavour}</option>+++\n\t{/each}\n+++</select>+++Note that we're able to omit the value attribute on the <option>, since the value is identical to the element's contents.[!NOTE] Press and hold the `control` key (or the `command` key on MacOS) to select multiple options.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Bindings","Textarea inputs"],"href":"/tutorial/svelte/textarea-inputs","content":"The <textarea> element behaves similarly to a text input in Svelte — use bind:value: \n<textarea +++bind:value=+++{value}></textarea>In cases like these, where the names match, we can also use a shorthand form: \n<textarea +++bind:value+++></textarea>This applies to all bindings, not just <textarea> bindings.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Classes and styles","The class attribute"],"href":"/tutorial/svelte/classes","content":"Like any other attribute, you can specify classes with a JavaScript attribute. Here, we could add a flipped class to the card: \n<button\n\tclass=\"card {+++flipped ? 'flipped' : ''+++}\"\n\tonclick={() => flipped = !flipped}\n>This works as expected — if you click on the card now, it'll flip.We can make it nicer though. Adding or removing a class based on some condition is such a common pattern in UI development that Svelte allows you to pass an object or array that is converted to a string by clsx. \n<button\n\t+++class={[\"card\", { flipped }]}+++\n\tonclick={() => flipped = !flipped}\n>This means 'always add the card class, and add the flipped class whenever flipped is truthy'.For more examples of how to combine conditional classes, consult the `class` documentation.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Classes and styles","The style directive"],"href":"/tutorial/svelte/styles","content":"As with class, you can write your inline style attributes literally, because Svelte is really just HTML with fancy bits: \n<button\n\tclass=\"card\"\n\t+++style=\"transform: {flipped ? 'rotateY(0)' : ''}; --bg-1: palegoldenrod; --bg-2: black; --bg-3: goldenrod\"+++\n\tonclick={() => flipped = !flipped}\n>When you have a lot of styles, it can start to look a bit wacky. We can tidy things up by using the style: directive: \n<button\n\tclass=\"card\"\n+++\tstyle:transform={flipped ? 'rotateY(0)' : ''}\n\tstyle:--bg-1=\"palegoldenrod\"\n\tstyle:--bg-2=\"black\"\n\tstyle:--bg-3=\"goldenrod\"+++\n\tonclick={() => flipped = !flipped}\n>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Classes and styles","Component styles"],"href":"/tutorial/svelte/component-styles","content":"Often, you need to influence the styles inside a child component. Perhaps we want to make these boxes red, green and blue.One way to do this is with the :global CSS modifier, which allows you to indiscriminately target elements inside other components: \n<style>\n\t.boxes :global(.box:nth-child(1)) {\n\t\tbackground-color: red;\n\t}\n\n\t.boxes :global(.box:nth-child(2)) {\n\t\tbackground-color: green;\n\t}\n\n\t.boxes :global(.box:nth-child(3)) {\n\t\tbackground-color: blue;\n\t}\n</style>But there are lots of reasons not to do that. For one thing, it's extremely verbose. For another, it's brittle — any changes to the implementation details of Box.svelte could break the selector.Most of all though, it's rude. Components should be able to decide for themselves which styles can be controlled from 'outside', in the same way they decide which variables are exposed as props. :global should be used as an escape hatch — a last resort.Inside Box.svelte, change background-color so that it is determined by a CSS custom property: \n<style>\n\t.box {\n\t\twidth: 5em;\n\t\theight: 5em;\n\t\tborder-radius: 0.5em;\n\t\tmargin: 0 0 1em 0;\n\t\tbackground-color: +++var(--color, #ddd)+++;\n\t}\n</style>Any parent element (such as <div class=\"boxes\">) can set the value of --color, but we can also set it on individual components: \n<div class=\"boxes\">\n\t<Box +++--color=\"red\"+++ />\n\t<Box +++--color=\"green\"+++ />\n\t<Box +++--color=\"blue\"+++ />\n</div>The values can be dynamic, like any other attribute.[!NOTE] This feature works by wrapping each component in an element with `display: contents`, where needed, and applying the custom properties to it. If you inspect the elements, you'll see markup like this:\n\n```svelte\n<svelte-css-wrapper style=\"display: contents; --color: red;\">\n\t<!-- contents -->\n</svelte-css-wrapper>\n```\n\nBecause of `display: contents` this won't affect your layout, but the extra element _can_ affect selectors like `.parent > .child`.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Attachments","The attach tag"],"href":"/tutorial/svelte/attach","content":"Attachments are essentially element-level lifecycle functions. They're useful for things like:interfacing with third-party libraries\nlazy-loaded images\ntooltips\nadding custom event handlersIn this app, you can scribble on the <canvas>, and change colours and brush size via the menu. But if you open the menu and cycle through the options with the Tab key, you'll soon find that the focus isn't trapped inside the modal.[!NOTE] Safari only focuses text fields and pop-up menus with the Tab key by default. To follow this exercise in Safari, use Option + Tab or enable Tab to highlight in Safari's advanced settings.We can fix that with an attachment. Import trapFocus from attachments.svelte.js... \n<script>\n\timport Canvas from './Canvas.svelte';\n\t+++import { trapFocus } from './attachments.svelte.js';+++\n\n\tconst colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet', 'white', 'black'];\n\n\tlet selected = $state(colors[0]);\n\tlet size = $state(10);\n\tlet showMenu = $state(true);\n</script>...then add it to the menu with the {@attach} tag: \n<div class=\"menu\" +++{@attach trapFocus}+++>Let's take a look at the trapFocus function in attachments.svelte.js. An attachment function is called with a node — the <div class=\"menu\"> in our case — when the node is mounted to the DOM. Attachments run inside an effect, so they re-run whenever any state read inside the function changes.First, we need to add an event listener that intercepts Tab key presses: \nfocusable()[0]?.focus();\n+++const off = on(node, 'keydown', handleKeydown);+++[!NOTE] [`on`](/docs/svelte/svelte-events#on) is a wrapper around `addEventListener` that uses <a href=\"/docs/svelte/basic-markup#Events-Event-delegation\">event delegation</a>. It returns a function that removes the handler.Second, we need to do some cleanup when the node is unmounted — removing the event listener, and restoring focus to where it was before the element mounted. As with effects, an attachment can return a teardown function, which runs immediately before the attachment re-runs or after the element is removed from the DOM: \nfocusable()[0]?.focus();\nconst off = on(node, 'keydown', handleKeydown);\n\n+++return () => {\n\toff();\n\tprevious?.focus();\n};+++Now, when you open the menu, you can cycle through the options with the Tab key.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Attachments","Attachment factories"],"href":"/tutorial/svelte/attachment-factories","content":"Often, you need an attachment to depend on some parameters or component state. In this scenario, you can use an attachment factory — a function that returns an attachment.In this exercise, we want to add a tooltip to the <button> using the `Tippy.js` library. The attachment is already wired up with {@attach tooltip}, but if you hover over the button (or focus it with the keyboard) the tooltip contains no content.First, we need to convert our simple attachment into a factory function that returns an attachment. \nfunction tooltip(---node---) {\n+++\treturn (node) => {+++\n\t\tconst tooltip = tippy(node);\n\t\treturn tooltip.destroy;\n+++\t};+++\n}Next, the factory needs to accept the options we want to pass to Tippy (in this case just content): \nfunction tooltip(+++content+++) {\n\treturn (node) => {\n\t\tconst tooltip = tippy(node+++, { content }+++);\n\t\treturn tooltip.destroy;\n\t};\n}[!NOTE] The `tooltip(content)` expression runs inside an effect, so the attachment is destroyed and recreated whenever content changes.Finally, we need to call the attachment factory and pass the content argument in our {@attach} tag: \n<button {@attach tooltip+++(content)+++}>\n\tHover me\n</button>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","The transition directive"],"href":"/tutorial/svelte/transition","content":"We can make more appealing user interfaces by gracefully transitioning elements into and out of the DOM. Svelte makes this very easy with the transition directive.First, import the fade function from svelte/transition... \n<script>\n\t+++import { fade } from 'svelte/transition';+++\n\n\tlet visible = $state(true);\n</script>...then add it to the <p> element: \n<p +++transition:fade+++>\n\tFades in and out\n</p>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Adding parameters"],"href":"/tutorial/svelte/adding-parameters-to-transitions","content":"Transition functions can accept parameters. Replace the fade transition with fly... \n<script>\n\timport { +++fly+++ } from 'svelte/transition';\n\n\tlet visible = $state(true);\n</script>...and apply it to the <p> along with some options: \n<p transition:+++fly={{ y: 200, duration: 2000 }}+++>\n\t+++Flies+++ in and out\n</p>Note that the transition is reversible — if you toggle the checkbox while the transition is ongoing, it transitions from the current point, rather than the beginning or the end.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","In and out"],"href":"/tutorial/svelte/in-and-out","content":"Instead of the transition directive, an element can have an in or an out directive, or both together. Import fade alongside fly... \nimport { +++fade+++, fly } from 'svelte/transition';...then replace the transition directive with separate in and out directives: \n<p +++in+++:fly={{ y: 200, duration: 2000 }} +++out:fade+++>\n\tFlies in, +++fades out+++\n</p>In this case, the transitions are not reversed.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Custom CSS transitions"],"href":"/tutorial/svelte/custom-css-transitions","content":"The svelte/transition module has a handful of built-in transitions, but it's very easy to create your own. By way of example, this is the source of the fade transition:function fade(node, { delay = 0, duration = 400 }) {\n\tconst o = +getComputedStyle(node).opacity;\n\n\treturn {\n\t\tdelay,\n\t\tduration,\n\t\tcss: (t) => `opacity: ${t * o}`\n\t};\n}The function takes two arguments — the node to which the transition is applied, and any parameters that were passed in — and returns a transition object which can have the following properties:`delay` — milliseconds before the transition begins\n`duration` — length of the transition in milliseconds\n`easing` — a `p => t` easing function (see the chapter on [tweening](/tutorial/svelte/tweens))\n`css` — a `(t, u) => css` function, where `u === 1 - t`\n`tick` — a `(t, u) => {...}` function that has some effect on the nodeThe t value is 0 at the beginning of an intro or the end of an outro, and 1 at the end of an intro or beginning of an outro.Most of the time you should return the css property and not the tick property, as CSS animations run off the main thread to prevent jank where possible. Svelte 'simulates' the transition and constructs a CSS animation, then lets it run.For example, the fade transition generates a CSS animation somewhat like this:\n0% { opacity: 0 }\n10% { opacity: 0.1 }\n20% { opacity: 0.2 }\n/* ... */\n100% { opacity: 1 }\nWe can get a lot more creative though. Let's make something truly gratuitous: \n<script>\n\timport { fade } from 'svelte/transition';\n\t+++import { elasticOut } from 'svelte/easing';+++\n\n\tlet visible = $state(true);\n\n\tfunction spin(node, { duration }) {\n\t\treturn {\n\t\t\tduration,\n\t\t\tcss: (t, u) => +++{\n\t\t\t\tconst eased = elasticOut(t);\n\n\t\t\t\treturn `\n\t\t\t\t\ttransform: scale(${eased}) rotate(${eased * 1080}deg);\n\t\t\t\t\tcolor: hsl(\n\t\t\t\t\t\t${Math.trunc(t * 360)},\n\t\t\t\t\t\t${Math.min(100, 1000 * u)}%,\n\t\t\t\t\t\t${Math.min(50, 500 * u)}%\n\t\t\t\t\t);`\n\t\t\t}+++\n\t\t};\n\t}\n</script>Remember: with great power comes great responsibility.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Custom JS transitions"],"href":"/tutorial/svelte/custom-js-transitions","content":"While you should generally use CSS for transitions as much as possible, there are some effects that can't be achieved without JavaScript, such as a typewriter effect: \nfunction typewriter(node, { speed = 1 }) {\n\tconst valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;\n\n\tif (!valid) {\n\t\tthrow new Error(`This transition only works on elements with a single text node child`);\n\t}\n\n\t+++const text = node.textContent;\n\tconst duration = text.length / (speed * 0.01);\n\n\treturn {\n\t\tduration,\n\t\ttick: (t) => {\n\t\t\tconst i = Math.trunc(text.length * t);\n\t\t\tnode.textContent = text.slice(0, i);\n\t\t}\n\t};+++\n}","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Transition events"],"href":"/tutorial/svelte/transition-events","content":"It can be useful to know when transitions are beginning and ending. Svelte dispatches events that you can listen to like any other DOM event: \n<p\n\ttransition:fly={{ y: 200, duration: 2000 }}\n+++\tonintrostart={() => status = 'intro started'}\n\tonoutrostart={() => status = 'outro started'}\n\tonintroend={() => status = 'intro ended'}\n\tonoutroend={() => status = 'outro ended'}+++\n>\n\tFlies in and out\n</p>","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Global transitions"],"href":"/tutorial/svelte/global-transitions","content":"Ordinarily, transitions will only play on elements when their direct containing block is added or destroyed. In the example here, toggling the visibility of the entire list does not apply transitions to individual list elements.Instead, we'd like transitions to not only play when individual items are added and removed with the slider but also when we toggle the checkbox.We can achieve this with a global transition, which plays when any block containing the transitions is added or removed: \n<div transition:slide+++|global+++>\n\t{item}\n</div>[!NOTE] In Svelte 3, transitions were global by default and you had to use the `|local` modifier to make them local.","rank":null},{"breadcrumbs":["Tutorial","Basic Svelte","Transitions","Key blocks"],"href":"/tutorial/svelte/key-blocks","content":"Key blocks destroy and recreate their contents when the value of an expression changes. This is useful if you want an element to play its transition whenever a value changes instead of only when the element enters or leaves the DOM.Here, for example, we'd like to play the typewriter transition from transition.js whenever the loading message, i.e. i changes. Wrap the <p> element in a key block: \n+++{#key i}+++\n\t<p in:typewriter={{ speed: 10 }}>\n\t\t{messages[i] || ''}\n\t</p>\n+++{/key}+++","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced reactivity","Raw state"],"href":"/tutorial/svelte/raw-state","content":"In previous exercises, we learned that state is deeply reactive — if you (for example) change a property of an object, or push to an array, it will cause the UI to update. This works by creating a proxy that intercepts reads and writes.Occasionally, that's not what you want. If you're not changing individual properties, or if it's important to maintain referential equality, then you can use raw state instead.In this example, we have a chart of Svelte's steadily increasing stock price. We want the chart to update when new data comes in, which we could achieve by turning data into state... \nlet data = +++$state(poll())+++;...but there's no need to make it deeply reactive when it will be discarded a few milliseconds later. Instead, use $state.raw: \nlet data = +++$state.raw(poll())+++;[!NOTE] Mutating raw state will have no direct effect. In general, mutating non-reactive state is strongly discouraged.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced reactivity","Reactive classes"],"href":"/tutorial/svelte/reactive-classes","content":"It's not just variables that can be made reactive — in Svelte, we can also make properties of classes reactive.Let's make the width and height properties of our Box class reactive: \nclass Box {\n\twidth = +++$state(0);+++\n\theight = +++$state(0);+++\n\tarea = 0;\n\n\t// ...\n}Now, when we interact with the range inputs or click the 'embiggen' button, the box reacts.We can also use $derived, so that box.area updates reactively: \nclass Box {\n\twidth = $state(0);\n\theight = $state(0);\n\tarea = +++$derived(this.width * this.height);+++\n\n\t// ...\n}[!NOTE] In addition to `$state` and `$derived`, you can use `$state.raw` and `$derived.by` to define reactive fields.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced reactivity","Getters and setters"],"href":"/tutorial/svelte/getters-and-setters","content":"Classes are particularly useful when you need to validate data. In the case of this Box class, it shouldn't be possible to keep embiggening past the maximum allowed by the sliders, but that's exactly what happens.We can fix that by replacing width and height with getters and setters, otherwise known as accessors. First, convert them to private properties: \nclass Box {\n\t+++#width+++ = $state(0);\n\t+++#height+++ = $state(0);\n\tarea = $derived(this.+++#width+++ * this.+++#height+++);\n\n\tconstructor(width, height) {\n\t\tthis.+++#width+++ = width;\n\t\tthis.+++#height+++ = height;\n\t}\n\n\t// ...\n}Then, create some getters and setters: \nclass Box {\n\t// ...\n\n+++\tget width() {\n\t\treturn this.#width;\n\t}\n\n\tget height() {\n\t\treturn this.#height;\n\t}\n\n\tset width(value) {\n\t\tthis.#width = value;\n\t}\n\n\tset height(value) {\n\t\tthis.#height = value;\n\t}+++\n\n\tembiggen(amount) {\n\t\tthis.width += amount;\n\t\tthis.height += amount;\n\t}\n}Finally, add the validation to the setters: \nset width(value) {\n\tthis.#width = +++Math.max(0, Math.min(MAX_SIZE, value));+++\n}\n\nset height(value) {\n\tthis.#height = +++Math.max(0, Math.min(MAX_SIZE, value));+++\n}It's now impossible to increase the box size past safe limits, whether through the bind:value on the range inputs, or the embiggen method, no matter how hard you press the button.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced reactivity","Reactive built-ins"],"href":"/tutorial/svelte/reactive-builtins","content":"Svelte ships with several reactive classes that you can use in place of JavaScript built-in objects — namely Map, Set, Date, URL and URLSearchParams.In this exercise, we could declare date using $state(new Date()) and reassign it inside the setInterval. But a nicer alternative is to use SvelteDate from `svelte/reactivity`: \n<script>\n\t+++import { SvelteDate } from 'svelte/reactivity';+++\n\n\tlet date = new +++SvelteDate();+++\n\n\t// ...\n</script>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced reactivity","Stores"],"href":"/tutorial/svelte/stores","content":"Prior to the introduction of runes in Svelte 5, stores were the idiomatic way to handle reactive state outside components. That's no longer the case, but you'll still encounter stores when using Svelte (including in SvelteKit, for now), so it's worth knowing how to use them.[!NOTE] We won't cover how to create your own custom stores — for that, [consult the documentation](/docs/svelte/stores).Let's revisit the example from the universal reactivity exercise, but this time implement the shared state using a store.In shared.js we're currently exporting count, which is a number. Turn it into a writable store: \n+++import { writable } from 'svelte/store';+++\n\nexport const count = +++writable(0)+++;To reference the value of the store, we prefix it with a $ symbol. In Counter.svelte, update the text inside the <button> so that it no longer says [object Object]: \n<button onclick={() => {}}>\n\tclicks: {+++$count+++}\n</button>Finally, add the event handler. Because this is a writable store, we can update the value programmatically using its set or update method...count.update((n) => n + 1);...but since we're in a component we can continue using the $ prefix: \n<button onclick={() => +++$count += 1+++}>\n\tclicks: {$count}\n</button>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Reusing content","Snippets and render tags"],"href":"/tutorial/svelte/snippets-and-render-tags","content":"Snippets allow you to reuse content within a component, without extracting it out into a separate file.In this exercise, we're creating a table of the three wise monkeys, along with their unicode escape sequences and HTML entities. So far, we have but a single monkey.We could duplicate the markup, of course. Or we could create an array of { emoji, description } objects and pass it into an {#each ...} block. But a neater solution is to encapsulate the markup in a reusable block.Begin by declaring a snippet: \n+++{#snippet monkey()}+++\n\t<tr>\n\t\t<td>{emoji}</td>\n\t\t<td>{description}</td>\n\t\t<td>\\u{emoji.charCodeAt(0).toString(16)}\\u{emoji.charCodeAt(1).toString(16)}</td>\n\t\t<td>&amp#{emoji.codePointAt(0)}</td>\n\t</tr>\n+++{/snippet}+++The monkey is no longer visible until we render it. Let's do that: \n<tbody>\n\t{#snippet monkey()}...{/snippet}\n\n\t+++{@render monkey()}+++\n</tbody>Before we can use the snippet for the rest of our monkeys, we need to pass data into the snippet. Snippets can have zero or more parameters: \n<tbody>\n\t+++{#snippet monkey(emoji, description)}...{/snippet}+++\n\n\t+++{@render monkey('🙈', 'see no evil')}+++\n</tbody>[!NOTE] You can also use destructured parameters, if you like.Add the rest of the monkeys:`'🙈', 'see no evil'`\n`'🙉', 'hear no evil'`\n`'🙊', 'speak no evil'`Finally, delete the <script> block we no longer need it: \n---<script>\n\tlet emoji = '🙈';\n\tlet description = 'see no evil';\n</script>---[!NOTE] Snippets can be declared anywhere in your component, but, like functions, are only visible to render tags in the same 'scope' or a child scope.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Reusing content","Passing snippets to components"],"href":"/tutorial/svelte/passing-snippets","content":"Since snippets — like functions — are just values, they can be passed to components as props.Take this <FilteredList> component. Its job is to filter the data that gets passed into it, but it has no opinions about how that data should be rendered — that's the responsibility of the parent component.We've already got some snippets defined. Begin by passing them into the <FilteredList>: \n<FilteredList\n\tdata={colors}\n\tfield=\"name\"\n\t+++{header}+++\n\t+++{row}+++\n></FilteredList>Then, on the other side, declare header and row as props: \n<script>\n\tlet { data, field, +++header, row+++ } = $props();\n\n\t// ...\n</script>Finally, replace the placeholder content with render tags: \n<div class=\"header\">\n\t+++{@render header()}+++\n</div>\n\n<div class=\"content\">\n\t{#each filtered as d}\n\t\t+++{@render row(d)}+++\n\t{/each}\n</div>Never again will you have to memorize the hex code for MistyRose or PeachPuff.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Reusing content","Implicit snippet props"],"href":"/tutorial/svelte/implicit-snippet-props","content":"As an authoring convenience, snippets declared directly inside components become props on those components. Take the header and row snippets and move them inside <FilteredList>: \n<FilteredList\n\tdata={colors}\n\tfield=\"name\"\n\t{header}\n\t{row}\n>\n\t+++{#snippet header()}...{/snippet}+++\n\n\t+++{#snippet row(d)}...{/snippet}+++\n</FilteredList>\n\n---{#snippet header()}...{/snippet}---\n\n---{#snippet row(d)}...{/snippet}---We can now remove them from the explicit props: \n<FilteredList data={colors} field=\"name\" ---{header} {row}--->\n\t{#snippet header()}...{/snippet}\n\n\t{#snippet row(d)}...{/snippet}\n</FilteredList>Any content inside a component that is not part of a declared snippet becomes a special children snippet. Since header has no parameters, we can turn it into children by removing the block tags... \n---{#snippet header()}---\n<header>\n\t<span class=\"color\"></span>\n\t<span class=\"name\">name</span>\n\t<span class=\"hex\">hex</span>\n\t<span class=\"rgb\">rgb</span>\n\t<span class=\"hsl\">hsl</span>\n</header>\n---{/snippet}---...and renaming the header prop to children on the other side: \n<script>\n\tlet { data, field, +++children+++, row } = $props();\n\n\t// ...\n</script> \n<div class=\"header\">\n\t+++{@render children()}+++\n</div>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Motion","Tweened values"],"href":"/tutorial/svelte/tweens","content":"Often, a good way to communicate that a value is changing is to use motion. Svelte ships classes for adding motion to your user interfaces.Import the Tween class from svelte/motion: \n<script>\n\t+++import { Tween } from 'svelte/motion';+++\n\n\tlet progress = $state(0);\n</script>Turn progress into an instance of Tween: \n<script>\n\timport { Tween } from 'svelte/motion';\n\n\tlet progress = +++new Tween+++(0);\n</script>The Tween class has a writable target property and a readonly current property — update the <progress> element...<progress value={progress.+++current+++}></progress>...and each of the event handlers:<button onclick={() => (progress.+++target+++ = 0)}>\n\t0%\n</button>Clicking the buttons causes the progress bar to animate to its new value. It's a bit robotic and unsatisfying though. We need to add an easing function: \n<script>\n\timport { Tween } from 'svelte/motion';\n\t+++import { cubicOut } from 'svelte/easing';+++\n\n\tlet progress = new Tween(0, +++{\n\t\tduration: 400,\n\t\teasing: cubicOut\n\t}+++);\n</script>[!NOTE] The `svelte/easing` module contains the [Penner easing equations](https://web.archive.org/web/20190805215728/http://robertpenner.com/easing/), or you can supply your own `p => t` function where `p` and `t` are both values between 0 and 1.The full set of options available to Tween:`delay` — milliseconds before the tween starts\n`duration` — either the duration of the tween in milliseconds, or a `(from, to) => milliseconds` function allowing you to (e.g.) specify longer tweens for larger changes in value\n`easing` — a `p => t` function\n`interpolate` — a custom `(from, to) => t => value` function for interpolating between arbitrary values. By default, Svelte will interpolate between numbers, dates, and identically-shaped arrays and objects (as long as they only contain numbers and dates or other valid arrays and objects). If you want to interpolate (for example) colour strings or transformation matrices, supply a custom interpolatorYou can also call progress.set(value, options) instead of assigning directly to progress.target, in which case options will override the defaults. The set method returns a promise that resolves when the tween completes.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Motion","Springs"],"href":"/tutorial/svelte/springs","content":"The Spring class is an alternative to Tween that often works better for values that are frequently changing.In this example we have a circle that follows the mouse, and two values — the circle's coordinates, and its size. Let's convert them to springs: \n<script>\n\t+++import { Spring } from 'svelte/motion+++';\n\n\tlet coords = +++new Spring+++({ x: 50, y: 50 });\n\tlet size = +++new Spring+++(10);\n</script>As with Tween, springs have a writable target property and a readonly current property. Update the event handlers...<svg\n\tonmousemove={(e) => {\n\t\tcoords.+++target+++ = { x: e.clientX, y: e.clientY };\n\t}}\n\tonmousedown={() => (size.+++target+++ = 30)}\n\tonmouseup={() => (size.+++target+++ = 10)}\n\trole=\"presentation\"\n>...and the <circle> attributes:<circle\n\tcx={coords.+++current+++.x}\n\tcy={coords.+++current+++.y}\n\tr={size.+++current+++}\n></circle>Both springs have default stiffness and damping values, which control the spring's, well... springiness. We can specify our own initial values: \nlet coords = new Spring({ x: 50, y: 50 }, +++{\n\tstiffness: 0.1,\n\tdamping: 0.25\n}+++);Waggle your mouse around, and try dragging the sliders to get a feel for how they affect the spring's behaviour. Notice that you can adjust the values while the spring is still in motion.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Contenteditable bindings"],"href":"/tutorial/svelte/contenteditable-bindings","content":"Elements with a contenteditable attribute support textContent and innerHTML bindings: \n<div +++bind:innerHTML={html}+++ contenteditable></div>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Each block bindings"],"href":"/tutorial/svelte/each-block-bindings","content":"You can bind to properties inside an each block. \n{#each todos as todo}\n\t<li class={{ done: todo.done }}>\n\t\t<input\n\t\t\ttype=\"checkbox\"\n\t\t\t+++bind:+++checked={todo.done}\n\t\t/>\n\n\t\t<input\n\t\t\ttype=\"text\"\n\t\t\tplaceholder=\"What needs to be done?\"\n\t\t\t+++bind:+++value={todo.text}\n\t\t/>\n\t</li>\n{/each}","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Media elements"],"href":"/tutorial/svelte/media-elements","content":"You can bind to properties of <audio> and <video> elements, making it easy to (for example) build custom player UI, like AudioPlayer.svelte.First, add the <audio> element along with its bindings (we'll use the shorthand form for src, duration and paused): \n<div class={['player', { paused }]}>\n+++\t<audio\n\t\t{src}\n\t\tbind:currentTime={time}\n\t\tbind:duration\n\t\tbind:paused\n\t></audio>+++\n\n\t<button\n\t\tclass=\"play\"\n\t\taria-label={paused ? 'play' : 'pause'}\n\t></button>Next, add an event handler to the <button> that toggles paused: \n<button\n\tclass=\"play\"\n\taria-label={paused ? 'play' : 'pause'}\n\t+++onclick={() => paused = !paused}+++\n></button>Our audio player now has basic functionality. Let's add the ability to seek to a specific part of a track by dragging the slider. Inside the slider's pointerdown handler there's a seek function, where we can update time: \nfunction seek(e) {\n\tconst { left, width } = div.getBoundingClientRect();\n\n\tlet p = (e.clientX - left) / width;\n\tif (p < 0) p = 0;\n\tif (p > 1) p = 1;\n\n\t+++time = p * duration;+++\n}When the track ends, be kind — rewind: \n<audio\n\t{src}\n\tbind:currentTime={time}\n\tbind:duration\n\tbind:paused\n+++\tonended={() => {\n\t\ttime = 0;\n\t}}+++\n></audio>The complete set of bindings for <audio> and <video> is as follows — seven readonly bindings...`duration` — the total duration, in seconds\n`buffered` — an array of `{start, end}` objects\n`seekable` — ditto\n`played` — ditto\n`seeking` — boolean\n`ended` — boolean\n`readyState` — number between (and including) 0 and 4...and five two-way bindings:`currentTime` — the current position of the playhead, in seconds\n`playbackRate` — speed up or slow down (`1` is 'normal')\n`paused` — this one should be self-explanatory\n`volume` — a value between 0 and 1\n`muted` — a boolean value where true is mutedVideos additionally have readonly videoWidth and videoHeight bindings.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Dimensions"],"href":"/tutorial/svelte/dimensions","content":"You can add clientWidth, clientHeight, offsetWidth and offsetHeight bindings to any element, and Svelte will update the bound values using a `ResizeObserver`: \n<div +++bind:clientWidth={w} bind:clientHeight={h}+++>\n\t<span style=\"font-size: {size}px\" contenteditable>edit this text</span>\n\t<span class=\"size\">{w} x {h}px</span>\n</div>These bindings are readonly — changing the values of w and h won't have any effect on the element.[!NOTE] `display: inline` elements do not have a width or height (except for elements with 'intrinsic' dimensions, like `<img>` and `<canvas>`), and cannot be observed with a `ResizeObserver`. You will need to change the `display` style of these elements to something else, such as `inline-block`.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","This"],"href":"/tutorial/svelte/bind-this","content":"You can use the special bind:this directive to get a readonly binding to an element in your component.The $effect in this exercise attempts to create a canvas context, but canvas is undefined. Begin by declaring it at the top level of the component... \n<script>\n\timport { paint } from './gradient.js';\n\n\t+++let canvas;+++\n\n\t$effect(() => {\n\t\t// ...\n\t});\n</script>...then add the directive to the <canvas> element: \n<canvas +++bind:this={canvas}+++></canvas>Note that the value of canvas will remain undefined until the component has mounted — in other words you can't access it until the $effect runs.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Component bindings"],"href":"/tutorial/svelte/component-bindings","content":"Just as you can bind to properties of DOM elements, you can bind to component props. For example, we can bind to the value prop of this <Keypad> component as though it were a form element.First, we need to mark the prop as bindable. Inside Keypad.svelte, update the $props() declaration to use the $bindable rune: \nlet { value +++= $bindable('')+++, onsubmit } = $props();Then, in App.svelte, add a bind: directive: \n<Keypad +++bind:value={pin}+++ {onsubmit} />Now, when the user interacts with the keypad, the value of pin in the parent component is immediately updated.[!NOTE] Use component bindings sparingly. It can be difficult to track the flow of data around your application if you have too many of them, especially if there is no 'single source of truth'.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced bindings","Binding to component instances"],"href":"/tutorial/svelte/component-this","content":"Just as you can bind to DOM elements, you can bind to component instances themselves with bind:this.This is useful in the rare cases that you need to interact with a component programmatically (rather than by providing it with updated props). Revisiting our canvas app from a few exercises ago, it would be nice to add a button to clear the screen.First, let's export a function from Canvas.svelte: \nlet canvas = $state();\nlet context = $state();\nlet coords = $state();\n\n+++export function clear() {\n\tcontext.clearRect(0, 0, canvas.width, canvas.height);\n}+++Then, create a reference to the component instance: \nlet selected = $state(colors[0]);\nlet size = $state(10);\nlet showMenu = $state(true);\n\n+++let canvas;+++ \n<Canvas +++bind:this={canvas}+++ color={selected} size={size} />Finally, add a button that calls the clear function: \n<div class=\"controls\">\n\t<button class=\"show-menu\" onclick={() => showMenu = !showMenu}>\n\t\t{showMenu ? 'close' : 'menu'}\n\t</button>\n\n+++\t<button onclick={() => canvas.clear()}>\n\t\tclear\n\t</button>+++\n</div>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced transitions","Deferred transitions"],"href":"/tutorial/svelte/deferred-transitions","content":"A particularly powerful feature of Svelte's transition engine is the ability to defer transitions, so that they can be coordinated between multiple elements.Take this pair of todo lists, in which toggling a todo sends it to the opposite list. In the real world, objects don't behave like that — instead of disappearing and reappearing in another place, they move through a series of intermediate positions. Using motion can go a long way towards helping users understand what's happening in your app.We can achieve this effect using the crossfade function, as seen in transition.js, which creates a pair of transitions called send and receive. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the fallback transition is used.Open TodoList.svelte. First, import the send and receive transitions from transition.js: \n<script>\n\t+++import { send, receive } from './transition.js';+++\n\n\tlet { todos, remove } = $props();\n</script>Then, add them to the <li> element, using the todo.id property as a key to match the elements: \n<li\n\tclass={{ done: todo.done }}\n\t+++in:receive={{ key: todo.id }}+++\n\t+++out:send={{ key: todo.id }}+++\n>Now, when you toggle items, they move smoothly to their new location. The non-transitioning items still jump around awkwardly — we can fix that in the next exercise.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Advanced transitions","Animations"],"href":"/tutorial/svelte/animations","content":"In the previous chapter, we used deferred transitions to create the illusion of motion as elements move from one todo list to the other.To complete the illusion, we also need to apply motion to the elements that aren't transitioning. For this, we use the animate directive.First, import the flip function — flip stands for 'First, Last, Invert, Play' — from svelte/animate into TodoList.svelte: \n<script>\n\t+++import { flip } from 'svelte/animate';+++\n\timport { send, receive } from './transition.js';\n\n\tlet { todos, remove } = $props();\n</script>Then add it to the <li> elements: \n<li\n\tclass={{ done: todo.done }}\n\tin:receive={{ key: todo.id }}\n\tout:send={{ key: todo.id }}\n\t+++animate:flip+++\n>The movement is a little slow in this case, so we can add a duration parameter: \n<li\n\tclass={{ done: todo.done }}\n\tin:receive={{ key: todo.id }}\n\tout:send={{ key: todo.id }}\n\tanimate:flip+++={{ duration: 200 }}+++\n>[!NOTE] `duration` can also be a `d => milliseconds` function, where `d` is the number of pixels the element has to travelNote that all the transitions and animations are being applied with CSS, rather than JavaScript, meaning they won't block (or be blocked by) the main thread.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Context API","setContext and getContext"],"href":"/tutorial/svelte/context-api","content":"The context API provides a mechanism for components to 'talk' to each other without passing around data and functions as props, or dispatching lots of events. It's an advanced feature, but a useful one. In this exercise, we're going to recreate Schotter by George Nees — one of the pioneers of generative art — using the context API.Inside Canvas.svelte, there's an addItem function that adds an item to the canvas. We can make it available to components inside <Canvas>, like <Square>, with setContext: \n+++import { setContext } from 'svelte';+++\nimport { SvelteSet } from 'svelte/reactivity';\n\nlet { width = 100, height = 100, children } = $props();\n\nlet canvas;\nlet items = new SvelteSet();\n\n+++setContext('canvas', { addItem });+++\n\nfunction addItem(fn) {\n\t$effect(() => {\n\t\titems.add(fn);\n\t\treturn () => items.delete(fn);\n\t});\n}Inside child components, we can now get the context with, well, getContext: \n+++import { getContext } from 'svelte';+++\n\nlet { x, y, size, rotate } = $props();\n\n+++getContext('canvas').addItem(draw);+++So far, so... boring. Let's add some randomness to the grid: \n<div class=\"container\">\n\t<Canvas width={800} height={1200}>\n\t\t{#each Array(12) as _, c}\n\t\t\t{#each Array(22) as _, r}\n\t\t\t\t<Square\n\t\t\t\t\tx={180 + c * 40+++ + jitter(r * 2)+++}\n\t\t\t\t\ty={180 + r * 40+++ + jitter(r * 2)+++}\n\t\t\t\t\tsize={40}\n\t\t\t\t\t+++rotate={jitter(r * 0.05)}+++\n\t\t\t\t/>\n\t\t\t{/each}\n\t\t{/each}\n\t</Canvas>\n</div>setContext and getContext must be called during component initialisation, so that the context can be correctly bound. The key — 'canvas' in this case — can be anything you like, including non-strings, which is useful for controlling who can access the context.[!NOTE] Your context object can include anything, including reactive state. This allows you to pass values that change over time to child components:\n\n```js\n// in a parent component\nimport { setContext } from 'svelte';\n\nlet context = $state({...});\nsetContext('my-context', context);\n```\n\n```js\n// in a child component\nimport { getContext } from 'svelte';\n\nconst context = getContext('my-context');\n```","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:window>"],"href":"/tutorial/svelte/svelte-window","content":"Just as you can add event listeners to any DOM element, you can add event listeners to the window object with <svelte:window>.We've already got an onkeydown function declared — now all we need to do is wire it up: \n<svelte:window +++{onkeydown}+++ />","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:window> bindings"],"href":"/tutorial/svelte/svelte-window-bindings","content":"We can also bind to certain properties of window, such as scrollY: \n<svelte:window +++bind:scrollY={y}+++ />The list of properties you can bind to is as follows:`innerWidth`\n`innerHeight`\n`outerWidth`\n`outerHeight`\n`scrollX`\n`scrollY`\n`online` — an alias for `window.navigator.onLine`All except scrollX and scrollY are readonly.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:document>"],"href":"/tutorial/svelte/svelte-document","content":"The <svelte:document> element allows you to listen for events that fire on document. This is useful with events like selectionchange, which doesn't fire on window.Add the onselectionchange handler to the <svelte:document> tag: \n<svelte:document +++{onselectionchange}+++ />[!NOTE] Avoid `mouseenter` and `mouseleave` handlers on this element, as these events are not fired on `document` in all browsers. Use `<svelte:body>` instead.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:body>"],"href":"/tutorial/svelte/svelte-body","content":"Similar to <svelte:window> and <svelte:document>, the <svelte:body> element allows you to listen for events that fire on document.body. This is useful with the mouseenter and mouseleave events, which don't fire on window.Add onmouseenter and onmouseleave handlers to the <svelte:body> tag... \n<svelte:body\n\t+++onmouseenter={() => hereKitty = true}+++\n\t+++onmouseleave={() => hereKitty = false}+++\n/>...and hover over the <body>.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:head>"],"href":"/tutorial/svelte/svelte-head","content":"The <svelte:head> element allows you to insert elements inside the <head> of your document. This is useful for things like <title> and <meta> tags, which are critical for good SEO.Since those are quite hard to show in the context of this tutorial, we'll use it for a different purpose — loading stylesheets. \n<script>\n\tconst themes = ['margaritaville', 'retrowave', 'spaaaaace', 'halloween'];\n\tlet selected = $state(themes[0]);\n</script>\n\n+++<svelte:head>\n\t<link rel=\"stylesheet\" href=\"/tutorial/stylesheets/{selected}.css\" />\n</svelte:head>+++\n\n<h1>Welcome to my site!</h1>[!NOTE] In server-side rendering (SSR) mode, contents of `<svelte:head>` are returned separately from the rest of your HTML.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:element>"],"href":"/tutorial/svelte/svelte-element","content":"Sometimes you don't know in advance which element needs to be rendered. Rather than having a long list of {#if ...} blocks... \n{#if selected === 'h1'}\n\t<h1>I'm a <code>&amp;lt;h1&amp;gt;</code> element</h1>\n{:else}\n\t<p>TODO others</p>\n{/if}...we can use <svelte:element>: \n+++<svelte:element this={selected}>\n\tI'm a <code>&amp;lt;{selected}&amp;gt;</code> element\n</svelte:element>+++The this value can be any string, or a falsy value — if it's falsy, no element is rendered.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Special elements","<svelte:boundary>"],"href":"/tutorial/svelte/svelte-boundary","content":"To prevent errors from leaving your app in a broken state, you can contain them inside an error boundary using the <svelte:boundary> element.In this example, <FlakyComponent> contains a bug — clicking the button will set mouse to null, meaning that the {mouse.x} and {mouse.y} expressions in the template will fail to render.In an ideal world we'd simply fix the bug. But that's not always an option — sometimes the component belongs to someone else, and sometimes you just need to guard against the unexpected. Begin by wrapping <FlakyComponent /> with <svelte:boundary>:<!--- file: App.svelte --->\n+++<svelte:boundary>+++\n\t<FlakyComponent />\n+++</svelte:boundary>+++So far, nothing has changed, because the boundary doesn't specify a handler. Add a failed snippet to provide some UI to show when an error occurs:<!--- file: App.svelte --->\n<svelte:boundary>\n\t<FlakyComponent />\n\n+++\t{#snippet failed(error)}\n\t\t<p>Oops! {error.message}</p>\n\t{/snippet}+++\n</svelte:boundary>Now, when we click the button, the contents of the boundary are replaced with the snippet. We can attempt to reset things by making use of the second argument passed to failed:<!--- file: App.svelte --->\n<svelte:boundary>\n\t<FlakyComponent />\n\n\t{#snippet failed(error+++, reset+++)}\n\t\t<p>Oops! {error.message}</p>\n\t\t+++<button onclick={reset}>Reset</button>+++\n\t{/snippet}\n</svelte:boundary>We can also specify an onerror handler, which is called with the same arguments passed to the failed snippet:<!--- file: App.svelte --->\n<svelte:boundary +++onerror={(e) => console.error(e)}+++>\n\t<FlakyComponent />\n\n\t{#snippet failed(error, reset)}\n\t\t<p>Oops! {error.message}</p>\n\t\t<button onclick={reset}>Reset</button>\n\t{/snippet}\n</svelte:boundary>This is useful for sending information about the error to a reporting service, or adding UI outside the error boundary itself.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","<script module>","Sharing code"],"href":"/tutorial/svelte/sharing-code","content":"In all the examples we've seen so far, the <script> block contains code that runs when each component instance is initialised. For the vast majority of components, that's all you'll ever need.Very occasionally, you'll need to run some code outside of an individual component instance. For example: returning to our custom audio player from a previous exercise, you can play all four tracks simultaneously. It would be better if playing one stopped all the others.We can do that by declaring a <script module> block. Code contained inside it will run once, when the module first evaluates, rather than when a component is instantiated. Place this at the top of AudioPlayer.svelte (note that this is a separate script tag): \n+++<script module>\n\tlet current;\n</script>+++It's now possible for the components to 'talk' to each other without any state management: \n<audio\n\tsrc={src}\n\tbind:currentTime={time}\n\tbind:duration\n\tbind:paused\n+++\tonplay={(e) => {\n\t\tconst audio = e.currentTarget;\n\n\t\tif (audio !== current) {\n\t\t\tcurrent?.pause();\n\t\t\tcurrent = audio;\n\t\t}\n\t}}+++\n\tonended={() => {\n\t\ttime = 0;\n\t}}\n/>","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","<script module>","Exports"],"href":"/tutorial/svelte/module-exports","content":"Anything exported from a module script block becomes an export from the module itself. Let's export a pauseAll function: \n<script module>\n\tlet current;\n\n+++\texport function pauseAll() {\n\t\tcurrent?.pause();\n\t}+++\n</script>We can now import pauseAll in App.svelte... \n<script>\n\timport AudioPlayer, +++{ pauseAll }+++ from './AudioPlayer.svelte';\n\timport { tracks } from './tracks.js';\n</script>...and use it in an event handler: \n<div class=\"centered\">\n\t{#each tracks as track}\n\t\t<AudioPlayer {...track} />\n\t{/each}\n\n+++\t<button onclick={pauseAll}>\n\t\tpause all\n\t</button>+++\n</div>[!NOTE] You can't have a default export, because the component _is_ the default export.","rank":null},{"breadcrumbs":["Tutorial","Advanced Svelte","Next steps","Congratulations!"],"href":"/tutorial/svelte/congratulations","content":"You've now finished the Svelte tutorial and are ready to start building.The next two parts of the tutorial will focus on SvelteKit, a full-fledged framework for creating apps of all shapes and sizes.If you're suffering from information overload and aren't ready to go through the SvelteKit tutorial yet, don't worry! You can use your existing Svelte knowledge without learning all of SvelteKit. Just run this in your terminal and follow the prompts...npx sv create...and start editing src/routes/+page.svelte. When you're ready, click the link below to continue your journey.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Introduction","What is SvelteKit?"],"href":"/tutorial/kit/introducing-sveltekit","content":"Whereas Svelte is a component framework, SvelteKit is an app framework (or 'metaframework', depending on who you ask) that solves the tricky problems of building something production-ready:Routing\nServer-side rendering\nData fetching\nService workers\nTypeScript integration\nPrerendering\nSingle-page apps\nLibrary packaging\nOptimised production builds\nDeploying to different hosting providers\n...and so onSvelteKit apps are server-rendered by default (like traditional 'multi-page apps' or MPAs) for excellent first load performance and SEO characteristics, but can then transition to client-side navigation (like modern 'single-page apps' or SPAs) to avoid jankily reloading everything (including things like third-party analytics code) when the user navigates. They can run anywhere JavaScript runs, though — as we'll see — your users may not need to run any JavaScript at all.If that sounds complicated, worry not: SvelteKit is the framework that grows with you! Start simple and add new features as you need them.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Introduction","What is SvelteKit?","Project structure"],"href":"/tutorial/kit/introducing-sveltekit#Project-structure","content":"On the right, in the file tree viewer, you'll see a handful of files that SvelteKit expects to find in a project.package.json will be familiar if you've worked with Node.js before. It lists the project's dependencies — including svelte and @sveltejs/kit — and a variety of scripts for interacting with the SvelteKit CLI. (We're currently running npm run dev in the bottom window.)[!NOTE] Note that it also specifies `\"type\": \"module\"`, which means that `.js` files are treated as native JavaScript modules by default, rather than the legacy CommonJS format.svelte.config.js contains your project configuration. We don't need to worry about this file for now, but if you're curious, visit the documentation.vite.config.js contains the Vite configuration. Because SvelteKit uses Vite, you can use Vite features like hot module replacement, TypeScript support, static asset handling and so on.src is where your app's source code goes. src/app.html is your page template (SvelteKit replaces the %sveltekit.head% and %sveltekit.body% as appropriate), and src/routes defines the routes of your app.Finally, static contains any assets (like a favicon.png or a robots.txt) that should be included when your app is deployed.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Routing","Pages"],"href":"/tutorial/kit/pages","content":"SvelteKit uses filesystem-based routing, which means that the routes of your app — in other words, what the app should do when a user navigates to a particular URL — are defined by the directories in your codebase.Every +page.svelte file inside src/routes creates a page in your app. In this app we currently have one page — src/routes/+page.svelte, which maps to /. If we navigate to /about, we'll see a 404 Not Found error.Let's fix that. Add a second page, src/routes/about/+page.svelte, copy the contents of src/routes/+page.svelte, and update it: \n<nav>\n\t<a href=\"/\">home</a>\n\t<a href=\"/about\">about</a>\n</nav>\n\n<h1>+++about+++</h1>\n<p>this is the +++about+++ page.</p>We can now navigate between / and /about.[!NOTE] Unlike traditional multi-page apps, navigating to `/about` and back updates the contents of the current page, like a single-page app. This gives us the best of both worlds — fast server-rendered startup, then instant navigation. (This behaviour can be [configured](/docs/kit/page-options).)","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Routing","Layouts"],"href":"/tutorial/kit/layouts","content":"Different routes of your app will often share common UI. Instead of repeating it in each +page.svelte component, we can use a +layout.svelte component that applies to all routes in the same directory.In this app we have two routes, src/routes/+page.svelte and src/routes/about/+page.svelte, that contain the same navigation UI. Let's create a new file, src/routes/+layout.svelte...src/routes/\n├ about/\n│ └ +page.svelte\n+++├ +layout.svelte+++\n└ +page.svelte...and move the duplicated content from the +page.svelte files into the new +layout.svelte file. The {@render children()} tag is where the page content will be rendered: \n<script>\n\tlet { children } = $props();\n</script>\n\n<nav>\n\t<a href=\"/\">home</a>\n\t<a href=\"/about\">about</a>\n</nav>\n\n{@render children()}A +layout.svelte file applies to every child route, including the sibling +page.svelte (if it exists). You can nest layouts to arbitrary depth.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Routing","Route parameters"],"href":"/tutorial/kit/params","content":"To create routes with dynamic parameters, use square brackets around a valid variable name. For example, a file like src/routes/blog/[slug]/+page.svelte will create a route that matches /blog/one, /blog/two, /blog/three and so on.Let's create that file: \n<h1>blog post</h1>We can now navigate from the /blog page to individual blog posts. In the next chapter, we'll see how to load their content.[!NOTE] Multiple route parameters can appear _within_ one URL segment, as long as they are separated by at least one static character: `foo/[bar]x[baz]` is a valid route where `[bar]` and `[baz]` are dynamic parameters.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Loading data","Page data"],"href":"/tutorial/kit/page-data","content":"At its core, SvelteKit's job boils down to three things:**Routing** — figure out which route matches an incoming request\n**Loading** — get the data needed by the route\n**Rendering** — generate some HTML (on the server) or update the DOM (in the browser)We've seen how routing and rendering work. Let's talk about the middle part — loading.Every page of your app can declare a load function in a +page.server.js file alongside the +page.svelte file. As the file name suggests, this module only ever runs on the server, including for client-side navigations. Let's add a src/routes/blog/+page.server.js file so that we can replace the hard-coded links in src/routes/blog/+page.svelte with actual blog post data: \nimport { posts } from './data.js';\n\nexport function load() {\n\treturn {\n\t\tsummaries: posts.map((post) => ({\n\t\t\tslug: post.slug,\n\t\t\ttitle: post.title\n\t\t}))\n\t};\n}[!NOTE] For the sake of the tutorial, we're importing data from `src/routes/blog/data.js`. In a real app, you'd be more likely to load the data from a database or a CMS, but for now we'll do it like this.We can access this data in src/routes/blog/+page.svelte via the data prop: \n+++<script>\n\tlet { data } = $props();\n</script>+++\n\n<h1>blog</h1>\n\n<ul>\n---\t<li><a href=\"/blog/one\">one</a></li>\n\t<li><a href=\"/blog/two\">two</a></li>\n\t<li><a href=\"/blog/three\">three</a></li>---\n+++\t{#each data.summaries as { slug, title }}\n\t\t<li><a href=\"/blog/{slug}\">{title}</a></li>\n\t{/each}+++\n</ul>Now, let's do the same for the post page: \nimport { posts } from '../data.js';\n\nexport function load({ params }) {\n\tconst post = posts.find((post) => post.slug === params.slug);\n\n\treturn {\n\t\tpost\n\t};\n} \n+++<script>\n\tlet { data } = $props();\n</script>+++\n\n---<h1>blog post</h1>---\n+++<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>+++There's one last detail we need to take care of — the user might visit an invalid pathname like /blog/nope, in which case we'd like to respond with a 404 page: \n+++import { error } from '@sveltejs/kit';+++\nimport { posts } from '../data.js';\n\nexport function load({ params }) {\n\tconst post = posts.find((post) => post.slug === params.slug);\n\n\t+++if (!post) error(404);+++\n\n\treturn {\n\t\tpost\n\t};\n}We'll learn more about error handling in later chapters.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Loading data","Layout data"],"href":"/tutorial/kit/layout-data","content":"Just as +layout.svelte files create UI for every child route, +layout.server.js files load data for every child route.Suppose we'd like to add a 'more posts' sidebar to our blog post page. We could return summaries from the load function in src/routes/blog/[slug]/+page.server.js, like we do in src/routes/blog/+page.server.js, but that would be repetitive.Instead, let's rename src/routes/blog/+page.server.js to src/routes/blog/+layout.server.js. Notice that the /blog route continues to work — data.summaries is still available to the page.Now, add a sidebar in the layout for the post page: \n<script>\n\tlet { data, children } = $props();\n</script>\n\n<div class=\"layout\">\n\t<main>\n\t\t{@render children()}\n\t</main>\n\n+++\t<aside>\n\t\t<h2>More posts</h2>\n\t\t<ul>\n\t\t\t{#each data.summaries as { slug, title }}\n\t\t\t\t<li>\n\t\t\t\t\t<a href=\"/blog/{slug}\">{title}</a>\n\t\t\t\t</li>\n\t\t\t{/each}\n\t\t</ul>\n\t</aside>+++\n</div>\n\n<style>\n\t@media (min-width: 640px) {\n\t\t.layout {\n\t\t\tdisplay: grid;\n\t\t\tgap: 2em;\n\t\t\tgrid-template-columns: 1fr 16em;\n\t\t}\n\t}\n</style>The layout (and any page below it) inherits data.summaries from the parent +layout.server.js.When we navigate from one post to another, we only need to load the data for the post itself — the layout data is still valid. See the documentation on invalidation to learn more.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Headers and cookies","Setting headers"],"href":"/tutorial/kit/headers","content":"Inside a load function (as well as in form actions, hooks and API routes, which we'll learn about later) you have access to a setHeaders function, which — unsurprisingly — can be used to set headers on the response.Most commonly, you'd use it to customise caching behaviour with the `Cache-Control` response header, but for the sake of this tutorial we'll do something less advisable and more dramatic: \nexport function load(+++{ setHeaders }+++) {\n+++\tsetHeaders({\n\t\t'Content-Type': 'text/plain'\n\t});+++\n}(You may need to reload the iframe to see the effect.)","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Headers and cookies","Reading and writing cookies"],"href":"/tutorial/kit/cookies","content":"The `setHeaders` function can't be used with the Set-Cookie header. Instead, you should use the cookies API.In your load functions, you can read a cookie with cookies.get(name, options): \nexport function load(+++{ cookies }+++) {\n\t+++const visited = cookies.get('visited');+++\n\n\treturn {\n\t\tvisited: visited === 'true'\n\t};\n}To set a cookie, use cookies.set(name, value, options). It's strongly recommended that you explicitly configure the path when setting a cookie, since browsers' default behaviour — somewhat uselessly — is to set the cookie on the parent of the current path. \nexport function load({ cookies }) {\n\tconst visited = cookies.get('visited');\n\n\t+++cookies.set('visited', 'true', { path: '/' });+++\n\n\treturn {\n\t\tvisited: visited === 'true'\n\t};\n}Now, if you reload the iframe, Hello stranger! becomes Hello friend!.Calling cookies.set(name, ...) causes a Set-Cookie header to be written, but it also updates the internal map of cookies, meaning any subsequent calls to cookies.get(name) during the same request will return the updated value. Under the hood, the cookies API uses the popular cookie package — the options passed to cookies.get and cookies.set correspond to the parse and serialize options from the cookie documentation. SvelteKit sets the following defaults to make your cookies more secure:{\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: 'lax'\n}","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Shared modules","The $lib alias"],"href":"/tutorial/kit/lib","content":"Because SvelteKit uses directory-based routing, it's easy to place modules and components alongside the routes that use them. A good rule of thumb is 'put code close to where it's used'.Sometimes, code is used in multiple places. When this happens, it's useful to have a place to put them that can be accessed by all routes without needing to prefix imports with ../../../../. In SvelteKit, that place is the src/lib directory. Anything inside this directory can be accessed by any module in src via the $lib alias.Both +page.svelte files in this exercise import src/lib/message.js. But if you navigate to /a/deeply/nested/route, the app breaks, because we got the prefix wrong. Update it to use $lib/message.js instead: \n<script>\n\timport { message } from +++'$lib/message.js'+++;\n</script>\n\n<h1>a deeply nested route</h1>\n<p>{message}</p>Do the same for src/routes/+page.svelte: \n<script>\n\timport { message } from +++'$lib/message.js'+++;\n</script>\n\n<h1>home</h1>\n<p>{message}</p>","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Forms","The <form> element"],"href":"/tutorial/kit/the-form-element","content":"In the chapter on loading data, we saw how to get data from the server to the browser. Sometimes you need to send data in the opposite direction, and that's where <form> — the web platform's way of submitting data — comes in.Let's build a todo app. We've already got an in-memory database set up in src/lib/server/database.js, and our load function in src/routes/+page.server.js uses the `cookies` API so that we can have a per-user todo list, but we need to add a <form> to create new todos: \n<h1>todos</h1>\n\n+++<form method=\"POST\">\n\t<label>\n\t\tadd a todo:\n\t\t<input\n\t\t\tname=\"description\"\n\t\t\tautocomplete=\"off\"\n\t\t/>\n\t</label>\n</form>+++\n\n<ul class=\"todos\">If we type something into the <input> and hit Enter, the browser makes a POST request (because of the method=\"POST\" attribute) to the current page. But that results in an error, because we haven't created a server-side action to handle the POST request. Let's do that now: \nimport * as db from '$lib/server/database.js';\n\nexport function load({ cookies }) {\n\t// ...\n}\n\n+++export const actions = {\n\tdefault: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\t\tdb.createTodo(cookies.get('userid'), data.get('description'));\n\t}\n};+++The request is a standard Request object; await request.formData() returns a `FormData` instance.When we hit Enter, the database is updated and the page reloads with the new data.Notice that we haven't had to write any fetch code or anything like that — data updates automatically. And because we're using a <form> element, this app would work even if JavaScript was disabled or unavailable.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Forms","Named form actions"],"href":"/tutorial/kit/named-form-actions","content":"A page that only has a single action is, in practice, quite rare. Most of the time you'll need to have multiple actions on a page. In this app, creating a todo isn't enough — we'd like to delete them once they're complete.Begin by replacing our default action with named create and delete actions: \nexport const actions = {\n\t+++create+++: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\t\tdb.createTodo(cookies.get('userid'), data.get('description'));\n\t}+++,+++\n\n+++\tdelete: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\t\tdb.deleteTodo(cookies.get('userid'), data.get('id'));\n\t}+++\n};[!NOTE] Default actions cannot coexist with named actions.The <form> element has an optional action attribute, which is similar to an <a> element's href attribute. Update the existing form so that it points to the new create action: \n<form method=\"POST\" +++action=\"?/create\"+++>\n\t<label>\n\t\tadd a todo:\n\t\t<input\n\t\t\tname=\"description\"\n\t\t\tautocomplete=\"off\"\n\t\t/>\n\t</label>\n</form>[!NOTE] The `action` attribute can be any URL — if the action was defined on another page, you might have something like `/todos?/create`. Since the action is on _this_ page, we can omit the pathname altogether, hence the leading `?` character.Next, we want to create a form for each todo, complete with a hidden <input> that uniquely identifies it: \n<ul class=\"todos\">\n\t{#each data.todos as todo (todo.id)}\n\t\t<li>\n+++\t\t\t<form method=\"POST\" action=\"?/delete\">\n\t\t\t\t<input type=\"hidden\" name=\"id\" value={todo.id} />\n\t\t\t\t<span>{todo.description}</span>\n\t\t\t\t<button aria-label=\"Mark as complete\"></button>\n\t\t\t</form>+++\n\t\t</li>\n\t{/each}\n</ul>","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Forms","Validation"],"href":"/tutorial/kit/form-validation","content":"Users are a mischievous bunch, who will submit all kinds of nonsensical data if given the chance. To prevent them from causing chaos, it's important to validate form data.The first line of defense is the browser's built-in form validation, which makes it easy to, for example, mark an <input> as required: \n<form method=\"POST\" action=\"?/create\">\n\t<label>\n\t\tadd a todo\n\t\t<input\n\t\t\tname=\"description\"\n\t\t\tautocomplete=\"off\"\n\t\t\t+++required+++\n\t\t/>\n\t</label>\n</form>Try hitting Enter while the <input> is empty.This kind of validation is helpful, but insufficient. Some validation rules (e.g. uniqueness) can't be expressed using <input> attributes, and in any case, if the user is an elite hacker they might simply delete the attributes using the browser's devtools. To guard against these sorts of shenanigans, you should always use server-side validation.In src/lib/server/database.js, validate that the description exists and is unique: \nexport function createTodo(userid, description) {\n+++\tif (description === '') {\n\t\tthrow new Error('todo must have a description');\n\t}+++\n\n\tconst todos = db.get(userid);\n\n+++\tif (todos.find((todo) => todo.description === description)) {\n\t\tthrow new Error('todos must be unique');\n\t}+++\n\n\ttodos.push({\n\t\tid: crypto.randomUUID(),\n\t\tdescription,\n\t\tdone: false\n\t});\n}Try submitting a duplicate todo. Yikes! SvelteKit takes us to an unfriendly-looking error page. On the server, we see a 'todos must be unique' error, but SvelteKit hides unexpected error messages from users because they often contain sensitive data.It would be much better to stay on the same page and provide an indication of what went wrong so that the user can fix it. To do this, we can use the fail function to return data from the action along with an appropriate HTTP status code: \n+++import { fail } from '@sveltejs/kit';+++\nimport * as db from '$lib/server/database.js';\n\nexport function load({ cookies }) {...}\n\nexport const actions = {\n\tcreate: async ({ cookies, request }) => {\n\t\tconst data = await request.formData();\n\n+++\t\ttry {+++\n\t\t\tdb.createTodo(cookies.get('userid'), data.get('description'));\n+++\t\t} catch (error) {\n\t\t\treturn fail(422, {\n\t\t\t\tdescription: data.get('description'),\n\t\t\t\terror: error.message\n\t\t\t});\n\t\t}+++\n\t}In src/routes/+page.svelte, we can access the returned value via the form prop, which is only ever populated after a form submission: \n<script>\n\tlet { data, +++form+++ } = $props();\n</script>\n\n<div class=\"centered\">\n\t<h1>todos</h1>\n\n\t+++{#if form?.error}\n\t\t<p class=\"error\">{form.error}</p>\n\t{/if}+++\n\n\t<form method=\"POST\" action=\"?/create\">\n\t\t<label>\n\t\t\tadd a todo:\n\t\t\t<input\n\t\t\t\tname=\"description\"\n\t\t\t\t+++value={form?.description ?? ''}+++\n\t\t\t\tautocomplete=\"off\"\n\t\t\t\trequired\n\t\t\t/>\n\t\t</label>\n\t</form>[!NOTE] You can also return data from an action _without_ wrapping it in `fail` — for example to show a 'success!' message when data was saved — and it will be available via the `form` prop.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Forms","Progressive enhancement"],"href":"/tutorial/kit/progressive-enhancement","content":"Because we're using <form>, our app works even if the user doesn't have JavaScript (which happens more often than you probably think). That's great, because it means our app is resilient.Most of the time, users do have JavaScript. In those cases, we can progressively enhance the experience, the same way SvelteKit progressively enhances <a> elements by using client-side routing.Import the enhance function from $app/forms... \n<script>\n\t+++import { enhance } from '$app/forms';+++\n\n\tlet { data, form } = $props();\n</script>...and add the use:enhance directive to the <form> elements: \n<form method=\"POST\" action=\"?/create\" +++use:enhance+++> \n<form method=\"POST\" action=\"?/delete\" +++use:enhance+++>And that's all it takes! Now, when JavaScript is enabled, use:enhance will emulate the browser-native behaviour except for the full-page reloads. It will:update the `form` prop\ninvalidate all data on a successful response, causing `load` functions to re-run\nnavigate to the new page on a redirect response\nrender the nearest error page if an error occursNow that we're updating the page rather than reloading it, we can get fancy with things like transitions: \n<script>\n\t+++import { fly, slide } from 'svelte/transition';+++\n\timport { enhance } from '$app/forms';\n\n\tlet { data, form } = $props();\n</script> \n<li +++in:fly={{ y: 20 }} out:slide+++>...</li>","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Forms","Customizing use:enhance"],"href":"/tutorial/kit/customizing-use-enhance","content":"With use:enhance, we can go further than just emulating the browser's native behaviour. By providing a callback, we can add things like pending states and optimistic UI. Let's simulate a slow network by adding an artificial delay to our two actions: \nexport const actions = {\n\tcreate: async ({ cookies, request }) => {\n\t\t+++await new Promise((fulfil) => setTimeout(fulfil, 1000));+++\n\t\t...\n\t},\n\n\tdelete: async ({ cookies, request }) => {\n\t\t+++await new Promise((fulfil) => setTimeout(fulfil, 1000));+++\n\t\t...\n\t}\n};When we create or delete items, it now takes a full second before the UI updates, leaving the user wondering if they messed up somehow. To solve that, add some local state... \n<script>\n\timport { fly, slide } from 'svelte/transition';\n\timport { enhance } from '$app/forms';\n\n\tlet { data, form } = $props();\n\n+++\tlet creating = $state(false);\n\tlet deleting = $state([]);+++\n</script>...and toggle creating inside the first use:enhance: \n<form\n\tmethod=\"POST\"\n\taction=\"?/create\"\n+++\tuse:enhance={() => {\n\t\tcreating = true;\n\n\t\treturn async ({ update }) => {\n\t\t\tawait update();\n\t\t\tcreating = false;\n\t\t};\n\t}}+++\n>\n\t<label>\n\t\tadd a todo:\n\t\t<input\n\t\t\t+++disabled={creating}+++\n\t\t\tname=\"description\"\n\t\t\tvalue={form?.description ?? ''}\n\t\t\tautocomplete=\"off\"\n\t\t\trequired\n\t\t/>\n\t</label>\n</form>We can then show a message while we're saving data: \n<ul class=\"todos\">\n\t<!-- ... -->\n</ul>\n\n+++{#if creating}\n\t<span class=\"saving\">saving...</span>\n{/if}+++In the case of deletions, we don't really need to wait for the server to validate anything — we can just update the UI immediately: \n<ul class=\"todos\">\n\t{#each +++data.todos.filter((todo) => !deleting.includes(todo.id))+++ as todo (todo.id)}\n\t\t<li in:fly={{ y: 20 }} out:slide>\n\t\t\t<form\n\t\t\t\tmethod=\"POST\"\n\t\t\t\taction=\"?/delete\"\n\t\t\t\t+++use:enhance={() => {\n\t\t\t\t\tdeleting = [...deleting, todo.id];\n\t\t\t\t\treturn async ({ update }) => {\n\t\t\t\t\t\tawait update();\n\t\t\t\t\t\tdeleting = deleting.filter((id) => id !== todo.id);\n\t\t\t\t\t};\n\t\t\t\t}}+++\n\t\t\t>\n\t\t\t\t<input type=\"hidden\" name=\"id\" value={todo.id} />\n\t\t\t\t<button aria-label=\"Mark as complete\">✔</button>\n\n\t\t\t\t{todo.description}\n\t\t\t</form>\n\t\t</li>\n\t{/each}\n</ul>[!NOTE] `use:enhance` is very customizable — you can `cancel()` submissions, handle redirects, control whether the form is reset, and so on. [See the docs](/docs/kit/$app-forms#enhance) for full details.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","API routes","GET handlers"],"href":"/tutorial/kit/get-handlers","content":"SvelteKit allows you to create more than just pages. We can also create API routes by adding a +server.js file that exports functions corresponding to HTTP methods: GET, PUT, POST, PATCH and DELETE.This app fetches data from a /roll API route when you click the button. Create that route by adding a src/routes/roll/+server.js file: \nexport function GET() {\n\tconst number = Math.floor(Math.random() * 6) + 1;\n\n\treturn new Response(number, {\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json'\n\t\t}\n\t});\n}Clicking the button now works.Request handlers must return a Response object. Since it's common to return JSON from an API route, SvelteKit provides a convenience function for generating these responses: \n+++import { json } from '@sveltejs/kit';+++\n\nexport function GET() {\n\tconst number = Math.floor(Math.random() * 6) + 1;\n\n---\treturn new Response(number, {\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json'\n\t\t}\n\t});---\n+++\treturn json(number);+++\n}","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","API routes","POST handlers"],"href":"/tutorial/kit/post-handlers","content":"You can also add handlers that mutate data, such as POST. In most cases, you should use form actions instead — you'll end up writing less code, and it'll work without JavaScript, making it more resilient.Inside the keydown event handler of the 'add a todo' <input>, let's post some data to the server: \n<input\n\ttype=\"text\"\n\tautocomplete=\"off\"\n\tonkeydown={async (e) => {\n\t\tif (e.key !== 'Enter') return;\n\n\t\tconst input = e.currentTarget;\n\t\tconst description = input.value;\n\n+++\t\tconst response = await fetch('/todo', {\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify({ description }),\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json'\n\t\t\t}\n\t\t});+++\n\n\t\tinput.value = '';\n\t}}\n/>Here, we're posting some JSON to the /todo API route — using a userid from the user's cookies — and receiving the id of the newly created todo in response.Create the /todo route by adding a src/routes/todo/+server.js file with a POST handler that calls createTodo in src/lib/server/database.js: \nimport { json } from '@sveltejs/kit';\nimport * as database from '$lib/server/database.js';\n\nexport async function POST({ request, cookies }) {\n\tconst { description } = await request.json();\n\n\tconst userid = cookies.get('userid');\n\tconst { id } = await database.createTodo({ userid, description });\n\n\treturn json({ id }, { status: 201 });\n}As with load functions and form actions, the request is a standard Request object; await request.json() returns the data that we posted from the event handler.We're returning a response with a 201 Created status and the id of the newly generated todo in our database. Back in the event handler, we can use this to update the page: \n<input\n\ttype=\"text\"\n\tautocomplete=\"off\"\n\tonkeydown={async (e) => {\n\t\tif (e.key !== 'Enter') return;\n\n\t\tconst input = e.currentTarget;\n\t\tconst description = input.value;\n\n\t\tconst response = await fetch('/todo', {\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify({ description }),\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json'\n\t\t\t}\n\t\t});\n\n+++\t\tconst { id } = await response.json();\n\n\t\tconst todos = [...data.todos, {\n\t\t\tid,\n\t\t\tdescription\n\t\t}];\n\n\t\tdata = { ...data, todos };+++\n\n\t\tinput.value = '';\n\t}}\n/>[!NOTE] You should only update `data` in such a way that you'd get the same result by reloading the page. The `data` prop is not _deeply_ reactive, so you need to replace it — mutations like `data.todos = todos` will not cause a re-render.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","API routes","Other handlers"],"href":"/tutorial/kit/other-handlers","content":"Similarly, we can add handlers for other HTTP verbs. Add a /todo/[id] route by creating a src/routes/todo/[id]/+server.js file with PUT and DELETE handlers for toggling and removing todos, using the toggleTodo and deleteTodo functions in src/lib/server/database.js: \nimport * as database from '$lib/server/database.js';\n\nexport async function PUT({ params, request, cookies }) {\n\tconst { done } = await request.json();\n\tconst userid = cookies.get('userid');\n\n\tawait database.toggleTodo({ userid, id: params.id, done });\n\treturn new Response(null, { status: 204 });\n}\n\nexport async function DELETE({ params, cookies }) {\n\tconst userid = cookies.get('userid');\n\n\tawait database.deleteTodo({ userid, id: params.id });\n\treturn new Response(null, { status: 204 });\n}Since we don't need to return any actual data to the browser, we're returning an empty Response with a 204 No Content status.We can now interact with this endpoint inside our event handlers: \n<label>\n\t<input\n\t\ttype=\"checkbox\"\n\t\tchecked={todo.done}\n\t\tonchange={async (e) => {\n\t\t\tconst done = e.currentTarget.checked;\n\n+++\t\t\tawait fetch(`/todo/${todo.id}`, {\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tbody: JSON.stringify({ done }),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t}\n\t\t\t});+++\n\t\t}}\n\t/>\n\t<span>{todo.description}</span>\n\t<button\n\t\taria-label=\"Mark as complete\"\n\t\tonclick={async (e) => {\n+++\t\t\tawait fetch(`/todo/${todo.id}`, {\n\t\t\t\tmethod: 'DELETE'\n\t\t\t});\n\n\t\t\tconst todos = data.todos.filter((t) => t !== todo);\n\n\t\t\tdata = { ...data, todos };+++\n\t\t}}\n\t></button>\n</label>","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","$app/state","page"],"href":"/tutorial/kit/page-state","content":"SvelteKit makes three readonly state objects available via the $app/state module — page, navigating and updated. The one you'll use most often is `page`, which provides information about the current page:`url` — the [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) of the current page\n`params` — the current page's [parameters](params)\n`route` — an object with an `id` property representing the current route\n`status` — the HTTP status code of the current page\n`error` — the error object of the current page, if any (you'll learn more about error handling in [later](error-basics) [exercises](handleerror))\n`data` — the data for the current page, combining the return values of all `load` functions\n`form` — the data returned from a [form action](the-form-element)Each of these properties is reactive, using $state.raw under the hood. Here's an example using page.url.pathname: \n<script>\n\t+++import { page } from '$app/state';+++\n\n\tlet { children } = $props();\n</script>\n\n<nav>\n\t<a href=\"/\" +++aria-current={page.url.pathname === '/'}+++>\n\t\thome\n\t</a>\n\n\t<a href=\"/about\" +++aria-current={page.url.pathname === '/about'}+++>\n\t\tabout\n\t</a>\n</nav>\n\n{@render children()}[!NOTE] Prior to SvelteKit 2.12, you had to use `$app/stores` for this, which provides a `$page` store with the same information. If you're currently using `$app/stores`, we advise you to migrate towards `$app/state` (requires Svelte 5).","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","$app/state","navigating"],"href":"/tutorial/kit/navigating-state","content":"The navigating object represents the current navigation. When a navigation starts — because of a link click, or a back/forward navigation, or a programmatic goto — the value of navigating will become an object with the following properties:`from` and `to` — objects with `params`, `route` and `url` properties\n`type` — the type of navigation, e.g. `link`, `popstate` or `goto`[!NOTE] For complete type information visit the [`Navigation`](/docs/kit/@sveltejs-kit#Navigation) documentation.It can be used to show a loading indicator for long-running navigations. In this exercise, src/routes/+page.server.js and src/routes/about/+page.server.js both have an artificial delay. Inside src/routes/+layout.svelte, import the navigating object and add a message to the nav bar: \n<script>\n\timport { page, +++navigating+++ } from '$app/state';\n\n\tlet { children } = $props();\n</script>\n\n<nav>\n\t<a href=\"/\" aria-current={page.url.pathname === '/'}>\n\t\thome\n\t</a>\n\n\t<a href=\"/about\" aria-current={page.url.pathname === '/about'}>\n\t\tabout\n\t</a>\n\n+++\t{#if navigating.to}\n\t\tnavigating to {navigating.to.url.pathname}\n\t{/if}+++\n</nav>\n\n{@render children()}[!NOTE] Prior to SvelteKit 2.12, you had to use `$app/stores` for this, which provides a `$navigating` store with the same information. If you're currently using `$app/stores`, we advise you to migrate towards `$app/state` (requires Svelte 5).","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","$app/state","updated"],"href":"/tutorial/kit/updated-state","content":"The updated state contains true or false depending on whether a new version of the app has been deployed since the page was first opened. For this to work, your svelte.config.js must specify kit.version.pollInterval. \n<script>\n\timport { page, navigating, +++updated+++ } from '$app/state';\n</script>Version changes only happen in production, not during development. For that reason, updated.current will always be false in this tutorial.You can manually check for new versions, regardless of pollInterval, by calling updated.check(). \n\n+++{#if updated.current}+++\n\t<div class=\"toast\">\n\t\t<p>\n\t\t\tA new version of the app is available\n\n\t\t\t<button onclick={() => location.reload()}>\n\t\t\t\treload the page\n\t\t\t</button>\n\t\t</p>\n\t</div>\n+++{/if}+++[!NOTE] Prior to SvelteKit 2.12, you had to use `$app/stores` for this, which provides an `$updated` store with the same information. If you're currently using `$app/stores`, we advise you to migrate towards `$app/state` (requires Svelte 5).","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Errors and redirects","Basics"],"href":"/tutorial/kit/error-basics","content":"There are two types of errors in SvelteKit — expected errors and unexpected errors.An expected error is one that was thrown via the `error` helper from @sveltejs/kit, as in src/routes/expected/+page.server.js: \nimport { error } from '@sveltejs/kit';\n\nexport function load() {\n\terror(420, 'Enhance your calm');\n}Any other error — such as the one in src/routes/unexpected/+page.server.js — is treated as unexpected: \nexport function load() {\n\tthrow new Error('Kaboom!');\n}When you throw an expected error, you're telling SvelteKit 'don't worry, I know what I'm doing here'. An unexpected error, by contrast, is assumed to be a bug in your app. When an unexpected error is thrown, its message and stack trace will be logged to the console.[!NOTE] In a later chapter we'll learn about how to add custom error handling using the `handleError` hook.If you click the links in this app, you'll notice an important difference: the expected error message is shown to the user, whereas the unexpected error message is redacted and replaced with a generic 'Internal Error' message and a 500 status code. That's because error messages can contain sensitive data.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Errors and redirects","Error pages"],"href":"/tutorial/kit/error-pages","content":"When something goes wrong inside a load function, SvelteKit renders an error page.The default error page is somewhat bland. We can customize it by creating a src/routes/+error.svelte component: \n<script>\n\timport { page } from '$app/state';\n\timport { emojis } from './emojis.js';\n</script>\n\n<h1>{page.status} {page.error.message}</h1>\n<span style=\"font-size: 10em\">\n\t{emojis[page.status] ?? emojis[500]}\n</span>Notice that the +error.svelte component is rendered inside the root +layout.svelte. We can create more granular +error.svelte boundaries: \n<h1>this error was expected</h1>This component will be rendered for /expected, while the root src/routes/+error.svelte page will be rendered for any other errors that occur.","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Errors and redirects","Fallback errors"],"href":"/tutorial/kit/fallback-errors","content":"If things go really wrong — an error occurs while loading the root layout data, or while rendering the error page — SvelteKit will fall back to a static error page.Add a new src/routes/+layout.server.js file to see this in action: \nexport function load() {\n\tthrow new Error('yikes');\n}You can customise the fallback error page. Create a src/error.html file: \n<h1>Game over</h1>\n<p>Code %sveltekit.status%</p>\n<p>%sveltekit.error.message%</p>This file can include the following:`%sveltekit.status%` — the HTTP status code\n`%sveltekit.error.message%` — the error message","rank":null},{"breadcrumbs":["Tutorial","Basic SvelteKit","Errors and redirects","Redirects"],"href":"/tutorial/kit/redirects","content":"We can use the redirect mechanism to redirect from one page to another.Create a new load function in src/routes/a/+page.server.js: \nimport { redirect } from '@sveltejs/kit';\n\nexport function load() {\n\tredirect(307, '/b');\n}Navigating to /a will now take us straight to /b.You can redirect(...) inside load functions, form actions, API routes and the handle hook, which we'll discuss in a later chapter.The most common status codes you'll use:`303` — for form actions, following a successful submission\n`307` — for temporary redirects\n`308` — for permanent redirects[!NOTE] `redirect(...)` throws, like `error(...)`, meaning no code _after_ the redirect will run.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Hooks","handle"],"href":"/tutorial/kit/handle","content":"SvelteKit provides several hooks — ways to intercept and override the framework's default behaviour.The most elementary hook is handle, which lives in src/hooks.server.js. It receives an event object along with a resolve function, and returns a `Response`.resolve is where the magic happens: SvelteKit matches the incoming request URL to a route of your app, imports the relevant code (+page.server.js and +page.svelte files and so on), loads the data needed by the route, and generates the response.The default handle hook looks like this: \nexport async function handle({ event, resolve }) {\n\treturn await resolve(event);\n}For pages (as opposed to API routes), you can modify the generated HTML with transformPageChunk: \nexport async function handle({ event, resolve }) {\n\treturn await resolve(event, {\n+++\t\ttransformPageChunk: ({ html }) => html.replace(\n\t\t\t'<body',\n\t\t\t'<body style=\"color: hotpink\"'\n\t\t)+++\n\t});\n}You can also create entirely new routes: \nexport async function handle({ event, resolve }) {\n+++\tif (event.url.pathname === '/ping') {\n\t\treturn new Response('pong');\n\t}+++\n\n\treturn await resolve(event, {\n\t\ttransformPageChunk: ({ html }) => html.replace(\n\t\t\t'<body',\n\t\t\t'<body style=\"color: hotpink\"'\n\t\t)\n\t});\n}","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Hooks","The RequestEvent object"],"href":"/tutorial/kit/event","content":"The event object passed into handle is the same object — an instance of a `RequestEvent` — that is passed into API routes in +server.js files, form actions in +page.server.js files, and load functions in +page.server.js and +layout.server.js.It contains a number of useful properties and methods, some of which we've already encountered:`cookies` — the [cookies API](cookies)\n`fetch` — the standard [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), with additional powers\n`getClientAddress()` — a function to get the client's IP address\n`isDataRequest` — `true` if the browser is requesting data for a page during client-side navigation, `false` if a page/route is being requested directly\n`locals` — a place to put arbitrary data\n`params` — the route parameters\n`request` — the [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object\n`route` — an object with an `id` property representing the route that was matched\n`setHeaders(...)` — a function for [setting HTTP headers](headers) on the response\n`url` — a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object representing the current requestA useful pattern is to add some data to event.locals in handle so that it can be read in subsequent load functions: \nexport async function handle({ event, resolve }) {\n\t+++event.locals.answer = 42;+++\n\treturn await resolve(event);\n} \nexport function load(+++event+++) {\n\treturn {\n\t\tmessage: `the answer is ${+++event.locals.answer+++}`\n\t};\n}","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Hooks","handleFetch"],"href":"/tutorial/kit/handlefetch","content":"The event object has a fetch method that behaves like the standard Fetch API, but with superpowers:it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers from the incoming request\nit can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)\ninternal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP callIts behaviour can be modified with the handleFetch hook, which by default looks like this: \nexport async function handleFetch({ event, request, fetch }) {\n\treturn await fetch(request);\n}For example, we could respond to requests for src/routes/a/+server.js with responses from src/routes/b/+server.js instead: \nexport async function handleFetch({ event, request, fetch }) {\n+++\tconst url = new URL(request.url);\n\tif (url.pathname === '/a') {\n\t\treturn await fetch('/b');\n\t}+++\n\n\treturn await fetch(request);\n}Later, when we cover universal `load` functions, we'll see that event.fetch can also be called from the browser. In that scenario, handleFetch is useful if you have requests to a public URL like https://api.yourapp.com from the browser, that should be redirected to an internal URL (bypassing whatever proxies and load balancers sit between the API server and the public internet) when running on the server.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Hooks","handleError"],"href":"/tutorial/kit/handleerror","content":"The handleError hook lets you intercept unexpected errors and trigger some behaviour, like pinging a Slack channel or sending data to an error logging service.As you'll recall from an earlier exercise, an error is unexpected if it wasn't created with the error helper from @sveltejs/kit. It generally means something in your app needs fixing. The default behaviour is to log the error: \nexport function handleError({ event, error }) {\n\tconsole.error(error.stack);\n}If you navigate to /the-bad-place, you'll see this in action — the error page is shown, and if you open the terminal (using the button to the right of the URL bar), you'll see the message from src/routes/the-bad-place/+page.server.js.Notice that we're not showing the error message to the user. That's because error messages can include sensitive information that at best will confuse your users, and at worst could benefit evildoers. Instead, the error object available to your application — represented as page.error in your +error.svelte pages, or %sveltekit.error% in your src/error.html fallback — is just this:\n{\n\tmessage: 'Internal Error' // or 'Not Found' for a 404\n}\nIn some situations you may want to customise this object. To do so, you can return an object from handleError: \nexport function handleError({ event, error }) {\n\tconsole.error(error.stack);\n\n\t+++return {\n\t\tmessage: 'everything is fine',\n\t\tcode: 'JEREMYBEARIMY'\n\t};+++\n}You can now reference properties other than message in a custom error page. Create src/routes/+error.svelte: \n<script>\n\timport { page } from '$app/state';\n</script>\n\n<h1>{page.status}</h1>\n<p>{page.error.message}</p>\n<p>error code: {page.error.code}</p>","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Page options","Basics"],"href":"/tutorial/kit/page-options","content":"In the chapter on loading data, we saw how you can export load functions from +page.js, +page.server.js, +layout.js and +layout.server.js files. We can also export various page options from these modules:`ssr` — whether or not pages should be server-rendered\n`csr` — whether to load the SvelteKit client\n`prerender` — whether to prerender pages at build time, instead of per-request\n`trailingSlash` — whether to strip, add, or ignore trailing slashes in URLsIn the following exercises, we'll learn about each of these in turn.Page options can apply to individual pages (if exported from +page.js or +page.server.js), or groups of pages (if exported from +layout.js or +layout.server.js). To define an option for the whole app, export it from the root layout. Child layouts and pages override values set in parent layouts, so — for example — you can enable prerendering for your entire app then disable it for pages that need to be dynamically rendered.You can mix and match these options in different areas of your app — you could prerender your marketing pages, dynamically server-render your data-driven pages, and treat your admin pages as a client-rendered SPA. This makes SvelteKit very versatile.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Page options","ssr"],"href":"/tutorial/kit/ssr","content":"Server-side rendering (SSR) is the process of generating HTML on the server, and is what SvelteKit does by default. It's important for performance and resilience, and is very beneficial for search engine optimization (SEO) — while some search engines can index content that is rendered in the browser with JavaScript, it happens less frequently and reliably.That said, some components can't be rendered on the server, perhaps because they expect to be able to access browser globals like window immediately. If you can, you should change those components so that they can render on the server, but if you can't then you can disable SSR: \nexport const ssr = false;[!NOTE] Setting `ssr` to `false` inside your root `+layout.server.js` effectively turns your entire app into a single-page app (SPA).","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Page options","csr"],"href":"/tutorial/kit/csr","content":"Client-side rendering is what makes the page interactive — such as incrementing the counter when you click the button in this app — and enables SvelteKit to update the page upon navigation without a full-page reload.As with ssr, you can disable client-side rendering altogether: \nexport const csr = false;This means that no JavaScript is served to the client, but it also means that your components are no longer interactive. It can be a useful way to check whether or not your application is usable for people who — for whatever reason — cannot use JavaScript.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Page options","prerender"],"href":"/tutorial/kit/prerender","content":"Prerendering means generating HTML for a page once, at build time, rather than dynamically for each request.The advantage is that serving static data is extremely cheap and performant, allowing you to easily serve large numbers of users without worrying about cache-control headers (which are easy to get wrong).The tradeoff is that the build process takes longer, and prerendered content can only be updated by building and deploying a new version of the application.To prerender a page, set prerender to true: \nexport const prerender = true;Here in the tutorial, this won't have any observable effect, since the application is running in dev mode.Not all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain form actions. Pages with dynamic route parameters can be prerendered as long as they are specified in the `prerender.entries` configuration or can be reached by following links from pages that are in prerender.entries.[!NOTE] Setting `prerender` to `true` inside your root `+layout.server.js` effectively turns SvelteKit into a static site generator (SSG).","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Page options","trailingSlash"],"href":"/tutorial/kit/trailingslash","content":"Two URLs like /foo and /foo/ might look the same, but they're actually different. A relative URL like ./bar will resolve to /bar in the first case and /foo/bar in the second, and search engines will treat them as separate entries, harming your SEO.In short, being loosey-goosey about trailing slashes is a bad idea. By default, SvelteKit strips trailing slashes, meaning that a request for /foo/ will result in a redirect to /foo.If you instead want to ensure that a trailing slash is always present, you can specify the trailingSlash option accordingly: \nexport const trailingSlash = 'always';To accommodate both cases (this is not recommended!), use 'ignore': \nexport const trailingSlash = 'ignore';The default value is 'never'.Whether or not trailing slashes are applied affects prerendering. A URL like /always/ will be saved to disk as always/index.html whereas a URL like /never will be saved as never.html.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Link options","Preloading"],"href":"/tutorial/kit/preload","content":"In this exercise, the /slow-a and /slow-b routes both have artificial delays in their load functions, meaning it takes a long time to navigate to them.You can't always make your data load more quickly — sometimes it's out of your control — but SvelteKit can speed up navigations by anticipating them. When an <a> element has a data-sveltekit-preload-data attribute, SvelteKit will begin the navigation as soon as the user hovers over the link (on desktop) or taps it (on mobile). Try adding it to the first link: \n<nav>\n\t<a href=\"/\">home</a>\n\t<a href=\"/slow-a\" +++data-sveltekit-preload-data+++>slow-a</a>\n\t<a href=\"/slow-b\">slow-b</a>\n</nav>Navigating to /slow-a will now be noticeably faster. Starting navigation on hover or tap (rather than waiting for a click event to be registered) might not sound like it makes much difference, but in practice it typically saves 200ms or more. That's enough to be the difference between sluggish and snappy.You can put the attribute on individual links, or on any element that contains links. The default project template includes the attribute on the <body> element:<body data-sveltekit-preload-data>\n\t%sveltekit.body%\n</body>You can customise the behaviour further by specifying one of the following values for the attribute:`\"hover\"` (default, falls back to `\"tap\"` on mobile)\n`\"tap\"` — only begin preloading on tap\n`\"false\"` — disable preloadingUsing data-sveltekit-preload-data may sometimes result in false positives - i.e. loading data in anticipation of a navigation that doesn't then happen — which might be undesirable. As an alternative, data-sveltekit-preload-code allows you to preload the JavaScript needed by a given route without eagerly loading its data. This attribute can have the following values:`\"eager\"` — preload everything on the page following a navigation\n`\"viewport\"` — preload everything as it appears in the viewport\n`\"hover\"` (default) as above\n`\"tap\"` — as above\n`\"false\"` — as aboveYou can also initiate preloading programmatically with preloadCode and preloadData imported from $app/navigation:import { preloadCode, preloadData } from '$app/navigation';\n\n// preload the code and data needed to navigate to /foo\npreloadData('/foo');\n\n// preload the code needed to navigate to /bar, but not the data\npreloadCode('/bar');","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Link options","Reloading the page"],"href":"/tutorial/kit/reload","content":"Ordinarily, SvelteKit will navigate between pages without refreshing the page. In this exercise, if we navigate between / and /about, the timer keeps on ticking.In rare cases, you might want to disable this behaviour. You can do so by adding the data-sveltekit-reload attribute on an individual link, or any element that contains links: \n<nav +++data-sveltekit-reload+++>\n\t<a href=\"/\">home</a>\n\t<a href=\"/about\">about</a>\n</nav>For more information on available link options and their values, consult the link options documentation.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced routing","Optional parameters"],"href":"/tutorial/kit/optional-params","content":"In the first chapter on routing, we learned how to create routes with dynamic parameters.Sometimes it's helpful to make a parameter optional. A classic example is when you use the pathname to determine the locale — /fr/..., /de/... and so on — but you also want to have a default locale.To do that, we use double brackets. Rename the [lang] directory to [[lang]].The app now fails to build, because src/routes/+page.svelte and src/routes/[[lang]]/+page.svelte would both match /. Delete src/routes/+page.svelte. (You may need to reload the app to recover from the error page).Lastly, edit src/routes/[[lang]]/+page.server.js to specify the default locale: \nconst greetings = {\n\ten: 'hello!',\n\tde: 'hallo!',\n\tfr: 'bonjour!'\n};\n\nexport function load({ params }) {\n\treturn {\n\t\tgreeting: greetings[params.lang +++?? 'en'+++]\n\t};\n}","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced routing","Rest parameters"],"href":"/tutorial/kit/rest-params","content":"To match an unknown number of path segments, use a [...rest] parameter, so named for its resemblance to rest parameters in JavaScript.Rename src/routes/[path] to src/routes/[...path]. The route now matches any path.[!NOTE] Other, more specific routes will be tested first, making rest parameters useful as 'catch-all' routes. For example, if you needed a custom 404 page for pages inside `/categories/...`, you could add these files:\n\n```tree\nsrc/routes/\n├ categories/\n│ ├ animal/\n│ ├ mineral/\n│ ├ vegetable/\n+++│ ├ [...catchall]/\n│ │ ├ +error.svelte\n│ │ └ +page.server.js+++\n```\n\nInside the `+page.server.js` file, `error(404)` inside `load`.Rest parameters do not need to go at the end — a route like /items/[...path]/edit or /items/[...path].json is totally valid.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced routing","Param matchers"],"href":"/tutorial/kit/param-matchers","content":"To prevent the router from matching on invalid input, you can specify a matcher. For example, you might want a route like /colors/[value] to match hex values like /colors/ff3e00 but not named colors like /colors/octarine or any other arbitrary input.First, create a new file called src/params/hex.js and export a match function from it: \nexport function match(value) {\n\treturn /^[0-9a-f]{6}$/.test(value);\n}Then, to use the new matcher, rename src/routes/colors/[color] to src/routes/colors/[color=hex].Now, whenever someone navigates to that route, SvelteKit will verify that color is a valid hex value. If not, SvelteKit will try to match other routes, before eventually returning a 404.[!NOTE] Matchers run both on the server and in the browser.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced routing","Route groups"],"href":"/tutorial/kit/route-groups","content":"As we saw in the routing introduction, layouts are a way to share UI and data loading logic between different routes.Sometimes it's useful to use layouts without affecting the route — for example, you might need your /app and /account routes to be behind authentication, while your /about page is open to the world. We can do this with a route group, which is a directory in parentheses.Create an (authed) group by renaming account to (authed)/account then renaming app to (authed)/app.Now we can control access to these routes by creating src/routes/(authed)/+layout.server.js: \nimport { redirect } from '@sveltejs/kit';\n\nexport function load({ cookies, url }) {\n\tif (!cookies.get('logged_in')) {\n\t\tredirect(303, `/login?redirectTo=${url.pathname}`);\n\t}\n}If you try to visit these pages, you'll be redirected to the /login route, which has a form action in src/routes/login/+page.server.js that sets the logged_in cookie.We can also add some UI to these two routes by adding a src/routes/(authed)/+layout.svelte file: \n<script>\n\tlet { children } = $props();\n</script>\n\n{@render children()}\n\n<form method=\"POST\" action=\"/logout\">\n\t<button>log out</button>\n</form>","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced routing","Breaking out of layouts"],"href":"/tutorial/kit/breaking-out-of-layouts","content":"Ordinarily, a page inherits every layout above it, meaning that src/routes/a/b/c/+page.svelte inherits four layouts:`src/routes/+layout.svelte`\n`src/routes/a/+layout.svelte`\n`src/routes/a/b/+layout.svelte`\n`src/routes/a/b/c/+layout.svelte`Occasionally, it's useful to break out of the current layout hierarchy. We can do that by adding the @ sign followed by the name of the parent segment to 'reset' to — for example +page@b.svelte would put /a/b/c inside src/routes/a/b/+layout.svelte, while +page@a.svelte would put it inside src/routes/a/+layout.svelte.Let's reset it all the way to the root layout, by renaming it to +page@.svelte.[!NOTE] The root layout applies to every page of your app, you cannot break out of it.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","Universal load functions"],"href":"/tutorial/kit/universal-load-functions","content":"In the previous section on loading we loaded data from the server using +page.server.js and +layout.server.js files. This is very convenient if you need to do things like getting data directly from a database, or reading cookies.Sometimes it doesn't make sense to load data from the server when doing a client-side navigation. For example:You're loading data from an external API\nYou want to use in-memory data if it's available\nYou want to delay navigation until an image has been preloaded, to avoid pop-in\nYou need to return something from `load` that can't be serialized (SvelteKit uses [devalue](https://github.com/Rich-Harris/devalue) to turn server data into JSON), such as a component or a storeIn this exercise, we're dealing with the latter case. The server load functions in src/routes/red/+page.server.js, src/routes/green/+page.server.js and src/routes/blue/+page.server.js return a component constructor, which can't be serialized like data. If you navigate to /red, /green or /blue, you'll see a 'Data returned from load ... is not serializable' error in the terminal.To turn the server load functions into universal load functions, rename each +page.server.js file to +page.js. Now, the functions will run on the server during server-side rendering, but will also run in the browser when the app hydrates or the user performs a client-side navigation.We can now use the component returned from these load functions like any other value, including in src/routes/+layout.svelte: \n<nav\n\tclass={[page.data.color && 'has-color']}\n\tstyle:background={page.data.color ?? 'var(--bg-2)'}\n>\n\t<a href=\"/\">home</a>\n\t<a href=\"/red\">red</a>\n\t<a href=\"/green\">green</a>\n\t<a href=\"/blue\">blue</a>\n\n+++\t{#if page.data.component}\n\t\t<page.data.component />\n\t{/if}+++\n</nav>Read the documentation to learn more about the distinction between server load functions and universal load functions, and when to use which.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","Using both load functions"],"href":"/tutorial/kit/using-both-load-functions","content":"Occasionally, you might need to use a server load function and a universal load function together. For example, you might need to return data from the server, but also return a value that can't be serialized as server data.In this example we want to return a different component from load depending on whether the data we got from src/routes/+page.server.js is cool or not.We can access server data in src/routes/+page.js via the data property: \nexport async function load(+++{ data }+++) {\n\tconst module = +++data.cool+++\n\t\t? await import('./CoolComponent.svelte')\n\t\t: await import('./BoringComponent.svelte');\n\n\treturn {\n\t\tcomponent: module.default,\n\t\tmessage: +++data.message+++\n\t};\n}[!NOTE] Note that the data isn't merged — we must explicitly return `message` from the universal `load` function.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","Using parent data"],"href":"/tutorial/kit/await-parent","content":"As we saw in the introduction to layout data, +page.svelte and +layout.svelte components have access to everything returned from their parent load functions.Occasionally it's useful for the load functions themselves to access data from their parents. This can be done with await parent().To show how it works, we'll sum two numbers that come from different load functions. First, return some data from src/routes/+layout.server.js: \nexport function load() {\n\treturn { +++a: 1+++ };\n}Then, get that data in src/routes/sum/+layout.js: \nexport async function load(+++{ parent }+++) {\n\t+++const { a } = await parent();+++\n\treturn { +++b: a + 1+++ };\n}[!NOTE] Notice that a [universal](/tutorial/kit/universal-load-functions) `load` function can get data from a parent _server_ `load` function. The reverse is not true — a server load function can only get parent data from another server load function.Finally, in src/routes/sum/+page.js, get parent data from both load functions: \nexport async function load(+++{ parent }+++) {\n\t+++const { a, b } = await parent();+++\n\treturn { +++c: a + b+++ };\n}[!NOTE] Take care not to introduce waterfalls when using `await parent()`. If you can `fetch` other data that is not dependent on parent data, do that first.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","Invalidation"],"href":"/tutorial/kit/invalidation","content":"When the user navigates from one page to another, SvelteKit calls your load functions, but only if it thinks something has changed.In this example, navigating between timezones causes the load function in src/routes/[...timezone]/+page.js to re-run because params.timezone is invalid. But the load function in src/routes/+layout.js does not re-run, because as far as SvelteKit is concerned it wasn't invalidated by the navigation.We can fix that by manually invalidating it using the `invalidate(...)` function, which takes a URL and re-runs any load functions that depend on it. Because the load function in src/routes/+layout.js calls fetch('/api/now'), it depends on /api/now.In src/routes/[...timezone]/+page.svelte, add an onMount callback that calls invalidate('/api/now') once a second: \n<script>\n\t+++import { onMount } from 'svelte';+++\n\t+++import { invalidate } from '$app/navigation';+++\n\n\tlet { data } = $props();\n\n+++\tonMount(() => {\n\t\tconst interval = setInterval(() => {\n\t\t\tinvalidate('/api/now');\n\t\t}, 1000);\n\n\t\treturn () => {\n\t\t\tclearInterval(interval);\n\t\t};\n\t});+++\n</script>\n\n<h1>\n\t{new Intl.DateTimeFormat([], {\n\t\ttimeStyle: 'full',\n\t\ttimeZone: data.timezone\n\t}).format(new Date(data.now))}\n</h1>[!NOTE] You can also pass a function to `invalidate`, in case you want to invalidate based on a pattern and not specific URLs","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","Custom dependencies"],"href":"/tutorial/kit/custom-dependencies","content":"Calling fetch(url) inside a load function registers url as a dependency. Sometimes it's not appropriate to use fetch, in which case you can specify a dependency manually with the `depends(url)` function.Since any string that begins with an [a-z]+: pattern is a valid URL, we can create custom invalidation keys like data:now.Update src/routes/+layout.js to return a value directly rather than making a fetch call, and add the depends: \nexport async function load({ +++depends+++ }) {\n\t+++depends('data:now');+++\n\n\treturn {\n\t\tnow: +++Date.now()+++\n\t};\n}Now, update the invalidate call in src/routes/[...timezone]/+page.svelte: \n<script>\n\timport { onMount } from 'svelte';\n\timport { invalidate } from '$app/navigation';\n\n\tlet { data } = $props();\n\n\tonMount(() => {\n\t\tconst interval = setInterval(() => {\n\t\t\tinvalidate(+++'data:now'+++);\n\t\t}, 1000);\n\n\t\treturn () => {\n\t\t\tclearInterval(interval);\n\t\t};\n\t});\n</script>","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Advanced loading","invalidateAll"],"href":"/tutorial/kit/invalidate-all","content":"Finally, there's the nuclear option — invalidateAll(). This will indiscriminately re-run all load functions for the current page, regardless of what they depend on.Update src/routes/[...timezone]/+page.svelte from the previous exercise: \n<script>\n\timport { onMount } from 'svelte';\n\timport { +++invalidateAll+++ } from '$app/navigation';\n\n\tlet { data } = $props();\n\n\tonMount(() => {\n\t\tconst interval = setInterval(() => {\n\t\t\t+++invalidateAll();+++\n\t\t}, 1000);\n\n\t\treturn () => {\n\t\t\tclearInterval(interval);\n\t\t};\n\t});\n</script>The depends call in src/routes/+layout.js is no longer necessary: \nexport async function load(---{ depends }---) {\n\t---depends('data:now');---\n\n\treturn {\n\t\tnow: Date.now()\n\t};\n}[!NOTE] `invalidate(() => true)` and `invalidateAll` are _not_ the same. `invalidateAll` also re-runs `load` functions without any `url` dependencies, which `invalidate(() => true)` does not.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/static/private"],"href":"/tutorial/kit/env-static-private","content":"Environment variables — like API keys and database credentials — can be added to a .env file, and they will be made available to your application.[!NOTE] You can also use `.env.local` or `.env.[mode]` files — see the [Vite documentation](https://vitejs.dev/guide/env-and-mode.html#env-files) for more information. Make sure you add any files containing sensitive information to your `.gitignore` file!\n\nEnvironment variables in `process.env` are also available via `$env/static/private`.In this exercise, we want to allow the user to enter the website if they know the correct passphrase, using an environment variable.First, in .env, add a new environment variable: \nPASSPHRASE=+++\"open sesame\"+++Open src/routes/+page.server.js. Import PASSPHRASE from $env/static/private and use it inside the form action: \nimport { redirect, fail } from '@sveltejs/kit';\n+++import { PASSPHRASE } from '$env/static/private';+++\n\nexport function load({ cookies }) {\n\tif (cookies.get('allowed')) {\n\t\tredirect(307, '/welcome');\n\t}\n}\n\nexport const actions = {\n\tdefault: async ({ request, cookies }) => {\n\t\tconst data = await request.formData();\n\n\t\tif (data.get('passphrase') === +++PASSPHRASE+++) {\n\t\t\tcookies.set('allowed', 'true', {\n\t\t\t\tpath: '/'\n\t\t\t});\n\n\t\t\tredirect(303, '/welcome');\n\t\t}\n\n\t\treturn fail(403, {\n\t\t\tincorrect: true\n\t\t});\n\t}\n};The website is now accessible to anyone who knows the correct passphrase.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/static/private","Keeping secrets"],"href":"/tutorial/kit/env-static-private#Keeping-secrets","content":"It's important that sensitive data doesn't accidentally end up being sent to the browser, where it could easily be stolen by hackers and scoundrels.SvelteKit makes it easy to prevent this from happening. Notice what happens if we try to import PASSPHRASE into src/routes/+page.svelte: \n<script>\n\t+++import { PASSPHRASE } from '$env/static/private';+++\n\tlet { form } = $props();\n</script>An error overlay pops up, telling us that $env/static/private cannot be imported into client-side code. It can only be imported into server modules:`+page.server.js`\n`+layout.server.js`\n`+server.js`\nany modules ending with `.server.js`\nany modules inside `src/lib/server`In turn, these modules can only be imported by other server modules.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/static/private","Static vs dynamic"],"href":"/tutorial/kit/env-static-private#Static-vs-dynamic","content":"The static in $env/static/private indicates that these values are known at build time, and can be statically replaced. This enables useful optimisations:import { FEATURE_FLAG_X } from '$env/static/private';\n\nif (FEATURE_FLAG_X === 'enabled') {\n\t// code in here will be removed from the build output\n\t// if FEATURE_FLAG_X is not enabled\n}In some cases you might need to refer to environment variables that are dynamic — in other words, not known until we run the app. We'll cover this case in the next exercise.","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/dynamic/private"],"href":"/tutorial/kit/env-dynamic-private","content":"If you need to read the values of environment variables when the app runs, as opposed to when the app is built, you can use $env/dynamic/private instead of $env/static/private: \nimport { redirect, fail } from '@sveltejs/kit';\nimport { +++env+++ } from '$env/+++dynamic+++/private';\n\nexport function load({ cookies }) {\n\tif (cookies.get('allowed')) {\n\t\tredirect(307, '/welcome');\n\t}\n}\n\nexport const actions = {\n\tdefault: async ({ request, cookies }) => {\n\t\tconst data = await request.formData();\n\n\t\tif (data.get('passphrase') === +++env.+++PASSPHRASE) {\n\t\t\tcookies.set('allowed', 'true', {\n\t\t\t\tpath: '/'\n\t\t\t});\n\n\t\t\tredirect(303, '/welcome');\n\t\t}\n\n\t\treturn fail(403, {\n\t\t\tincorrect: true\n\t\t});\n\t}\n};","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/static/public"],"href":"/tutorial/kit/env-static-public","content":"Some environment variables can be safely exposed to the browser. These are distinguished from private environment variables with a PUBLIC_ prefix.Add values to the two public environment variables in .env: \nPUBLIC_THEME_BACKGROUND=+++\"steelblue\"+++\nPUBLIC_THEME_FOREGROUND=+++\"bisque\"+++Then, import them into src/routes/+page.svelte: \n<script>\n---\tconst PUBLIC_THEME_BACKGROUND = 'white';\n\tconst PUBLIC_THEME_FOREGROUND = 'black';---\n+++\timport {\n\t\tPUBLIC_THEME_BACKGROUND,\n\t\tPUBLIC_THEME_FOREGROUND\n\t} from '$env/static/public';+++\n</script>","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Environment variables","$env/dynamic/public"],"href":"/tutorial/kit/env-dynamic-public","content":"As with private environment variables, it's preferable to use static values if possible, but if necessary we can use dynamic values instead: \n<script>\n\timport { +++env+++ } from '$env/+++dynamic+++/public';\n</script>\n\n<main\n\tstyle:background={+++env.+++PUBLIC_THEME_BACKGROUND}\n\tstyle:color={+++env.+++PUBLIC_THEME_FOREGROUND}\n>\n\t{+++env.+++PUBLIC_THEME_FOREGROUND} on {+++env.+++PUBLIC_THEME_BACKGROUND}\n</main>","rank":null},{"breadcrumbs":["Tutorial","Advanced SvelteKit","Conclusion","Next steps"],"href":"/tutorial/kit/next-steps","content":"Congratulations! If you've made it the entire way through this tutorial, you can now consider yourself a Svelte and SvelteKit expert.You can start building apps on your own machine with Svelte CLI:npx sv createSvelte and SvelteKit will continue to evolve, and so will this tutorial. Check back periodically for updates.To keep up with developments in the Svelte world, join our Discord server at svelte.dev/chat and follow Svelte Society on BlueSky. We're so happy to welcome you to the Svelte community!","rank":null},{"breadcrumbs":["Examples","Introduction","Hello world"],"href":"/playground/hello-world","content":"","rank":10},{"breadcrumbs":["Examples","Introduction","Dynamic attributes"],"href":"/playground/dynamic-attributes","content":"","rank":10},{"breadcrumbs":["Examples","Introduction","Styling"],"href":"/playground/styling","content":"","rank":10},{"breadcrumbs":["Examples","Introduction","Nested components"],"href":"/playground/nested-components","content":"","rank":10},{"breadcrumbs":["Examples","Introduction","HTML tags"],"href":"/playground/html-tags","content":"","rank":10},{"breadcrumbs":["Examples","Reactivity","Reactive assignments"],"href":"/playground/reactive-assignments","content":"","rank":10},{"breadcrumbs":["Examples","Reactivity","Reactive declarations"],"href":"/playground/reactive-declarations","content":"","rank":10},{"breadcrumbs":["Examples","Reactivity","Reactive statements"],"href":"/playground/reactive-statements","content":"","rank":10},{"breadcrumbs":["Examples","Props","Declaring props"],"href":"/playground/declaring-props","content":"","rank":10},{"breadcrumbs":["Examples","Props","Default values"],"href":"/playground/default-values","content":"","rank":10},{"breadcrumbs":["Examples","Props","Spread props"],"href":"/playground/spread-props","content":"","rank":10},{"breadcrumbs":["Examples","Logic","If blocks"],"href":"/playground/if-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Logic","Else blocks"],"href":"/playground/else-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Logic","Else-if blocks"],"href":"/playground/else-if-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Logic","Each blocks"],"href":"/playground/each-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Logic","Keyed each blocks"],"href":"/playground/keyed-each-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Logic","Await blocks"],"href":"/playground/await-blocks","content":"","rank":10},{"breadcrumbs":["Examples","Events","DOM events"],"href":"/playground/dom-events","content":"","rank":10},{"breadcrumbs":["Examples","Events","Inline handlers"],"href":"/playground/inline-handlers","content":"","rank":10},{"breadcrumbs":["Examples","Events","Component events"],"href":"/playground/component-events","content":"","rank":10},{"breadcrumbs":["Examples","Events","Event forwarding"],"href":"/playground/event-forwarding","content":"","rank":10},{"breadcrumbs":["Examples","Events","DOM event forwarding"],"href":"/playground/dom-event-forwarding","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Text inputs"],"href":"/playground/text-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Numeric inputs"],"href":"/playground/numeric-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Checkbox inputs"],"href":"/playground/checkbox-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Group inputs"],"href":"/playground/group-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Textarea inputs"],"href":"/playground/textarea-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","File inputs"],"href":"/playground/file-inputs","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Select bindings"],"href":"/playground/select-bindings","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Select multiple"],"href":"/playground/multiple-select-bindings","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Each block bindings"],"href":"/playground/each-block-bindings","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Media elements"],"href":"/playground/media-elements","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Dimensions"],"href":"/playground/dimensions","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","bind:this={canvas}"],"href":"/playground/bind-this","content":"","rank":10},{"breadcrumbs":["Examples","Bindings","Component bindings"],"href":"/playground/component-bindings","content":"","rank":10},{"breadcrumbs":["Examples","Lifecycle","onMount"],"href":"/playground/onmount","content":"","rank":10},{"breadcrumbs":["Examples","Lifecycle","onDestroy"],"href":"/playground/ondestroy","content":"","rank":10},{"breadcrumbs":["Examples","Lifecycle","tick"],"href":"/playground/tick","content":"","rank":10},{"breadcrumbs":["Examples","Stores","Writable stores"],"href":"/playground/writable-stores","content":"","rank":10},{"breadcrumbs":["Examples","Stores","Auto-subscriptions"],"href":"/playground/auto-subscriptions","content":"","rank":10},{"breadcrumbs":["Examples","Stores","Readable stores"],"href":"/playground/readable-stores","content":"","rank":10},{"breadcrumbs":["Examples","Stores","Derived stores"],"href":"/playground/derived-stores","content":"","rank":10},{"breadcrumbs":["Examples","Stores","Custom stores"],"href":"/playground/custom-stores","content":"","rank":10},{"breadcrumbs":["Examples","Motion","Tweened"],"href":"/playground/tweened","content":"","rank":10},{"breadcrumbs":["Examples","Motion","Spring"],"href":"/playground/spring","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","The transition directive"],"href":"/playground/transition","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","Adding parameters"],"href":"/playground/adding-parameters-to-transitions","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","In and out"],"href":"/playground/in-and-out","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","Custom CSS transitions"],"href":"/playground/custom-css-transitions","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","Custom JS transitions"],"href":"/playground/custom-js-transitions","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","Transition events"],"href":"/playground/transition-events","content":"","rank":10},{"breadcrumbs":["Examples","Transitions","Deferred transitions"],"href":"/playground/deferred-transitions","content":"","rank":10},{"breadcrumbs":["Examples","Animations","The animate directive"],"href":"/playground/animate","content":"","rank":10},{"breadcrumbs":["Examples","Easing","Ease Visualiser"],"href":"/playground/easing","content":"","rank":10},{"breadcrumbs":["Examples","SVG","Clock"],"href":"/playground/clock","content":"","rank":10},{"breadcrumbs":["Examples","SVG","Bar chart"],"href":"/playground/bar-chart","content":"","rank":10},{"breadcrumbs":["Examples","SVG","Area chart"],"href":"/playground/area-chart","content":"","rank":10},{"breadcrumbs":["Examples","SVG","Scatterplot"],"href":"/playground/scatterplot","content":"","rank":10},{"breadcrumbs":["Examples","SVG","SVG transitions"],"href":"/playground/svg-transitions","content":"","rank":10},{"breadcrumbs":["Examples","Actions","The use directive"],"href":"/playground/actions","content":"","rank":10},{"breadcrumbs":["Examples","Actions","Adding parameters"],"href":"/playground/adding-parameters-to-actions","content":"","rank":10},{"breadcrumbs":["Examples","Actions","A more complex action"],"href":"/playground/actions-pannable","content":"","rank":10},{"breadcrumbs":["Examples","Classes","The class directive"],"href":"/playground/classes","content":"","rank":10},{"breadcrumbs":["Examples","Classes","Shorthand class directive"],"href":"/playground/class-shorthand","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Render props"],"href":"/playground/render-props","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Render prop fallbacks"],"href":"/playground/render-prop-fallbacks","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Named render props"],"href":"/playground/named-render-props","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Render prop props"],"href":"/playground/render-prop-props","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Conditional render props"],"href":"/playground/conditional-render-props","content":"","rank":10},{"breadcrumbs":["Examples","Component composition","Modal"],"href":"/playground/modal","content":"","rank":10},{"breadcrumbs":["Examples","Context API","setContext and getContext"],"href":"/playground/context-api","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:element>"],"href":"/playground/svelte-element","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:window>"],"href":"/playground/svelte-window","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:window> bindings"],"href":"/playground/svelte-window-bindings","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:document>"],"href":"/playground/svelte-document","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:body>"],"href":"/playground/svelte-body","content":"","rank":10},{"breadcrumbs":["Examples","Special elements","<svelte:head>"],"href":"/playground/svelte-head","content":"","rank":10},{"breadcrumbs":["Examples","Module context","Named exports"],"href":"/playground/module-exports","content":"","rank":10},{"breadcrumbs":["Examples","Debugging","The @debug tag"],"href":"/playground/debug","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","Counter"],"href":"/playground/7guis-counter","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","Temperature Converter"],"href":"/playground/7guis-temperature","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","Flight booker"],"href":"/playground/7guis-flight-booker","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","Timer"],"href":"/playground/7guis-timer","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","CRUD"],"href":"/playground/7guis-crud","content":"","rank":10},{"breadcrumbs":["Examples","7GUIs","Circle Drawer"],"href":"/playground/7guis-circles","content":"","rank":10},{"breadcrumbs":["Examples","Miscellaneous","Recursive components"],"href":"/playground/recursive-components","content":"","rank":10},{"breadcrumbs":["Examples","Miscellaneous","Dynamic components"],"href":"/playground/dynamic-components","content":"","rank":10},{"breadcrumbs":["Examples","Miscellaneous","Hacker News"],"href":"/playground/hacker-news","content":"","rank":10}]}