-
Notifications
You must be signed in to change notification settings - Fork 0
/
skit.json
1 lines (1 loc) · 354 KB
/
skit.json
1
{"blocks":[{"breadcrumbs":["Introduction"],"href":"/docs/introduction","content":""},{"breadcrumbs":["Introduction","Before we begin"],"href":"/docs/introduction#before-we-begin","content":"If you're new to Svelte or SvelteKit we recommend checking out the interactive tutorial.\n\nIf you get stuck, reach out for help in the Discord chatroom."},{"breadcrumbs":["Introduction","What is SvelteKit?"],"href":"/docs/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.\n\nTo learn more about the kinds of applications you can build with SvelteKit, see the FAQ."},{"breadcrumbs":["Introduction","What is Svelte?"],"href":"/docs/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."},{"breadcrumbs":["Introduction","SvelteKit vs Svelte"],"href":"/docs/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.\n\nSvelteKit 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.\n\nIt 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)."},{"breadcrumbs":["Creating a project"],"href":"/docs/creating-a-project","content":"The easiest way to start building a SvelteKit app is to run npm create:\n\nnpm create svelte@latest my-app\ncd my-app\nnpm install\nnpm run devThe first command will scaffold a new project in the my-app directory asking you if you'd like to set up some basic tooling such as TypeScript. See integrations for pointers on setting up additional tooling. The subsequent commands will then install its dependencies and start a server on localhost:5173.\n\nThere are two basic concepts:\n\nEach page of your app is a 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 over\n\nTry editing the files to get a feel for how everything works."},{"breadcrumbs":["Creating a project","Editor setup"],"href":"/docs/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."},{"breadcrumbs":["Project structure"],"href":"/docs/project-structure","content":"A typical SvelteKit project looks like this:\n\nmy-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├ 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 npm create svelte@latest)."},{"breadcrumbs":["Project structure","Project files"],"href":"/docs/project-structure#project-files","content":""},{"breadcrumbs":["Project structure","Project files","src"],"href":"/docs/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.\n\nlib contains your library code (utilities and components), which can be imported via the $lib alias, or packaged up for distribution using svelte-packageserver contains your server-only library code. It can be imported by using the $lib/server alias. SvelteKit will prevent you from importing these in client code.\n\n\nparams contains any param matchers your app needs\nroutes contains the routes of your application. You can also colocate other components that are only used within a single route here\napp.html is your page template — an HTML document containing the following placeholders:%sveltekit.head% — <link> and <script> elements needed by the app, plus any <svelte:head> content\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, if specified, or a relative path to paths.base\n%sveltekit.nonce% — a 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 (usually PUBLIC_). It will fallback to '' if not matched.\n\n\nerror.html is the page that is rendered when everything else fails. It can contain the following placeholders:%sveltekit.status% — the HTTP status\n%sveltekit.error.message% — the error message\n\n\nhooks.client.js contains your client hooks\nhooks.server.js contains your server hooks\nservice-worker.js contains your service worker\n\n(Whether the project contains .js or .ts files depends on whether you opt to use TypeScript when you create your project. You can switch between JavaScript and TypeScript in the documentation using the toggle at the bottom of this page.)\n\nIf you added Vitest when you set up your project, your unit tests will live in the src directory with a .test.js extension."},{"breadcrumbs":["Project structure","Project files","static"],"href":"/docs/project-structure#project-files-static","content":"Any static assets that should be served as-is, like robots.txt or favicon.png, go in here."},{"breadcrumbs":["Project structure","Project files","tests"],"href":"/docs/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."},{"breadcrumbs":["Project structure","Project files","package.json"],"href":"/docs/project-structure#project-files-package-json","content":"Your package.json file must include @sveltejs/kit, svelte and vite as devDependencies.\n\nWhen you create a project with npm create svelte@latest, 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."},{"breadcrumbs":["Project structure","Project files","svelte.config.js"],"href":"/docs/project-structure#project-files-svelte-config-js","content":"This file contains your Svelte and SvelteKit configuration."},{"breadcrumbs":["Project structure","Project files","tsconfig.json"],"href":"/docs/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 npm create svelte@latest. 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."},{"breadcrumbs":["Project structure","Project files","vite.config.js"],"href":"/docs/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."},{"breadcrumbs":["Project structure","Other files"],"href":"/docs/project-structure#other-files","content":""},{"breadcrumbs":["Project structure","Other files",".svelte-kit"],"href":"/docs/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)."},{"breadcrumbs":["Web standards"],"href":"/docs/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.\n\nThese 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).\n\nIn particular, you'll get comfortable with the following:"},{"breadcrumbs":["Web standards","Fetch APIs"],"href":"/docs/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.\n\nA special version of fetch is available in load functions, server hooks and API routes 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.\n\n\nBesides fetch itself, the Fetch API includes the following interfaces:"},{"breadcrumbs":["Web standards","Fetch APIs","Request"],"href":"/docs/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."},{"breadcrumbs":["Web standards","Fetch APIs","Response"],"href":"/docs/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."},{"breadcrumbs":["Web standards","Fetch APIs","Headers"],"href":"/docs/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:"},{"breadcrumbs":["Web standards","FormData"],"href":"/docs/web-standards#formdata","content":"When dealing with HTML native form submissions you'll be working with FormData objects."},{"breadcrumbs":["Web standards","Stream APIs"],"href":"/docs/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."},{"breadcrumbs":["Web standards","URL APIs"],"href":"/docs/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."},{"breadcrumbs":["Web standards","URL APIs","URLSearchParams"],"href":"/docs/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:\n\nconst foo = url.searchParams.get('foo');"},{"breadcrumbs":["Web standards","Web Crypto"],"href":"/docs/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:\n\nconst uuid = crypto.randomUUID();"},{"breadcrumbs":["Routing"],"href":"/docs/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:\n\nsrc/routes is the root route\nsrc/routes/about creates an /about route\nsrc/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\n\nYou can change src/routes to a different directory by editing the project config.\n\n\nEach route directory contains one or more route files, which can be identified by their + prefix.\n\nWe'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:\n\nAll 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"},{"breadcrumbs":["Routing","+page"],"href":"/docs/routing#page","content":""},{"breadcrumbs":["Routing","+page","+page.svelte"],"href":"/docs/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.\n\n<!--- 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><!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n</script>\n\n<h1>{data.title}</h1>\n<div>{@html data.content}</div>Note that SvelteKit uses <a> elements to navigate between routes, rather than a framework-specific <Link> component."},{"breadcrumbs":["Routing","+page","+page.js"],"href":"/docs/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:\n\nThis 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.\n\nAs well as load, +page.js can export values that configure the page's behaviour:\n\nexport const prerender = true or false or 'auto'\nexport const ssr = true or false\nexport const csr = true or false\n\nYou can find more information about these in page options."},{"breadcrumbs":["Routing","+page","+page.server.js"],"href":"/docs/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.\n\nimport { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n const post = await getPostFromDatabase(params.slug);\n\n if (post) {\n return post;\n }\n\n error(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.\n\nLike +page.js, +page.server.js can export page options — prerender, ssr and csr.\n\nA +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."},{"breadcrumbs":["Routing","+error"],"href":"/docs/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:\n\n<!--- file: src/routes/blog/[slug]/+error.svelte --->\n<script>\n import { page } from '$app/stores';\n</script>\n\n<h1>{$page.status}: {$page.error.message}</h1>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.\n\nIf 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).\n\nIf no route can be found (404), src/routes/+error.svelte (or the default error page, if that file does not exist) will be used.\n\n+error.svelte is not used when an error occurs inside handle or a +server.js request handler.\n\n\nYou can read more about error handling here."},{"breadcrumbs":["Routing","+layout"],"href":"/docs/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.\n\nBut 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."},{"breadcrumbs":["Routing","+layout","+layout.svelte"],"href":"/docs/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...\n\n<slot></slot>...but we can add whatever markup, styles and behaviour we want. The only requirement is that the component includes a <slot> for the page content. For example, let's add a nav bar:\n\nIf we create pages for /, /about and /settings...\n\n...the nav will always be visible, and clicking between the three pages will only result in the <h1> being replaced.\n\nLayouts 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).\n\nWe can create a layout that only applies to pages below /settings (while inheriting the root layout with the top-level nav):\n\n<!--- file: src/routes/settings/+layout.svelte --->\n<script>\n /** @type {import('./$types').LayoutData} */\n export let data;\n</script>\n\n<h1>Settings</h1>\n\n<div class=\"submenu\">\n {#each data.sections as section}\n <a href=\"/settings/{section.slug}\">{section.title}</a>\n {/each}\n</div>\n\n<slot></slot>You can see how data is populated by looking at the +layout.js example in the next section just below.\n\nBy default, each layout inherits the layout above it. Sometimes that isn't what you want - in this case, advanced layouts can help you."},{"breadcrumbs":["Routing","+layout","+layout.js"],"href":"/docs/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\nIf a +layout.js exports page options — prerender, ssr and csr — they will be used as defaults for child pages.\n\nData returned from a layout's load function is also available to all its child pages:\n\n<!--- file: src/routes/settings/profile/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n\n console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]\n</script>Often, layout data is unchanged when navigating between pages. SvelteKit will intelligently rerun load functions when necessary."},{"breadcrumbs":["Routing","+layout","+layout.server.js"],"href":"/docs/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.\n\nLike +layout.js, +layout.server.js can export page options — prerender, ssr and csr."},{"breadcrumbs":["Routing","+server"],"href":"/docs/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.\n\nFor example we could create an /api/random-number route with a GET handler:\n\nThe 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).\n\nYou can use the error, redirect and json methods from @sveltejs/kit for convenience (but you don't have to).\n\nIf 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.\n\nWhen 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."},{"breadcrumbs":["Routing","+server","Receiving data"],"href":"/docs/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:\n\n<!--- file: src/routes/add/+page.svelte --->\n<script>\n let a = 0;\n let b = 0;\n let total = 0;\n\n async function add() {\n const response = await fetch('/api/add', {\n method: 'POST',\n body: JSON.stringify({ a, b }),\n headers: {\n 'content-type': 'application/json'\n }\n });\n\n total = await response.json();\n }\n</script>\n\n<input type=\"number\" bind:value={a}> +\n<input type=\"number\" bind:value={b}> =\n{total}\n\n<button on:click={add}>Calculate</button>In general, form actions are a better way to submit data from the browser to the server.\n\n\nIf a GET handler is exported, a HEAD request will return the content-length of the GET handler's response body."},{"breadcrumbs":["Routing","+server","Fallback method handler"],"href":"/docs/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.\n\nFor HEAD requests, the GET handler takes precedence over the fallback handler."},{"breadcrumbs":["Routing","+server","Content negotiation"],"href":"/docs/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:\n\nPUT/PATCH/DELETE/OPTIONS requests are always handled by +server.js since they do not apply to pages\nGET/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."},{"breadcrumbs":["Routing","$types"],"href":"/docs/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.\n\nFor example, annotating export let data with PageData (or LayoutData, for a +layout.svelte file) tells TypeScript that the type of data is whatever was returned from load:\n\n<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n</script>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.\n\nIf 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.\n\nYou can read more about omitting $types in our blog post about it."},{"breadcrumbs":["Routing","Other files"],"href":"/docs/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.\n\nIf components and modules are needed by multiple routes, it's a good idea to put them in $lib."},{"breadcrumbs":["Routing","Further reading"],"href":"/docs/routing#further-reading","content":"Tutorial: Routing\nTutorial: API routes\nDocs: Advanced routing"},{"breadcrumbs":["Loading data"],"href":"/docs/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."},{"breadcrumbs":["Loading data","Page data"],"href":"/docs/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\n<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n</script>\n\n<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>Thanks to the generated $types module, we get full type safety.\n\nA 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.\n\nA 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:\n\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n return {\n post: await db.getPost(params.slug)\n };\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."},{"breadcrumbs":["Loading data","Layout data"],"href":"/docs/load#layout-data","content":"Your +layout.svelte files can also load data, via +layout.js or +layout.server.js.\n\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load() {\n return {\n posts: await db.getPostSummaries()\n };\n}<!--- file: src/routes/blog/[slug]/+layout.svelte --->\n<script>\n /** @type {import('./$types').LayoutData} */\n export let data;\n</script>\n\n<main>\n <!-- +page.svelte is rendered in this <slot> -->\n <slot />\n</main>\n\n<aside>\n <h2>More posts</h2>\n <ul>\n {#each data.posts as post}\n <li>\n <a href=\"/blog/{post.slug}\">\n {post.title}\n </a>\n </li>\n {/each}\n </ul>\n</aside>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\nIf 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 }."},{"breadcrumbs":["Loading data","$page.data"],"href":"/docs/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.\n\nIn 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:\n\n<!--- file: src/routes/+layout.svelte --->\n<script>\n import { page } from '$app/stores';\n</script>\n\n<svelte:head>\n <title>{$page.data.title}</title>\n</svelte:head>Type information for $page.data is provided by App.PageData."},{"breadcrumbs":["Loading data","Universal vs server"],"href":"/docs/load#universal-vs-server","content":"As we've seen, there are two types of load function:\n\n+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-side\n\nConceptually, they're the same thing, but there are some important differences to be aware of."},{"breadcrumbs":["Loading data","Universal vs server","When does which load function run?"],"href":"/docs/load#universal-vs-server-when-does-which-load-function-run","content":"Server load functions always run on the server.\n\nBy 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.\n\nIf a route contains both universal and server load functions, the server load runs first.\n\nA load function is invoked at runtime, unless you prerender the page — in that case, it's invoked at build time."},{"breadcrumbs":["Loading data","Universal vs server","Input"],"href":"/docs/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.\n\nServer load functions are called with a ServerLoadEvent, which inherits clientAddress, cookies, locals, platform and request from RequestEvent.\n\nUniversal 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."},{"breadcrumbs":["Loading data","Universal vs server","Output"],"href":"/docs/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.\n\nA 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."},{"breadcrumbs":["Loading data","Universal vs server","When to use which"],"href":"/docs/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.\n\nUniversal 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.\n\nIn 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):"},{"breadcrumbs":["Loading data","Using URL data"],"href":"/docs/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."},{"breadcrumbs":["Loading data","Using URL data","url"],"href":"/docs/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.\n\nIn some environments this is derived from request headers during server-side rendering. If you're using adapter-node, for example, you may need to configure the adapter in order for the URL to be correct."},{"breadcrumbs":["Loading data","Using URL data","route"],"href":"/docs/load#using-url-data-route","content":"Contains the name of the current route directory, relative to src/routes:"},{"breadcrumbs":["Loading data","Using URL data","params"],"href":"/docs/load#using-url-data-params","content":"params is derived from url.pathname and route.id.\n\nGiven a route.id of /a/[b]/[...c] and a url.pathname of /a/x/y/z, the params object would look like this:\n\n{\n \"b\": \"x\",\n \"c\": \"y/z\"\n}"},{"breadcrumbs":["Loading data","Making fetch requests"],"href":"/docs/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:\n\nIt 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.\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."},{"breadcrumbs":["Loading data","Cookies"],"href":"/docs/load#cookies","content":"A server load function can get and set cookies.\n\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load({ cookies }) {\n const sessionid = cookies.get('sessionid');\n\n return {\n user: await db.getUser(sessionid)\n };\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.\n\nFor example, if SvelteKit is serving my.domain.com:\n\ndomain.com WILL NOT receive cookies\nmy.domain.com WILL receive cookies\napi.domain.com WILL NOT receive cookies\nsub.my.domain.com WILL receive cookies\n\nOther 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."},{"breadcrumbs":["Loading data","Headers"],"href":"/docs/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\nSetting 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 cookies.set(name, value, options) instead."},{"breadcrumbs":["Loading data","Using parent data"],"href":"/docs/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\n<!--- file: src/routes/abc/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n</script>\n\n<!-- renders `1 + 2 = 3` -->\n<p>{data.a} + {data.b} = {data.c}</p>Notice that the load function in +page.js receives the merged data from both layout load functions, not just the immediate parent.\n\n\nInside +page.server.js and +layout.server.js, parent returns data from parent +layout.server.js files.\n\nIn +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 file\n\nTake 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."},{"breadcrumbs":["Loading data","Errors"],"href":"/docs/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:\n\nimport { error } from '@sveltejs/kit';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport function load({ locals }) {\n if (!locals.user) {\n error(401, 'not logged in');\n }\n\n if (!locals.user.isAdmin) {\n error(403, 'not an admin');\n }\n}Calling error(...) will throw an exception, making it easy to stop execution from inside helper functions.\n\nIf an unexpected error is thrown, SvelteKit will invoke handleError and treat it as a 500 Internal Error.\n\nIn SvelteKit 1.x you had to throw the error yourself"},{"breadcrumbs":["Loading data","Redirects"],"href":"/docs/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.\n\nimport { redirect } from '@sveltejs/kit';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport function load({ locals }) {\n if (!locals.user) {\n redirect(307, '/login');\n }\n}Don't use redirect() inside a try {...} block, as the redirect will immediately trigger the catch statement.\n\n\nIn the browser, you can also navigate programmatically outside of a load function using goto from $app.navigation.\n\nIn SvelteKit 1.x you had to throw the redirect yourself"},{"breadcrumbs":["Loading data","Streaming with promises"],"href":"/docs/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:\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n return {\n // make sure the `await` happens at the end, otherwise we\n // can't start loading comments until we've loaded the post\n comments: loadComments(params.slug),\n post: await loadPost(params.slug)\n };\n}This is useful for creating skeleton loading states, for example:\n\n<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n</script>\n\n<h1>{data.post.title}</h1>\n<div>{@html data.post.content}</div>\n\n{#await data.comments}\n Loading comments...\n{:then comments}\n {#each comments as comment}\n <p>{comment.content}</p>\n {/each}\n{:catch error}\n <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\nOn 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.\n\n\nStreaming 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.\n\n\nThe 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.\n\n\nIn SvelteKit 1.x top-level promises were automatically awaited, only nested promises were streamed."},{"breadcrumbs":["Loading data","Parallel loading"],"href":"/docs/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."},{"breadcrumbs":["Loading data","Rerunning load functions"],"href":"/docs/load#rerunning-load-functions","content":"SvelteKit tracks the dependencies of each load function to avoid rerunning it unnecessarily during navigation.\n\nFor example, given a pair of load functions like these...\n\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n return {\n post: await db.getPost(params.slug)\n };\n}import * as db from '$lib/server/database';\n\n/** @type {import('./$types').LayoutServerLoad} */\nexport async function load() {\n return {\n posts: await db.getPostSummaries()\n };\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.\n\nA load function that calls await parent() will also rerun if a parent load function is rerun.\n\nDependency 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.\n\nSearch 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."},{"breadcrumbs":["Loading data","Rerunning load functions","Untracking dependencies"],"href":"/docs/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:"},{"breadcrumbs":["Loading data","Rerunning load functions","Manual invalidation"],"href":"/docs/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.\n\nA 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\n<!--- file: src/routes/random-number/+page.svelte --->\n<script>\n import { invalidate, invalidateAll } from '$app/navigation';\n\n /** @type {import('./$types').PageData} */\n export let data;\n\n function rerunLoadFunction() {\n // any of these will cause the `load` function to rerun\n invalidate('app:random');\n invalidate('https://api.example.com/random-number');\n invalidate(url => url.href.includes('random-number'));\n invalidateAll();\n }\n</script>\n\n<p>random number: {data.number}</p>\n<button on:click={rerunLoadFunction}>Update random number</button>"},{"breadcrumbs":["Loading data","Rerunning load functions","When do load functions rerun?"],"href":"/docs/load#rerunning-load-functions-when-do-load-functions-rerun","content":"To summarize, a load function will rerun in the following situations:\n\nIt 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\nIt declared a dependency on a specific URL via fetch (universal load only) or depends, and that URL was marked invalid with invalidate(url)\nAll active load functions were forcibly rerun with invalidateAll()\n\nparams and url can change in response to a <a href=".."> link click, a <form> interaction, a goto invocation, or a redirect.\n\nNote 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."},{"breadcrumbs":["Loading data","Implications for authentication"],"href":"/docs/load#implications-for-authentication","content":"A couple features of loading data have important implications for auth checks:\n\nLayout load functions do not run on every request, such as during client side navigation between child routes. (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.\n\nThere are a few possible strategies to ensure an auth check occurs before protected code.\n\nTo prevent data waterfalls and preserve layout load caches:\n\nUse hooks to protect multiple routes before any load functions run\nUse auth guards directly in +page.server.js load functions for route specific protection\n\nPutting 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."},{"breadcrumbs":["Loading data","Further reading"],"href":"/docs/load#further-reading","content":"Tutorial: Loading data\nTutorial: Errors and redirects\nTutorial: Advanced loading"},{"breadcrumbs":["Form actions"],"href":"/docs/form-actions","content":"A +page.server.js file can export actions, which allow you to POST data to the server using the <form> element.\n\nWhen using <form>, client-side JavaScript is optional, but you can easily progressively enhance your form interactions with JavaScript to provide the best user experience."},{"breadcrumbs":["Form actions","Default actions"],"href":"/docs/form-actions#default-actions","content":"In the simplest case, a page declares a default action:\n\nTo invoke this action from the /login page, just add a <form> — no JavaScript needed:\n\n<!--- file: src/routes/login/+page.svelte --->\n<form method=\"POST\">\n <label>\n Email\n <input name=\"email\" type=\"email\">\n </label>\n <label>\n Password\n <input name=\"password\" type=\"password\">\n </label>\n <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.\n\nActions always use POST requests, since GET requests should never have side-effects.\n\n\nWe 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:"},{"breadcrumbs":["Form actions","Named actions"],"href":"/docs/form-actions#named-actions","content":"Instead of one default action, a page can have as many named actions as it needs:\n\nTo invoke a named action, add a query parameter with the name prefixed by a / character:\n\n<!--- 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\nWe 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."},{"breadcrumbs":["Form actions","Anatomy of an action"],"href":"/docs/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.\n\n<!--- file: src/routes/login/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n\n /** @type {import('./$types').ActionData} */\n export let form;\n</script>\n\n{#if form?.success}\n <!-- this message is ephemeral; it exists because the page was rendered in\n response to a form submission. it will vanish if the user reloads -->\n <p>Successfully logged in! Welcome back, {data.user.name}</p>\n{/if}"},{"breadcrumbs":["Form actions","Anatomy of an action","Validation errors"],"href":"/docs/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:\n\nNote that as a precaution, we only return the email back to the page — not the password.\n\n\nThe 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."},{"breadcrumbs":["Form actions","Anatomy of an action","Redirects"],"href":"/docs/form-actions#anatomy-of-an-action-redirects","content":"Redirects (and errors) work exactly the same as in load:"},{"breadcrumbs":["Form actions","Loading data"],"href":"/docs/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.\n\nNote 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:\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n event.locals.user = await getUser(event.cookies.get('sessionid'));\n return resolve(event);\n}/** @type {import('./$types').PageServerLoad} */\nexport function load(event) {\n return {\n user: event.locals.user\n };\n}\n\n/** @type {import('./$types').Actions} */\nexport const actions = {\n logout: async (event) => {\n event.cookies.delete('sessionid', { path: '/' });\n event.locals.user = null;\n }\n};"},{"breadcrumbs":["Form actions","Progressive enhancement"],"href":"/docs/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."},{"breadcrumbs":["Form actions","Progressive enhancement","use:enhance"],"href":"/docs/form-actions#progressive-enhancement-use-enhance","content":"The easiest way to progressively enhance a form is to add the use:enhance action:\n\nYes, it's a little confusing that the enhance action and <form action> are both called 'action'. These docs are action-packed. Sorry.\n\n\nWithout an argument, use:enhance will emulate the browser-native behaviour, just without the full-page reloads. It will:\n\nupdate 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" ..>, form and $page 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\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\nreset focus to the appropriate element"},{"breadcrumbs":["Form actions","Progressive enhancement","Customising use:enhance"],"href":"/docs/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. Note that if you return a callback, the default behavior mentioned above is not triggered. To get it back, call update.\n\n<form\n method=\"POST\"\n use:enhance={({ formElement, formData, action, cancel, submitter }) => {\n // `formElement` is this `<form>` element\n // `formData` is its `FormData` object that's about to be submitted\n // `action` is the URL to which the form is posted\n // calling `cancel()` will prevent the submission\n // `submitter` is the `HTMLElement` that caused the form to be submitted\n\n return async ({ result, update }) => {\n // `result` is an `ActionResult` object\n // `update` is a function which triggers the default logic that would be triggered if this callback wasn't set\n };\n }}\n>You can use these functions to show and hide loading UI, and so on.\n\nIf you return a callback, you may need to reproduce part of the default use:enhance behaviour, but without invalidating all data on a successful response. You can do so with applyAction:\n\nThe behaviour of applyAction(result) depends on result.type:\n\nsuccess, 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)\nredirect — calls goto(result.location, { invalidateAll: true })\nerror — renders the nearest +error boundary with result.error\n\nIn all cases, focus will be reset."},{"breadcrumbs":["Form actions","Progressive enhancement","Custom event listener"],"href":"/docs/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>:\n\n<!--- file: src/routes/login/+page.svelte --->\n<script>\n import { invalidateAll, goto } from '$app/navigation';\n import { applyAction, deserialize } from '$app/forms';\n\n /** @type {import('./$types').ActionData} */\n export let form;\n\n /** @type {any} */\n let error;\n\n /** @param {{ currentTarget: EventTarget & HTMLFormElement}} event */\n async function handleSubmit(event) {\n const data = new FormData(event.currentTarget);\n\n const response = await fetch(event.currentTarget.action, {\n method: 'POST',\n body: data\n });\n\n /** @type {import('@sveltejs/kit').ActionResult} */\n const result = deserialize(await response.text());\n\n if (result.type === 'success') {\n // rerun all `load` functions, following the successful update\n await invalidateAll();\n }\n\n applyAction(result);\n }\n</script>\n\n<form method=\"POST\" on:submit|preventDefault={handleSubmit}>\n <!-- 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.\n\nIf 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:\n\nconst response = await fetch(this.action, {\n method: 'POST',\n body: data,\n+\theaders: {\n+\t\t'x-sveltekit-action': 'true'\n+\t}\n});"},{"breadcrumbs":["Form actions","Alternatives"],"href":"/docs/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:\n\n<!--- file: send-message/+page.svelte --->\n<script>\n function rerun() {\n fetch('/api/ci', {\n method: 'POST'\n });\n }\n</script>\n\n<button on:click={rerun}>Rerun CI</button>"},{"breadcrumbs":["Form actions","GET vs POST"],"href":"/docs/form-actions#get-vs-post","content":"As we've seen, to invoke a form action you must use method="POST".\n\nSome 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:\n\n<form action=\"/search\">\n <label>\n Search\n <input name=\"q\">\n </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."},{"breadcrumbs":["Form actions","Further reading"],"href":"/docs/form-actions#further-reading","content":"Tutorial: Forms"},{"breadcrumbs":["Page options"],"href":"/docs/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.\n\nYou 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.\n\nYou 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."},{"breadcrumbs":["Page options","prerender"],"href":"/docs/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.\n\nAlternatively, 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:\n\nRoutes 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':\n\nIf your entire app is suitable for prerendering, you can use adapter-static, which will output files suitable for use with any static webserver.\n\n\nThe 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.\n\nWhile prerendering, the value of building imported from $app/environment will be true."},{"breadcrumbs":["Page options","prerender","Prerendering server routes"],"href":"/docs/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...\n\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."},{"breadcrumbs":["Page options","prerender","When not to prerender"],"href":"/docs/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.\n\nNot 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.\n\n\nNote 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.\n\nAccessing 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).\n\nPages with actions cannot be prerendered, because a server must be able to handle the action POST requests."},{"breadcrumbs":["Page options","prerender","Route conflicts"],"href":"/docs/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.\n\nFor 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.\n\nFor pages, we skirt around this problem by writing foo/index.html instead of foo."},{"breadcrumbs":["Page options","prerender","Troubleshooting"],"href":"/docs/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.\n\nSince 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:\n\nEnsure that SvelteKit can find the route by following links from config.kit.prerender.entries or the 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"},{"breadcrumbs":["Page options","entries"],"href":"/docs/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...\n\n/ # 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.\n\nMost 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.\n\nThis 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\nentries can be an async function, allowing you to (for example) retrieve a list of posts from a CMS or database, in the example above."},{"breadcrumbs":["Page options","ssr"],"href":"/docs/page-options#ssr","content":"Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's hydrated. 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).\n\nIf 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."},{"breadcrumbs":["Page options","csr"],"href":"/docs/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:\n\nDisabling CSR does not ship any JavaScript to the client. This means:\n\nThe webpage should work with HTML and CSS only.\n<script> tags inside all Svelte components are removed.\n<form> elements cannot be progressively enhanced.\nLinks are handled by the browser with a full-page navigation.\nHot Module Replacement (HMR) will be disabled.\n\nYou can enable csr during development (for example to take advantage of HMR) like so:"},{"breadcrumbs":["Page options","trailingSlash"],"href":"/docs/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'.\n\nAs 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.\n\nThis 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.\n\nIgnoring 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."},{"breadcrumbs":["Page options","config"],"href":"/docs/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.\n\nconfig 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\nconfig 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...\n\n...is overridden by this page configuration...\n\n...which results in the config value { runtime: 'edge', regions: ['us1', 'us2'], foo: { baz: true } } for that page."},{"breadcrumbs":["Page options","Further reading"],"href":"/docs/page-options#further-reading","content":"Tutorial: Page options"},{"breadcrumbs":["State management"],"href":"/docs/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."},{"breadcrumbs":["State management","Avoid shared state on the server"],"href":"/docs/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.\n\nConceptually, 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\nThe 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.\n\nInstead, you should authenticate the user using cookies and persist the data to a database."},{"breadcrumbs":["State management","No side-effects in load"],"href":"/docs/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 inside a load function so that you can use the store value in your components:\n\nimport { user } from '$lib/user';\n\n/** @type {import('./$types').PageLoad} */\nexport async function load({ fetch }) {\n const response = await fetch('/api/user');\n\n // NEVER DO THIS!\n user.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\n...and pass it around to the components that need it, or use $page.data.\n\nIf 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."},{"breadcrumbs":["State management","Using stores with context"],"href":"/docs/state-management#using-stores-with-context","content":"You might wonder how we're able to use $page.data and other app stores if we can't use our own stores. The answer is that app stores on the server use Svelte's context API — the 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 stores:\n\n<!--- file: src/routes/+layout.svelte --->\n<script>\n import { setContext } from 'svelte';\n import { writable } from 'svelte/store';\n\n /** @type {import('./$types').LayoutData} */\n export let data;\n\n // Create a store and update it when necessary...\n const user = writable();\n $: user.set(data.user);\n\n // ...and add it to the context for child components to access\n setContext('user', user);\n</script><!--- file: src/routes/user/+page.svelte --->\n<script>\n import { getContext } from 'svelte';\n\n // Retrieve user store from context\n const user = getContext('user');\n</script>\n\n<p>Welcome {$user.name}</p>Updating the value of a context-based store 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 store 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.\n\nIf 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."},{"breadcrumbs":["State management","Component and page state is preserved"],"href":"/docs/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...\n\n<!--- file: src/routes/blog/[slug]/+page.svelte --->\n<script>\n /** @type {import('./$types').PageData} */\n export let data;\n\n // THIS CODE IS BUGGY!\n const wordCount = data.content.split(' ').length;\n const estimatedReadingTime = wordCount / 250;\n</script>\n\n<header>\n <h1>{data.title}</h1>\n <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.\n\nInstead, we need to make the value reactive:\n\nIf your code in onMount and onDestroy has to run again after navigation you can use afterNavigate and beforeNavigate respectively.\n\n\nReusing 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:\n\n{#key $page.url.pathname}\n <BlogPost title={data.title} content={data.title} />\n{/key}"},{"breadcrumbs":["State management","Storing state in the URL"],"href":"/docs/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."},{"breadcrumbs":["State management","Storing ephemeral state in snapshots"],"href":"/docs/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."},{"breadcrumbs":["Building your app"],"href":"/docs/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).\n\nFirstly, 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.\n\nSecondly, an adapter takes this production build and tunes it for your target environment — more on this on the following pages."},{"breadcrumbs":["Building your app","During the build"],"href":"/docs/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:\n\n+import { building } from '$app/environment';\nimport { setupMyDatabase } from '$lib/server/database';\n\n+if (!building) {\n setupMyDatabase();\n+}\n\nexport function load() {\n // ...\n}"},{"breadcrumbs":["Building your app","Preview your app"],"href":"/docs/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."},{"breadcrumbs":["Adapters"],"href":"/docs/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.\n\nOfficial adapters exist for a variety of platforms — these are documented on the following pages:\n\n@sveltejs/adapter-cloudflare for Cloudflare Pages\n@sveltejs/adapter-cloudflare-workers for Cloudflare Workers\n@sveltejs/adapter-netlify for Netlify\n@sveltejs/adapter-node for Node servers\n@sveltejs/adapter-static for static site generation (SSG)\n@sveltejs/adapter-vercel for Vercel\n\nAdditional community-provided adapters exist for other platforms."},{"breadcrumbs":["Adapters","Using adapters"],"href":"/docs/adapters#using-adapters","content":"Your adapter is specified in svelte.config.js:\n\nimport adapter from 'svelte-adapter-foo';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n kit: {\n adapter: adapter({\n // adapter options go here\n })\n }\n};\n\nexport default config;"},{"breadcrumbs":["Adapters","Platform-specific context"],"href":"/docs/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."},{"breadcrumbs":["Zero-config deployments"],"href":"/docs/adapter-auto","content":"When you create a new SvelteKit project with npm create svelte@latest, it installs adapter-auto by default. This adapter automatically installs and uses the correct adapter for supported environments when you deploy:\n\n@sveltejs/adapter-cloudflare for Cloudflare Pages\n@sveltejs/adapter-netlify for Netlify\n@sveltejs/adapter-vercel for Vercel\nsvelte-adapter-azure-swa for Azure Static Web Apps\nsvelte-kit-sst for AWS via SST\n@sveltejs/adapter-node for Google Cloud Run\n\nIt'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."},{"breadcrumbs":["Zero-config deployments","Environment-specific configuration"],"href":"/docs/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."},{"breadcrumbs":["Zero-config deployments","Adding community adapters"],"href":"/docs/adapter-auto#adding-community-adapters","content":"You can add zero-config support for additional adapters by editing adapters.js and opening a pull request."},{"breadcrumbs":["Node servers"],"href":"/docs/adapter-node","content":"To generate a standalone Node server, use adapter-node."},{"breadcrumbs":["Node servers","Usage"],"href":"/docs/adapter-node#usage","content":"Install with npm i -D @sveltejs/adapter-node, then add the adapter to your svelte.config.js:"},{"breadcrumbs":["Node servers","Deploying"],"href":"/docs/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.\n\nYou 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:\n\nnode 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."},{"breadcrumbs":["Node servers","Deploying","Compressing responses"],"href":"/docs/adapter-node#deploying-compressing-responses","content":"You will typically want to compress responses coming from the server. If you are already deploying your server behind a reverse proxy for SSL or load balancing, it typically results in better performance to also handle compression at that layer since Node.js is single-threaded.\n\nHowever, 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."},{"breadcrumbs":["Node servers","Environment variables"],"href":"/docs/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.)\n\nIn production, .env files are not automatically loaded. To do so, install dotenv in your project...\n\nnpm install dotenv...and invoke it before running the built app:\n\n- node build\n+ node -r dotenv/config buildIf you use Node.js v20.6+, you can use the --env-file flag instead:\n\n- node build\n+ node --env-file=.env build"},{"breadcrumbs":["Node servers","Environment variables","`PORT`, `HOST` and `SOCKET_PATH`"],"href":"/docs/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:\n\nHOST=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.\n\nSOCKET_PATH=/tmp/socket node build"},{"breadcrumbs":["Node servers","Environment variables","`ORIGIN`, `PROTOCOL_HEADER`, `HOST_HEADER`, and `PORT_HEADER`"],"href":"/docs/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:\n\nORIGIN=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:\n\nPROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node buildx-forwarded-proto and 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.\n\n\nIf adapter-node can't correctly determine the URL of your deployment, you may experience this error when using form actions:\n\nCross-site POST form submissions are forbidden"},{"breadcrumbs":["Node servers","Environment variables","`ADDRESS_HEADER` and `XFF_DEPTH`"],"href":"/docs/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:\n\nADDRESS_HEADER=True-Client-IP node buildHeaders can easily be spoofed. As with PROTOCOL_HEADER and HOST_HEADER, you should know what you're doing before setting these.\n\n\nIf 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:\n\n<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:\n\n<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.\n\nIf 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."},{"breadcrumbs":["Node servers","Environment variables","`BODY_SIZE_LIMIT`"],"href":"/docs/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."},{"breadcrumbs":["Node servers","Environment variables","`SHUTDOWN_TIMEOUT`"],"href":"/docs/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."},{"breadcrumbs":["Node servers","Environment variables","`IDLE_TIMEOUT`"],"href":"/docs/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."},{"breadcrumbs":["Node servers","Options"],"href":"/docs/adapter-node#options","content":"The adapter can be configured with various options:"},{"breadcrumbs":["Node servers","Options","out"],"href":"/docs/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."},{"breadcrumbs":["Node servers","Options","precompress"],"href":"/docs/adapter-node#options-precompress","content":"Enables precompressing using gzip and brotli for assets and prerendered pages. It defaults to true."},{"breadcrumbs":["Node servers","Options","envPrefix"],"href":"/docs/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:\n\nenvPrefix: 'MY_CUSTOM_';MY_CUSTOM_HOST=127.0.0.1 \\\nMY_CUSTOM_PORT=4000 \\\nMY_CUSTOM_ORIGIN=https://my.site \\\nnode build"},{"breadcrumbs":["Node servers","Graceful shutdown"],"href":"/docs/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:\n\nreject new requests (server.close)\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)\nand finally, close any remaining connections that are still active after SHUTDOWN_TIMEOUT seconds. (server.closeAllConnections)\n\nIf you want to customize this behaviour you can use a custom server.\n\n\nYou 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.\n\nThe parameter reason has one of the following values:\n\nSIGINT - shutdown was triggered by a SIGINT signal\nSIGTERM - shutdown was triggered by a SIGTERM signal\nIDLE - shutdown was triggered by IDLE_TIMEOUT"},{"breadcrumbs":["Node servers","Socket activation"],"href":"/docs/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.\n\nYou can still use envPrefix with systemd socket activation. LISTEN_PID and LISTEN_FDS are always read without a prefix.\n\n\nTo take advantage of socket activation follow these steps.\n\nRun your app as a systemd service. 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 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\nCreate an accompanying socket unit. The adapter only accepts a single socket.\n\nMake 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."},{"breadcrumbs":["Node servers","Custom server"],"href":"/docs/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.\n\nAlternatively, 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:"},{"breadcrumbs":["Static site generation"],"href":"/docs/adapter-static","content":"To use SvelteKit as a static site generator (SSG), use adapter-static.\n\nThis 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."},{"breadcrumbs":["Static site generation","Usage"],"href":"/docs/adapter-static#usage","content":"Install with npm i -D @sveltejs/adapter-static, then add the adapter to your svelte.config.js:\n\n...and add the prerender option to your root layout:\n\nYou must ensure SvelteKit's 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."},{"breadcrumbs":["Static site generation","Zero-config support"],"href":"/docs/adapter-static#zero-config-support","content":"Some platforms have zero-config support (more to come in future):\n\nVercel\n\nOn these platforms, you should omit the adapter options so that adapter-static can provide the optimal configuration:"},{"breadcrumbs":["Static site generation","Options"],"href":"/docs/adapter-static#options","content":""},{"breadcrumbs":["Static site generation","Options","pages"],"href":"/docs/adapter-static#options-pages","content":"The directory to write prerendered pages to. It defaults to build."},{"breadcrumbs":["Static site generation","Options","assets"],"href":"/docs/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."},{"breadcrumbs":["Static site generation","Options","fallback"],"href":"/docs/adapter-static#options-fallback","content":"Specify a fallback page for SPA mode, e.g. index.html or 200.html or 404.html."},{"breadcrumbs":["Static site generation","Options","precompress"],"href":"/docs/adapter-static#options-precompress","content":"If true, precompresses files with brotli and gzip. This will generate .br and .gz files."},{"breadcrumbs":["Static site generation","Options","strict"],"href":"/docs/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."},{"breadcrumbs":["Static site generation","GitHub Pages"],"href":"/docs/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.\n\nYou'll also want to generate a fallback 404.html page to replace the default 404 page shown by GitHub Pages.\n\nA config for GitHub Pages might look like the following:\n\nYou can use GitHub actions to automatically deploy your site to GitHub Pages when you make a change. Here's an example workflow:"},{"breadcrumbs":["Static site generation","GitHub Pages","file: .github/workflows/deploy.yml"],"href":"/docs/adapter-static#github-pages-file-github-workflows-deploy-yml","content":"name: Deploy to GitHub Pages\n\non:\n push:\n branches: 'main'\n\njobs:\n build_site:\n runs-on: ubuntu-latest\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n # 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 install\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-latest\n\npermissions:\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."},{"breadcrumbs":["Single-page apps"],"href":"/docs/single-page-apps","content":"You can turn any SvelteKit app, using any adapter, into a fully client-rendered single-page app (SPA) by disabling SSR at the root layout:\n\nIn most situations this is not recommended: it harms SEO, tends to slow down perceived performance, and makes your app inaccessible to users if JavaScript fails or is disabled (which happens more often than you probably think).\n\n\nIf 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 by adding a fallback page."},{"breadcrumbs":["Single-page apps","Usage"],"href":"/docs/single-page-apps#usage","content":"Install with npm i -D @sveltejs/adapter-static, then add the adapter to your svelte.config.js with the following options:\n\nThe 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.\n\nOn some hosts it may be index.html or something else entirely — consult your platform's documentation.\n\nNote that the fallback page will always contain absolute asset paths (i.e. beginning with / rather than .) regardless of the value of paths.relative, since it is used to respond to requests for arbitrary paths."},{"breadcrumbs":["Single-page apps","Apache"],"href":"/docs/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:\n\n<IfModule mod_rewrite.c>\n RewriteEngine On\n RewriteBase /\n RewriteRule ^200\\.html$ - [L]\n RewriteCond %{REQUEST_FILENAME} !-f\n RewriteCond %{REQUEST_FILENAME} !-d\n RewriteRule . /200.html [L]\n</IfModule>"},{"breadcrumbs":["Single-page apps","Prerendering individual pages"],"href":"/docs/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:"},{"breadcrumbs":["Cloudflare Pages"],"href":"/docs/adapter-cloudflare","content":"To deploy to Cloudflare Pages, use adapter-cloudflare.\n\nThis adapter will be installed by default when you use adapter-auto. If you plan on staying with Cloudflare Pages, you can switch from adapter-auto to using this adapter directly so that values specific to Cloudflare Workers are emulated during local development, type declarations are automatically applied, and the ability to set Cloudflare-specific options is provided."},{"breadcrumbs":["Cloudflare Pages","Comparisons"],"href":"/docs/adapter-cloudflare#comparisons","content":"adapter-cloudflare – supports all SvelteKit features; builds for Cloudflare Pages\nadapter-cloudflare-workers – supports all SvelteKit features; builds for Cloudflare Workers\nadapter-static – only produces client-side static assets; compatible with Cloudflare Pages"},{"breadcrumbs":["Cloudflare Pages","Usage"],"href":"/docs/adapter-cloudflare#usage","content":"Install with npm i -D @sveltejs/adapter-cloudflare, then add the adapter to your svelte.config.js:"},{"breadcrumbs":["Cloudflare Pages","Options"],"href":"/docs/adapter-cloudflare#options","content":""},{"breadcrumbs":["Cloudflare Pages","Options","routes"],"href":"/docs/adapter-cloudflare#options-routes","content":"Allows you to customise the _routes.json file generated by adapter-cloudflare.\n\ninclude defines routes that will invoke a function, and defaults to ['/*']\nexclude defines routes that will not invoke a function — this is a faster and cheaper way to serve your app's static assets. This array can include the following special values:<build> contains your app's build artifacts (the files generated by Vite)\n<files> contains the contents of your static directory\n<prerendered> contains a list of prerendered pages\n<all> (the default) contains all of the above\n\n\n\nYou 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', ...]."},{"breadcrumbs":["Cloudflare Pages","Options","platformProxy"],"href":"/docs/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."},{"breadcrumbs":["Cloudflare Pages","Deployment"],"href":"/docs/adapter-cloudflare#deployment","content":"Please follow the Get Started Guide for Cloudflare Pages to begin.\n\nWhen configuring your project settings, you must use the following settings:\n\nFramework preset – SvelteKit\nBuild command – npm run build or vite build\nBuild output directory – .svelte-kit/cloudflare"},{"breadcrumbs":["Cloudflare Pages","Runtime APIs"],"href":"/docs/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 context, caches, and cf, meaning that you can access it in hooks and endpoints:\n\nSvelteKit's built-in $env module should be preferred for environment variables.\n\n\nTo include type declarations for your bindings, reference them in your src/app.d.ts:"},{"breadcrumbs":["Cloudflare Pages","Runtime APIs","Testing Locally"],"href":"/docs/adapter-cloudflare#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 the configuration in your wrangler.toml 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.\n\nFor testing the build, you should use wrangler version 3. Once you have built your site, run wrangler pages dev .svelte-kit/cloudflare."},{"breadcrumbs":["Cloudflare Pages","Notes"],"href":"/docs/adapter-cloudflare#notes","content":"Functions contained in the /functions directory at the project's root will not be included in the deployment, which is compiled to a single _worker.js file. Functions should be implemented as server endpoints in your SvelteKit app.\n\nThe _headers and _redirects files specific to Cloudflare Pages can be used for static asset responses (like images) by putting them into the /static folder.\n\nHowever, 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."},{"breadcrumbs":["Cloudflare Pages","Troubleshooting"],"href":"/docs/adapter-cloudflare#troubleshooting","content":""},{"breadcrumbs":["Cloudflare Pages","Troubleshooting","Further reading"],"href":"/docs/adapter-cloudflare#troubleshooting-further-reading","content":"You may wish to refer to Cloudflare's documentation for deploying a SvelteKit site."},{"breadcrumbs":["Cloudflare Pages","Troubleshooting","Accessing the file system"],"href":"/docs/adapter-cloudflare#troubleshooting-accessing-the-file-system","content":"You can't use fs in Cloudflare Workers — you must prerender the routes in question."},{"breadcrumbs":["Cloudflare Workers"],"href":"/docs/adapter-cloudflare-workers","content":"To deploy to Cloudflare Workers, use adapter-cloudflare-workers.\n\nUnless you have a specific reason to use adapter-cloudflare-workers, it's recommended that you use adapter-cloudflare instead. Both adapters have equivalent functionality, but Cloudflare Pages offers features like GitHub integration with automatic builds and deploys, preview deployments, instant rollback and so on."},{"breadcrumbs":["Cloudflare Workers","Usage"],"href":"/docs/adapter-cloudflare-workers#usage","content":"Install with npm i -D @sveltejs/adapter-cloudflare-workers, then add the adapter to your svelte.config.js:"},{"breadcrumbs":["Cloudflare Workers","Options"],"href":"/docs/adapter-cloudflare-workers#options","content":""},{"breadcrumbs":["Cloudflare Workers","Options","config"],"href":"/docs/adapter-cloudflare-workers#options-config","content":"Path to your custom wrangler.toml config file."},{"breadcrumbs":["Cloudflare Workers","Options","platformProxy"],"href":"/docs/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."},{"breadcrumbs":["Cloudflare Workers","Basic Configuration"],"href":"/docs/adapter-cloudflare-workers#basic-configuration","content":"This adapter expects to find a wrangler.toml file in the project root. It should look something like this:\n\n<your-service-name> can be anything. <your-account-id> can be found by logging into your Cloudflare dashboard and grabbing it from the end of the URL:\n\nhttps://dash.cloudflare.com/<your-account-id>You should add the .cloudflare directory (or whichever directories you specified for main and site.bucket) to your .gitignore.\n\n\nYou will need to install wrangler and log in, if you haven't already:\n\nnpm i -g wrangler\nwrangler loginThen, you can build your app and deploy it:\n\nwrangler deploy"},{"breadcrumbs":["Cloudflare Workers","Custom config"],"href":"/docs/adapter-cloudflare-workers#custom-config","content":"If you would like to use a config file other than wrangler.toml you can specify so using the config option.\n\nIf you would like to enable Node.js compatibility, you can add "nodejs_compat" flag to wrangler.toml:"},{"breadcrumbs":["Cloudflare Workers","Runtime APIs"],"href":"/docs/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 context, caches, and cf, meaning that you can access it in hooks and endpoints:\n\nSvelteKit's built-in $env module should be preferred for environment variables.\n\n\nTo include type declarations for your bindings, reference them in your src/app.d.ts:"},{"breadcrumbs":["Cloudflare Workers","Runtime APIs","Testing Locally"],"href":"/docs/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 the configuration in your wrangler.toml 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.\n\nFor testing the build, you should use wrangler version 3. Once you have built your site, run wrangler dev."},{"breadcrumbs":["Cloudflare Workers","Troubleshooting"],"href":"/docs/adapter-cloudflare-workers#troubleshooting","content":""},{"breadcrumbs":["Cloudflare Workers","Troubleshooting","Worker size limits"],"href":"/docs/adapter-cloudflare-workers#troubleshooting-worker-size-limits","content":"When deploying to workers, 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."},{"breadcrumbs":["Cloudflare Workers","Troubleshooting","Accessing the file system"],"href":"/docs/adapter-cloudflare-workers#troubleshooting-accessing-the-file-system","content":"You can't use fs in Cloudflare Workers — you must prerender the routes in question."},{"breadcrumbs":["Netlify"],"href":"/docs/adapter-netlify","content":"To deploy to Netlify, use adapter-netlify.\n\nThis adapter will be installed by default when you use adapter-auto, but adding it to your project allows you to specify Netlify-specific options."},{"breadcrumbs":["Netlify","Usage"],"href":"/docs/adapter-netlify#usage","content":"Install with npm i -D @sveltejs/adapter-netlify, then add the adapter to your svelte.config.js:\n\nThen, 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:\n\n[build]\n command = \"npm run build\"\n publish = \"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"."},{"breadcrumbs":["Netlify","Usage","Node version"],"href":"/docs/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."},{"breadcrumbs":["Netlify","Netlify Edge Functions"],"href":"/docs/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."},{"breadcrumbs":["Netlify","Netlify alternatives to SvelteKit functionality"],"href":"/docs/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."},{"breadcrumbs":["Netlify","Netlify alternatives to SvelteKit functionality","Redirect rules"],"href":"/docs/adapter-netlify#netlify-alternatives-to-sveltekit-functionality-redirect-rules","content":"During compilation, redirect rules are automatically appended to your _redirects file. (If it doesn't exist yet, it will be created.) That means:\n\n[[redirects]] in netlify.toml will never match as _redirects has a higher priority. So always put your rules in the _redirects file.\n_redirects shouldn't have any custom "catch all" rules such as /* /foobar/:splat. Otherwise the automatically appended rule will never be applied as Netlify is only processing the first matching rule."},{"breadcrumbs":["Netlify","Netlify alternatives to SvelteKit functionality","Netlify Forms"],"href":"/docs/adapter-netlify#netlify-alternatives-to-sveltekit-functionality-netlify-forms","content":"Create your Netlify HTML form as described here, 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 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 like <form netlify ... action="/success"> then ensure the corresponding /routes/success/+page.svelte exists and is prerendered."},{"breadcrumbs":["Netlify","Netlify alternatives to SvelteKit functionality","Netlify Functions"],"href":"/docs/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\nAdditionally, you can add your own Netlify functions by creating a directory for them and adding the configuration to your netlify.toml file. For example:\n\n[build]\n command = \"npm run build\"\n publish = \"build\"\n\n[functions]\n directory = \"functions\""},{"breadcrumbs":["Netlify","Troubleshooting"],"href":"/docs/adapter-netlify#troubleshooting","content":""},{"breadcrumbs":["Netlify","Troubleshooting","Accessing the file system"],"href":"/docs/adapter-netlify#troubleshooting-accessing-the-file-system","content":"You can't use fs in edge deployments.\n\nYou 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. read does not work inside edge deployments (this may change in future).\n\nAlternatively, you can prerender the routes in question."},{"breadcrumbs":["Vercel"],"href":"/docs/adapter-vercel","content":"To deploy to Vercel, use adapter-vercel.\n\nThis adapter will be installed by default when you use adapter-auto, but adding it to your project allows you to specify Vercel-specific options."},{"breadcrumbs":["Vercel","Usage"],"href":"/docs/adapter-vercel#usage","content":"Install with npm i -D @sveltejs/adapter-vercel, then add the adapter to your svelte.config.js:"},{"breadcrumbs":["Vercel","Deployment configuration"],"href":"/docs/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.\n\nFor example you could deploy some parts of your app as Edge Functions...\n\n...and others as Serverless Functions (note that by specifying config inside a layout, it applies to all child pages):\n\nThe following options apply to all functions:\n\nruntime: 'edge', 'nodejs18.x' or 'nodejs20.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\nregions: an array of 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\nsplit: 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 functions\n\nAdditionally, the following option applies to edge functions:\n\nexternal: 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 Node\n\nAnd the following option apply to serverless functions:\n\nmemory: the amount of memory available to the function. Defaults to 1024 Mb, and can be decreased to 128 Mb or increased in 64Mb increments up to 3008 Mb on Pro or Enterprise accounts\nmaxDuration: maximum execution duration of the function. Defaults to 10 seconds for Hobby accounts, 15 for Pro and 900 for Enterprise\nisr: configuration Incremental Static Regeneration, described below\n\nIf 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."},{"breadcrumbs":["Vercel","Image Optimization"],"href":"/docs/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:"},{"breadcrumbs":["Vercel","Incremental Static Regeneration"],"href":"/docs/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.\n\nTo add ISR to a route, include the isr property in your config object:\n\nimport { BYPASS_TOKEN } from '$env/static/private';\n\nexport const config = {\n isr: {\n // Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function.\n // Setting the value to `false` means it will never expire.\n expiration: 60,\n\n // Random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset\n // with a __prerender_bypass=<token> cookie.\n //\n // Making a `GET` or `HEAD` request with `x-prerender-revalidate: <token>` will force the asset to be re-validated.\n bypassToken: BYPASS_TOKEN,\n\n // List of valid query parameters. Other parameters (such as utm tracking codes) will be ignored,\n // ensuring that they do not result in content being regenerated unnecessarily\n allowQuery: ['search']\n }\n};The expiration property is required; all others are optional."},{"breadcrumbs":["Vercel","Environment variables"],"href":"/docs/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:\n\n<!--- file: +layout.svelte --->\n<script>\n /** @type {import('./$types').LayoutServerData} */\n export let data;\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."},{"breadcrumbs":["Vercel","Skew protection"],"href":"/docs/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 the updated store value, which tells clients when a new version has been deployed.)\n\nSkew 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. (The updated store 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.\n\nCookie-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."},{"breadcrumbs":["Vercel","Notes"],"href":"/docs/adapter-vercel#notes","content":""},{"breadcrumbs":["Vercel","Notes","Vercel functions"],"href":"/docs/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."},{"breadcrumbs":["Vercel","Notes","Node version"],"href":"/docs/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."},{"breadcrumbs":["Vercel","Troubleshooting"],"href":"/docs/adapter-vercel#troubleshooting","content":""},{"breadcrumbs":["Vercel","Troubleshooting","Accessing the file system"],"href":"/docs/adapter-vercel#troubleshooting-accessing-the-file-system","content":"You can't use fs in edge functions.\n\nYou 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. read does not work inside routes deployed as edge functions (this may change in future).\n\nAlternatively, you can prerender the routes in question."},{"breadcrumbs":["Writing adapters"],"href":"/docs/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.\n\nAdapter packages implement the following API, which creates an Adapter:\n\n/** @param {AdapterSpecificOptions} options */\nexport default function (options) {\n /** @type {import('@sveltejs/kit').Adapter} */\n const adapter = {\n name: 'adapter-package-name',\n async adapt(builder) {\n // adapter implementation\n },\n async emulate() {\n return {\n async platform({ config, prerender }) {\n // the returned object becomes `event.platform` during dev, build and\n // preview. Its shape is that of `App.Platform`\n }\n }\n },\n supports: {\n read: ({ config, route }) => {\n // Return `true` if the route with the given `config` can use `read`\n // from `$app/server` in production, return `false` if it can't.\n // Or throw a descriptive error describing how to configure the deployment\n }\n }\n };\n\n return adapter;\n}Of these, name and adapt are required. emulate and supports are optional.\n\nWithin the adapt method, there are a number of things that an adapter should do:\n\nClear out the build directory\nWrite SvelteKit output with builder.writeClient, builder.writeServer, and builder.writePrerendered\nOutput code that:Imports Server from ${builder.getServerDirectory()}/index.js\nInstantiates the app with a manifest generated with builder.generateManifest({ relativePath })\nListens for requests from the platform, converts them to a standard Request if necessary, calls the server.respond(request, { getClientAddress }) function to generate a Response and responds with it\nexpose any platform-specific information to SvelteKit via the platform option passed to server.respond\nGlobally shims fetch to work on the target platform, if necessary. SvelteKit provides a @sveltejs/kit/node/polyfills helper for platforms that can use undici\n\n\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 platform\n\nWhere possible, we recommend putting the adapter output under the build/ directory with any intermediate output placed under .svelte-kit/[adapter-name]."},{"breadcrumbs":["Advanced routing"],"href":"/docs/advanced-routing","content":""},{"breadcrumbs":["Advanced routing","Rest parameters"],"href":"/docs/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...\n\n/[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// @noErrors\n{\n org: 'sveltejs',\n repo: 'kit',\n branch: 'main',\n file: 'documentation/docs/04-advanced-routing.md'\n}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."},{"breadcrumbs":["Advanced routing","Rest parameters","404 pages"],"href":"/docs/advanced-routing#rest-parameters-404-pages","content":"Rest parameters also allow you to render custom 404s. Given these routes...\n\nsrc/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:\n\nsrc/routes/\n├ marx-brothers/\n+| ├ [...path]/\n│ ├ chico/\n│ ├ harpo/\n│ ├ groucho/\n│ └ +error.svelte\n└ +error.svelteIf you don't handle 404 cases, they will appear in handleError"},{"breadcrumbs":["Advanced routing","Optional parameters"],"href":"/docs/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]]/home\n\nNote 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."},{"breadcrumbs":["Advanced routing","Matching"],"href":"/docs/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 params directory...\n\n...and augmenting your routes:\n\n-src/routes/fruits/[page]\n+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.\n\nEach 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.\n\nMatchers run both on the server and in the browser."},{"breadcrumbs":["Advanced routing","Sorting"],"href":"/docs/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:\n\nsrc/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...\n\nMore 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 ([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\n\n...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:\n\nsrc/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"},{"breadcrumbs":["Advanced routing","Encoding"],"href":"/docs/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.\n\nTo 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:\n\n\\ — [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]\n\nFor example, to create a /smileys/:-) route, you would create a src/routes/smileys/[x+3a]-[x+29]/+page.svelte file.\n\nYou can determine the hexadecimal code for a character with JavaScript:\n\n':'.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:\n\nsrc/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.\n\nSince TypeScript struggles with directories with a leading . character, you may find it useful to encode these characters when creating e.g. .well-known routes: src/routes/[x+2e]well-known/..."},{"breadcrumbs":["Advanced routing","Advanced layouts"],"href":"/docs/advanced-routing#advanced-layouts","content":"By default, the layout hierarchy mirrors the route hierarchy. In some cases, that might not be what you want."},{"breadcrumbs":["Advanced routing","Advanced layouts","(group)"],"href":"/docs/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:\n\nsrc/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."},{"breadcrumbs":["Advanced routing","Advanced layouts","Breaking out of layouts"],"href":"/docs/advanced-routing#advanced-layouts-breaking-out-of-layouts","content":"The root layout applies to every page of your app — if omitted, it defaults to <slot />. 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.\n\nIn the example above, the /admin route does not inherit either the (app) or (marketing) layouts."},{"breadcrumbs":["Advanced routing","Advanced layouts","+page@"],"href":"/docs/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:\n\nsrc/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:\n\n+page@[id].svelte - inherits from src/routes/(app)/item/[id]/+layout.svelte\[email protected] - inherits from src/routes/(app)/item/+layout.svelte\n+page@(app).svelte - inherits from src/routes/(app)/+layout.svelte\[email protected] - inherits from src/routes/+layout.svelte\n\nsrc/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"},{"breadcrumbs":["Advanced routing","Advanced layouts","+layout@"],"href":"/docs/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 [email protected] component would reset the hierarchy for all its child routes.\n\nsrc/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/[email protected]\n│ │ │ └ +page.svelte // uses (app)/item/[email protected]\n│ │ └ [email protected] // inherits from root layout, skipping (app)/+layout.svelte\n│ └ +layout.svelte\n└ +layout.svelte"},{"breadcrumbs":["Advanced routing","Advanced layouts","When to use layout groups"],"href":"/docs/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:\n\n<!--- file: src/routes/nested/route/[email protected] --->\n<script>\n import ReusableLayout from '$lib/ReusableLayout.svelte';\n export let data;\n</script>\n\n<ReusableLayout {data}>\n <slot />\n</ReusableLayout>import { reusableLoad } from '$lib/reusable-load-function';\n\n/** @type {import('./$types').PageLoad} */\nexport function load(event) {\n // Add additional logic here, if needed\n return reusableLoad(event);\n}"},{"breadcrumbs":["Advanced routing","Further reading"],"href":"/docs/advanced-routing#further-reading","content":"Tutorial: Advanced Routing"},{"breadcrumbs":["Hooks"],"href":"/docs/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.\n\nThere are three hooks files, all optional:\n\nsrc/hooks.server.js — your app's server hooks\nsrc/hooks.client.js — your app's client hooks\nsrc/hooks.js — your app's hooks that run on both the client and server\n\nCode in these modules will run when the application starts up, making them useful for initializing database clients and so on.\n\nYou can configure the location of these files with config.kit.files.hooks."},{"breadcrumbs":["Hooks","Server hooks"],"href":"/docs/hooks#server-hooks","content":"The following hooks can be added to src/hooks.server.js:"},{"breadcrumbs":["Hooks","Server hooks","handle"],"href":"/docs/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\nRequests for static assets — which includes pages that were already prerendered — are not handled by SvelteKit.\n\n\nIf unimplemented, defaults to ({ event, resolve }) => resolve(event). 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.\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n event.locals.user = await getUserInformation(event.cookies.get('sessionid'));\n\n const response = await resolve(event);\n response.headers.set('x-custom-header', 'potato');\n\n return response;\n}You can define multiple handle functions and execute them with the sequence helper function.\n\nresolve 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:\n\ntransformPageChunk(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.\nfilterSerializedResponseHeaders(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.\npreload(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\nNote 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."},{"breadcrumbs":["Hooks","Server hooks","handleFetch"],"href":"/docs/hooks#server-hooks-handlefetch","content":"This function allows you to modify (or replace) a fetch request that happens inside a load or action function that runs on the server (or during pre-rendering).\n\nFor 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\nCredentials\n\nFor same-origin requests, SvelteKit's fetch implementation will forward cookie and authorization headers unless the credentials option is set to "omit".\n\nFor 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.\n\nIf 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:"},{"breadcrumbs":["Hooks","Shared hooks"],"href":"/docs/hooks#shared-hooks","content":"The following can be added to src/hooks.server.js and src/hooks.client.js:"},{"breadcrumbs":["Hooks","Shared hooks","handleError"],"href":"/docs/hooks#shared-hooks-handleerror","content":"If an unexpected error is thrown during loading or rendering, this function will be called with the error, event, status code and message. This allows for two things:\n\nyou 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.\n\nFor 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).\n\nTo 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:\n\nimport * as Sentry from '@sentry/sveltekit';\n\nSentry.init({/*...*/})\n\n/** @type {import('@sveltejs/kit').HandleServerError} */\nexport async function handleError({ error, event, status, message }) {\n const errorId = crypto.randomUUID();\n\n // example integration with https://sentry.io/\n Sentry.captureException(error, {\n extra: { event, errorId, status }\n });\n\n return {\n message: 'Whoops!',\n errorId\n };\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 const errorId = crypto.randomUUID();\n\n // example integration with https://sentry.io/\n Sentry.captureException(error, {\n extra: { event, errorId, status }\n });\n\n return {\n message: 'Whoops!',\n errorId\n };\n}In src/hooks.client.js, the type of handleError is HandleClientError instead of HandleServerError, and event is a NavigationEvent rather than a RequestEvent.\n\n\nThis function is not called for expected errors (those thrown with the error function imported from @sveltejs/kit).\n\nDuring 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.\n\nMake sure that handleError never throws an error"},{"breadcrumbs":["Hooks","Universal hooks"],"href":"/docs/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)."},{"breadcrumbs":["Hooks","Universal hooks","reroute"],"href":"/docs/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.\n\nFor 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\nThe lang parameter will be correctly derived from the returned pathname.\n\nUsing reroute will not change the contents of the browser's address bar, or the value of event.url."},{"breadcrumbs":["Hooks","Further reading"],"href":"/docs/hooks#further-reading","content":"Tutorial: Hooks"},{"breadcrumbs":["Errors"],"href":"/docs/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."},{"breadcrumbs":["Errors","Error objects"],"href":"/docs/errors#error-objects","content":"SvelteKit distinguishes between expected and unexpected errors, both of which are represented as simple { message: string } objects by default.\n\nYou 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)."},{"breadcrumbs":["Errors","Expected errors"],"href":"/docs/errors#expected-errors","content":"An expected error is one created with the error helper imported from @sveltejs/kit:\n\nimport { error } from '@sveltejs/kit';\nimport * as db from '$lib/server/database';\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function load({ params }) {\n const post = await db.getPost(params.slug);\n\n if (!post) {\n error(404, {\n message: 'Not found'\n });\n }\n\n return { 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(...).\n\n<!--- file: src/routes/+error.svelte --->\n<script>\n import { page } from '$app/stores';\n</script>\n\n<h1>{$page.error.message}</h1>You can add extra properties to the error object if needed...\n\nerror(404, {\n message: 'Not found',\n+\tcode: 'NOT_FOUND'\n});...otherwise, for convenience, you can pass a string as the second argument:\n\n-error(404, { message: 'Not found' });\n+error(404, 'Not found');In SvelteKit 1.x you had to throw the error yourself"},{"breadcrumbs":["Errors","Unexpected errors"],"href":"/docs/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.\n\nBy 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:\n\n{ \"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."},{"breadcrumbs":["Errors","Responses"],"href":"/docs/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.\n\nYou can customise the fallback error page by adding a src/error.html file:\n\n<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>%sveltekit.error.message%</title>\n </head>\n <body>\n <h1>My custom error page</h1>\n <p>Status: %sveltekit.status%</p>\n <p>Message: %sveltekit.error.message%</p>\n </body>\n</html>SvelteKit will replace %sveltekit.status% and %sveltekit.error.message% with their corresponding values.\n\nIf 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).\n\nThe 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."},{"breadcrumbs":["Errors","Type safety"],"href":"/docs/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'):\n\nThis interface always includes a message: string property."},{"breadcrumbs":["Errors","Further reading"],"href":"/docs/errors#further-reading","content":"Tutorial: Errors and redirects\nTutorial: Hooks"},{"breadcrumbs":["Link options"],"href":"/docs/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.\n\nYou can customise the behaviour of links with data-sveltekit-* attributes. These can be applied to the <a> itself, or to a parent element.\n\nThese options also apply to <form> elements with method="GET"."},{"breadcrumbs":["Link options","data-sveltekit-preload-data"],"href":"/docs/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.\n\nSvelteKit 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.\n\nWe can control this behaviour with the data-sveltekit-preload-data attribute, which can have one of two values:\n\n"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 registered\n\nThe 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:\n\n<body data-sveltekit-preload-data=\"hover\">\n <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.\n\nIn these cases, you can specify the "tap" value, which causes SvelteKit to call load only when the user taps or clicks on a link:\n\n<a data-sveltekit-preload-data=\"tap\" href=\"/stonks\">\n Get current stonk values\n</a>You can also programmatically invoke preloadData from $app/navigation.\n\n\nData will never be preloaded if the user has chosen reduced data usage, meaning navigator.connection.saveData is true."},{"breadcrumbs":["Link options","data-sveltekit-preload-code"],"href":"/docs/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':\n\n"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 preloaded\n\nNote 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.\n\nSince 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.\n\n\nAs with data-sveltekit-preload-data, this attribute will be ignored if the user has chosen reduced data usage."},{"breadcrumbs":["Link options","data-sveltekit-reload"],"href":"/docs/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...\n\n<a data-sveltekit-reload href=\"/path\">Path</a>...will cause a full-page navigation when the link is clicked.\n\nLinks with a rel="external" attribute will receive the same treatment. In addition, they will be ignored during prerendering."},{"breadcrumbs":["Link options","data-sveltekit-replacestate"],"href":"/docs/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...\n\n<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."},{"breadcrumbs":["Link options","data-sveltekit-keepfocus"],"href":"/docs/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...\n\n<form data-sveltekit-keepfocus>\n <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."},{"breadcrumbs":["Link options","data-sveltekit-noscroll"],"href":"/docs/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).\n\nIn certain cases, you may wish to disable this behaviour. Adding a data-sveltekit-noscroll attribute to a link...\n\n<a href=\"path\" data-sveltekit-noscroll>Path</a>...will prevent scrolling after the link is clicked."},{"breadcrumbs":["Link options","Disabling options"],"href":"/docs/link-options#disabling-options","content":"To disable any of these options inside an element where they have been enabled, use the "false" value:\n\n<div data-sveltekit-preload-data>\n <!-- these links will be preloaded -->\n <a href=\"/a\">a</a>\n <a href=\"/b\">b</a>\n <a href=\"/c\">c</a>\n\n <div data-sveltekit-preload-data=\"false\">\n <!-- these links will NOT be preloaded -->\n <a href=\"/d\">d</a>\n <a href=\"/e\">e</a>\n <a href=\"/f\">f</a>\n </div>\n</div>To apply an attribute to an element conditionally, do this:\n\n<div data-sveltekit-preload-data={condition ? 'hover' : false}>"},{"breadcrumbs":["Service workers"],"href":"/docs/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.\n\nIn 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 change the location of your service worker if you need to.\n\nYou 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:\n\nif ('serviceWorker' in navigator) {\n addEventListener('load', function () {\n navigator.serviceWorker.register('./path/to/service-worker.js');\n });\n}"},{"breadcrumbs":["Service workers","Inside the service worker"],"href":"/docs/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.\n\nThe 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\nBe 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."},{"breadcrumbs":["Service workers","During development"],"href":"/docs/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:\n\nimport { dev } from '$app/environment';\n\nnavigator.serviceWorker.register('/service-worker.js', {\n type: dev ? 'module' : 'classic'\n});build and prerendered are empty arrays during development"},{"breadcrumbs":["Service workers","Type safety"],"href":"/docs/service-workers#type-safety","content":"Setting up proper types for service workers requires some manual setup. Inside your service-worker.js, add the following to the top of your file:\n\n/// <reference types=\"@sveltejs/kit\" />\n/// <reference no-default-lib=\"true\"/>\n/// <reference lib=\"esnext\" />\n/// <reference lib=\"webworker\" />\n\nconst sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (self));/// <reference types=\"@sveltejs/kit\" />\n/// <reference no-default-lib=\"true\"/>\n/// <reference lib=\"esnext\" />\n/// <reference lib=\"webworker\" />\n\nconst sw = self as unknown as ServiceWorkerGlobalScope;This disables access to DOM typings like HTMLElement which are not available inside a service worker and instantiates the correct globals. The reassignment of self to sw allows you to type cast it in the process (there are a couple of ways to do this, but this is the easiest that requires no additional files). Use sw instead of self in the rest of the file. The reference to the SvelteKit types ensures that the $service-worker import has proper type definitions. If you import $env/static/public you either have to // @ts-ignore the import or add /// <reference types="../.svelte-kit/ambient.d.ts" /> to the reference types."},{"breadcrumbs":["Service workers","Other solutions"],"href":"/docs/service-workers#other-solutions","content":"SvelteKit's service worker implementation is deliberately low-level. If you need a more full-fledged but also more opinionated solution, we recommend looking at solutions like Vite PWA plugin, which uses Workbox. For more general information on service workers, we recommend the MDN web docs."},{"breadcrumbs":["Server-only modules"],"href":"/docs/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."},{"breadcrumbs":["Server-only modules","Private environment variables"],"href":"/docs/server-only-modules#private-environment-variables","content":"The $env/static/private and $env/dynamic/private modules, which are covered in the modules section, can only be imported into modules that only run on the server, such as hooks.server.js or +page.server.js."},{"breadcrumbs":["Server-only modules","Server-only utilities"],"href":"/docs/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."},{"breadcrumbs":["Server-only modules","Your modules"],"href":"/docs/server-only-modules#your-modules","content":"You can make your own modules server-only in two ways:\n\nadding .server to the filename, e.g. secrets.server.js\nplacing them in $lib/server, e.g. $lib/server/secrets.js"},{"breadcrumbs":["Server-only modules","How it works"],"href":"/docs/server-only-modules#how-it-works","content":"Any time you have public-facing code that imports server-only code (whether directly or indirectly)...\n\n...SvelteKit will error:\n\nCannot import $lib/server/secrets.js into public-facing code:\n- src/routes/+page.svelte\n - src/routes/utils.js\n - $lib/server/secrets.jsEven 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.\n\nThis feature also works with dynamic imports, even interpolated ones like await import(`./${foo}.js`), with one small caveat: during development, if there are two or more dynamic imports between the public-facing code and the server-only module, the illegal import will not be detected the first time the code is loaded.\n\nUnit 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'."},{"breadcrumbs":["Server-only modules","Further reading"],"href":"/docs/server-only-modules#further-reading","content":"Tutorial: Environment variables"},{"breadcrumbs":["Snapshots"],"href":"/docs/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.\n\nFor 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.\n\nTo do this, export a snapshot object with capture and restore methods from a +page.svelte or +layout.svelte:\n\n<!--- file: +page.svelte --->\n<script>\n let comment = '';\n\n /** @type {import('./$types').Snapshot<string>} */\n export const snapshot = {\n capture: () => comment,\n restore: (value) => comment = value\n };\n</script>\n\n<form method=\"POST\">\n <label for=\"comment\">Comment</label>\n <textarea id=\"comment\" bind:value={comment} />\n <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.\n\nThe 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.\n\nAvoid 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."},{"breadcrumbs":["Shallow routing"],"href":"/docs/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.\n\nSometimes, 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.\n\nSvelteKit 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:\n\n<!--- file: +page.svelte --->\n<script>\n import { pushState } from '$app/navigation';\n import { page } from '$app/stores';\n import Modal from './Modal.svelte';\n\n function showModal() {\n pushState('', {\n showModal: true\n });\n }\n</script>\n\n{#if $page.state.showModal}\n <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."},{"breadcrumbs":["Shallow routing","API"],"href":"/docs/shallow-routing#api","content":"The first argument to pushState is the URL, relative to the current URL. To stay on the current URL, use ''.\n\nThe second argument is the new page state, which can be accessed via the page store as $page.state. You can make page state type-safe by declaring an App.PageState interface (usually in src/app.d.ts).\n\nTo set page state without creating a new history entry, use replaceState instead of pushState."},{"breadcrumbs":["Shallow routing","Loading data for a route"],"href":"/docs/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.\n\nFor 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.\n\n<!--- file: src/routes/photos/+page.svelte --->\n<script>\n import { preloadData, pushState, goto } from '$app/navigation';\n import { page } from '$app/stores';\n import Modal from './Modal.svelte';\n import PhotoPage from './[id]/+page.svelte';\n\n export let data;\n</script>\n\n{#each data.thumbnails as thumbnail}\n <a\n href=\"/photos/{thumbnail.id}\"\n on:click={async (e) => {\n if (innerWidth < 640 // bail if the screen is too small\n || e.shiftKey // or the link is opened in a new window\n || e.metaKey || e.ctrlKey // or a new tab (mac: metaKey, win/linux: ctrlKey)\n // should also consider clicking with a mouse scroll wheel \n ) return;\n\n // prevent navigation\n e.preventDefault();\n\n const { href } = e.currentTarget;\n\n // run `load` functions (or rather, get the result of the `load` functions\n // that are already running because of `data-sveltekit-preload-data`)\n const result = await preloadData(href);\n\n if (result.type === 'loaded' && result.status === 200) {\n pushState(href, { selected: result.data });\n } else {\n // something bad happened! try navigating\n goto(href);\n }\n }}\n >\n <img alt={thumbnail.alt} src={thumbnail.src} />\n </a>\n{/each}\n\n{#if $page.state.selected}\n <Modal on:close={() => history.back()}>\n <!-- pass page data to the +page.svelte component,\n just like SvelteKit would on navigation -->\n <PhotoPage data={$page.state.selected} />\n </Modal>\n{/if}"},{"breadcrumbs":["Shallow routing","Caveats"],"href":"/docs/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.\n\nShallow 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."},{"breadcrumbs":["Packaging"],"href":"/docs/packaging","content":"You can use SvelteKit to build apps as well as component libraries, using the @sveltejs/package package (npm create svelte has an option to set this up for you).\n\nWhen you're creating an app, the contents of src/routes is the public-facing stuff; src/lib contains your app's internal library.\n\nA 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.\n\nRunning 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:\n\nAll 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, but we strongly recommend against it — people using your library might use TypeScript, for which they require these type definition files.\n\n@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 for migration instructions."},{"breadcrumbs":["Packaging","Anatomy of a package.json"],"href":"/docs/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."},{"breadcrumbs":["Packaging","Anatomy of a package.json","name"],"href":"/docs/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\n{\n \"name\": \"your-library\"\n}Read more about it here."},{"breadcrumbs":["Packaging","Anatomy of a package.json","license"],"href":"/docs/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\n{\n \"license\": \"MIT\"\n}Read more about it here. Note that you should also include a LICENSE file in your package."},{"breadcrumbs":["Packaging","Anatomy of a package.json","files"],"href":"/docs/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\n{\n \"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.\n\nRead more about it here."},{"breadcrumbs":["Packaging","Anatomy of a package.json","exports"],"href":"/docs/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 npm create svelte@latest, it's set to a single export, the package root:\n\n{\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"svelte\": \"./dist/index.js\"\n }\n }\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:\n\nThe types and svelte keys are export conditions. They tell tooling what file to import when they look up the your-library import:\n\nTypeScript 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.\n\nPrevious 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.\n\n\nYou 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\n{\n \"exports\": {\n \"./Foo.svelte\": {\n \"types\": \"./dist/Foo.svelte.d.ts\",\n \"svelte\": \"./dist/Foo.svelte\"\n }\n }\n}...and a consumer of your library could import the component like so:\n\nimport Foo from 'your-library/Foo.svelte';Beware that doing this will need additional care if you provide type definitions. Read more about the caveat here\n\n\nIn 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.\n\nRead more about exports here."},{"breadcrumbs":["Packaging","Anatomy of a package.json","svelte"],"href":"/docs/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\n{\n \"svelte\": \"./dist/index.js\"\n}"},{"breadcrumbs":["Packaging","Anatomy of a package.json","sideEffects"],"href":"/docs/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.\n\nSetting 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.\n\nMake sure that "sideEffects" is correctly set. 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\nThis will treat only the specified files as having side effects."},{"breadcrumbs":["Packaging","TypeScript"],"href":"/docs/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 npm create svelte@latest, this is automatically setup for the root export.\n\nIf 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:\n\nThe 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.\n\nThe 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\n{\n \"exports\": {\n \"./foo\": {\n \"types\": \"./dist/foo.d.ts\",\n \"svelte\": \"./dist/foo.js\"\n }\n },\n \"typesVersions\": {\n \">4.0\": {\n \"foo\": [\"./dist/foo.d.ts\"]\n }\n }\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": [..]).\n\nYou can read more about that feature here."},{"breadcrumbs":["Packaging","Best practices"],"href":"/docs/packaging#best-practices","content":"You should avoid using SvelteKit-specific modules like $app 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/stores, $app/navigation, etc. Writing your app in this more generic fashion will also make it easier to setup tools for testing, UI demos and so on.\n\nEnsure that you add aliases via svelte.config.js (not vite.config.js or tsconfig.json), so that they are processed by svelte-package.\n\nYou 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\n{\n \"exports\": {\n \".\": {\n \"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 },\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 }\n}"},{"breadcrumbs":["Packaging","Options"],"href":"/docs/packaging#options","content":"svelte-package accepts the following options:\n\n-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-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."},{"breadcrumbs":["Packaging","Publishing"],"href":"/docs/packaging#publishing","content":"To publish the generated package:\n\nnpm publish"},{"breadcrumbs":["Packaging","Caveats"],"href":"/docs/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:\n\n-import { something } from './something';\n+import { something } from './something/index.js';If you are using TypeScript, you need to import .ts files the same way, but using a .js file ending, not a .ts file ending. (This is a TypeScript design decision outside our control.) Setting "moduleResolution": "NodeNext" in your tsconfig.json or jsconfig.json will help you with this.\n\nAll files except Svelte files (preprocessed) and TypeScript files (transpiled to JavaScript) are copied across as-is."},{"breadcrumbs":["Performance"],"href":"/docs/performance","content":"Out of the box, SvelteKit does a lot of work to make your applications as performant as possible:\n\nCode-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 anticipated\n\nNevertheless, we can't (yet) eliminate all sources of slowness. To eke out maximum performance, you should be mindful of the following tips."},{"breadcrumbs":["Performance","Diagnosing issues"],"href":"/docs/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.\n\nYour browser also includes useful developer tools for analysing your site, whether deployed or running locally:\n\nChrome - Lighthouse, Network, and Performance devtools\nEdge - Lighthouse, Network, and Performance devtools\nFirefox - Network and Performance devtools\nSafari - enhancing the performance of your webpage\n\nNote 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."},{"breadcrumbs":["Performance","Diagnosing issues","Instrumenting"],"href":"/docs/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."},{"breadcrumbs":["Performance","Optimizing assets"],"href":"/docs/performance#optimizing-assets","content":""},{"breadcrumbs":["Performance","Optimizing assets","Images"],"href":"/docs/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-image package, detailed on the images page, for making this easier. Additionally, Lighthouse is useful for identifying the worst offenders."},{"breadcrumbs":["Performance","Optimizing assets","Videos"],"href":"/docs/performance#optimizing-assets-videos","content":"Video files can be very large, so extra care should be taken to ensure that they're optimized:\n\nCompress videos with tools such as Handbrake. Consider converting the videos to web-friendly formats such as .webm or .mp4.\nYou can lazy-load videos 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."},{"breadcrumbs":["Performance","Optimizing assets","Fonts"],"href":"/docs/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.\n\nYou can reduce the size of font files by subsetting your fonts."},{"breadcrumbs":["Performance","Reducing code size"],"href":"/docs/performance#reducing-code-size","content":""},{"breadcrumbs":["Performance","Reducing code size","Svelte version"],"href":"/docs/performance#reducing-code-size-svelte-version","content":"We recommend running the latest version of Svelte. Svelte 4 is smaller and faster than Svelte 3. (The Svelte 5 preview is much smaller and faster still, but we don't recommend that you upgrade to this version until it's production ready.)"},{"breadcrumbs":["Performance","Reducing code size","Packages"],"href":"/docs/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."},{"breadcrumbs":["Performance","Reducing code size","External scripts"],"href":"/docs/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.\n\nTo run third party scripts in a web worker (which avoids blocking the main thread), use Partytown's SvelteKit integration."},{"breadcrumbs":["Performance","Reducing code size","Selective loading"],"href":"/docs/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."},{"breadcrumbs":["Performance","Navigation"],"href":"/docs/performance#navigation","content":""},{"breadcrumbs":["Performance","Navigation","Preloading"],"href":"/docs/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."},{"breadcrumbs":["Performance","Navigation","Non-essential data"],"href":"/docs/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)."},{"breadcrumbs":["Performance","Navigation","Preventing waterfalls"],"href":"/docs/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.\n\nAsset waterfalls can occur in the browser when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding modulepreload 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 since they need to be handled manually.\nIf 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 where possible.\nServer load functions are also not immune to waterfalls (though they are much less costly since they rarely involve roundtrips with high latency). For example if you query a database to get the current user and then use that data to make a second query for a list of saved items, it will typically be more performant to issue a single query with a database join."},{"breadcrumbs":["Performance","Hosting"],"href":"/docs/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.\n\nEnsure 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."},{"breadcrumbs":["Performance","Further reading"],"href":"/docs/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."},{"breadcrumbs":["Images"],"href":"/docs/images","content":"Images can have a big impact on your app's performance. For best results, you should optimize them by doing the following:\n\ngenerate optimal formats like .avif and .webp\ncreate different sizes for different screens\nensure that assets can be cached effectively\n\nDoing this manually is tedious. There are a variety of techniques you can use, depending on your needs and preferences."},{"breadcrumbs":["Images","Vite's built-in handling"],"href":"/docs/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.\n\n<script>\n import logo from '$lib/assets/logo.png';\n</script>\n\n<img alt=\"The project logo\" src={logo} />"},{"breadcrumbs":["Images","@sveltejs/enhanced-img"],"href":"/docs/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.\n\nAs 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.\n\nWARNING: The @sveltejs/enhanced-img package is experimental. It uses pre-1.0 versioning and may introduce breaking changes with every minor version release."},{"breadcrumbs":["Images","@sveltejs/enhanced-img","Setup"],"href":"/docs/images#sveltejs-enhanced-img-setup","content":"Install:\n\nnpm install --save-dev @sveltejs/enhanced-imgAdjust vite.config.js:\n\nimport { sveltekit } from '@sveltejs/kit/vite';\n+import { enhancedImages } from '@sveltejs/enhanced-img';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n plugins: [\n+\t\tenhancedImages(),\n sveltekit()\n ]\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."},{"breadcrumbs":["Images","@sveltejs/enhanced-img","Basic usage"],"href":"/docs/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:\n\n<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.\n\nYou 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.\n\nIf you wish to add styles to your <enhanced:img>, you should add a class and target that."},{"breadcrumbs":["Images","@sveltejs/enhanced-img","Dynamically choosing an image"],"href":"/docs/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.\n\n<script>\n import 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:\n\n<script>\n const imageModules = import.meta.glob(\n '/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',\n {\n eager: true,\n query: {\n enhanced: true\n }\n }\n )\n</script>\n\n{#each Object.entries(imageModules) as [_path, module]}\n <enhanced:img src={module.default} alt=\"some alt text\" />\n{/each}"},{"breadcrumbs":["Images","@sveltejs/enhanced-img","Intrinsic Dimensions"],"href":"/docs/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:\n\n<style>\n .hero-image img {\n width: var(--size);\n height: auto;\n }\n</style>"},{"breadcrumbs":["Images","@sveltejs/enhanced-img","`srcset` and `sizes`"],"href":"/docs/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:\n\n<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.\n\nThe 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:\n\n<enhanced:img\n src=\"./image.png?w=1280;640;400\"\n sizes=\"(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."},{"breadcrumbs":["Images","@sveltejs/enhanced-img","Per-image transforms"],"href":"/docs/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:\n\n<enhanced:img src=\"./path/to/your/image.jpg?blur=15\" alt=\"An alt text\" />See the imagetools repo for the full list of directives."},{"breadcrumbs":["Images","Loading images dynamically from a CDN"],"href":"/docs/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.\n\nUsing 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.\n\nCDNs 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."},{"breadcrumbs":["Images","Best practices"],"href":"/docs/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) image, set fetchpriority="high" loading="eager" 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). 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."},{"breadcrumbs":["Accessibility"],"href":"/docs/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.\n\nHere'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.\n\nWe 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."},{"breadcrumbs":["Accessibility","Route announcements"],"href":"/docs/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.\n\nSince 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.\n\nBecause 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:\n\n<!--- file: src/routes/+page.svelte --->\n<svelte:head>\n <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."},{"breadcrumbs":["Accessibility","Focus management"],"href":"/docs/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.\n\nTo 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.\n\nIf you want to customize SvelteKit's focus management, you can use the afterNavigate hook:\n\nimport { afterNavigate } from '$app/navigation';\n\nafterNavigate(() => {\n /** @type {HTMLElement | null} */\n const to_focus = document.querySelector('.focus-me');\n to_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."},{"breadcrumbs":["Accessibility","The \"lang\" attribute"],"href":"/docs/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\nIf 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\n/** @type {import('@sveltejs/kit').Handle} */\nexport function handle({ event, resolve }) {\n return resolve(event, {\n transformPageChunk: ({ html }) => html.replace('%lang%', get_lang(event))\n });\n}"},{"breadcrumbs":["Accessibility","Further reading"],"href":"/docs/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:\n\nMDN Web Docs: Accessibility\nThe A11y Project\nHow to Meet WCAG (Quick Reference)"},{"breadcrumbs":["SEO"],"href":"/docs/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."},{"breadcrumbs":["SEO","Out of the box"],"href":"/docs/seo#out-of-the-box","content":""},{"breadcrumbs":["SEO","Out of the box","SSR"],"href":"/docs/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.\n\nSvelteKit's rendering is highly configurable and you can implement dynamic rendering if necessary. It's not generally recommended, since SSR has other benefits beyond SEO."},{"breadcrumbs":["SEO","Out of the box","Performance"],"href":"/docs/seo#out-of-the-box-performance","content":"Signals such as Core Web Vitals impact search engine ranking. Because Svelte and SvelteKit introduce minimal overhead, it's easier to build high performance sites. You can test your site's performance using Google's PageSpeed Insights or Lighthouse. Read the performance page for more details."},{"breadcrumbs":["SEO","Out of the box","Normalized URLs"],"href":"/docs/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."},{"breadcrumbs":["SEO","Manual setup"],"href":"/docs/seo#manual-setup","content":""},{"breadcrumbs":["SEO","Manual setup","<title> and <meta>"],"href":"/docs/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.\n\nA common pattern is to return SEO-related data from page load functions, then use it (as $page.data) in a <svelte:head> in your root layout."},{"breadcrumbs":["SEO","Manual setup","Sitemaps"],"href":"/docs/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:"},{"breadcrumbs":["SEO","Manual setup","AMP"],"href":"/docs/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\n...disabling csr in your root +layout.js/+layout.server.js...\n\n...adding amp to your app.html\n\n<html amp>\n......and transforming the HTML using transformPageChunk along with transform imported from @sveltejs/amp:\n\nTo prevent shipping any unused CSS as a result of transforming the page to amp, we can use dropcss:\n\nIt'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."},{"breadcrumbs":["Configuration"],"href":"/docs/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.\n\nimport adapter from '@sveltejs/adapter-auto';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n kit: {\n adapter: adapter()\n }\n};\n\nexport default config;\ninterface Config {/*…*/}\n// @noErrors\ncompilerOptions?: CompileOptions;\n\n\ndefault\n {}\n\n\nOptions passed to svelte.compile.\n\n\n\n// @noErrors\nextensions?: string[];\n\n\ndefault\n [".svelte"]\n\n\nList of file extensions that should be treated as Svelte files.\n\n\n\n// @noErrors\nkit?: KitConfig;\nSvelteKit options\n\n\n\n// @noErrors\npreprocess?: any;\nPreprocessor options, if any. Preprocessing can alternatively also be done through Vite's preprocessor capabilities.\n\n\n\n// @noErrors\nvitePlugin?: PluginOptions;\nvite-plugin-svelte plugin options.\n\n\n\n// @noErrors\n[key: string]: any;\nAny additional options required by tooling that integrates with Svelte.\n\n\nThe kit property configures SvelteKit, and can have the following properties:\n\nadapter\n\n\ndefault\n undefined\n\n\nYour adapter is run when executing vite build. It determines how the output is converted for different platforms.\n\n\n\nalias\n\n\ndefault\n {}\n\n\nAn object containing zero or more aliases used to replace values in import statements. These aliases are automatically passed to Vite and TypeScript.\n\nThe built-in $lib alias is controlled by config.kit.files.lib as it is used for packaging.\n\n\nYou will need to run npm run dev to have SvelteKit automatically generate the required alias configuration in jsconfig.json or tsconfig.json.\n\n\n\n\nappDir\n\n\ndefault\n "_app"\n\n\nThe directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes.\n\nIf paths.assets is specified, there will be two app directories — ${paths.assets}/${appDir} and ${paths.base}/${appDir}.\n\n\n\ncsp\n\n\nContent 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...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.\n\nTo 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%">).\n\nWhen 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).\n\nWhen 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.\n\n\nNote that most Svelte transitions 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.\n\n\nIf 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\n\n// @noErrors\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\n\n// @noErrors\ndirectives?: CspDirectives;\nDirectives that will be added to Content-Security-Policy headers.\n\n\n// @noErrors\nreportOnly?: CspDirectives;\nDirectives that will be added to Content-Security-Policy-Report-Only headers.\n\n\n\ncsrf\n\n\nProtection against cross-site request forgery (CSRF) attacks.\n\n\n\n// @noErrors\ncheckOrigin?: boolean;\n\n\ndefault\n true\n\n\nWhether to check the incoming origin header for POST, PUT, PATCH, or DELETE form submissions and verify that it matches the server's origin.\n\nTo 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\n\n\nembedded\n\n\ndefault\n false\n\n\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).\n\n\n\nenv\n\n\nEnvironment variable configuration\n\n\n\n// @noErrors\ndir?: string;\n\n\ndefault\n "."\n\n\nThe directory to search for .env files.\n\n\n// @noErrors\npublicPrefix?: string;\n\n\ndefault\n "PUBLIC_"\n\n\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\n\n// @noErrors\nprivatePrefix?: string;\n\n\ndefault\n ""\n\n\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.\n\n\n\nfiles\n\n\nWhere to find various files within your project.\n\n\n\n// @noErrors\nassets?: string;\n\n\ndefault\n "static"\n\n\na place to put static files that should have stable URLs and undergo no processing, such as favicon.ico or manifest.json\n\n\n// @noErrors\nhooks?: {/*…*/}\n\n// @noErrors\nclient?: string;\n\n\ndefault\n "src/hooks.client"\n\n\nThe location of your client hooks.\n\n\n// @noErrors\nserver?: string;\n\n\ndefault\n "src/hooks.server"\n\n\nThe location of your server hooks.\n\n\n// @noErrors\nuniversal?: string;\n\n\ndefault\n "src/hooks"\n\n\nThe location of your universal hooks.\n\n\n// @noErrors\nlib?: string;\n\n\ndefault\n "src/lib"\n\n\nyour app's internal library, accessible throughout the codebase as $lib\n\n\n// @noErrors\nparams?: string;\n\n\ndefault\n "src/params"\n\n\na directory containing parameter matchers\n\n\n// @noErrors\nroutes?: string;\n\n\ndefault\n "src/routes"\n\n\nthe files that define the structure of your app (see Routing)\n\n\n// @noErrors\nserviceWorker?: string;\n\n\ndefault\n "src/service-worker"\n\n\nthe location of your service worker's entry point (see Service workers)\n\n\n// @noErrors\nappTemplate?: string;\n\n\ndefault\n "src/app.html"\n\n\nthe location of the template for HTML responses\n\n\n// @noErrors\nerrorTemplate?: string;\n\n\ndefault\n "src/error.html"\n\n\nthe location of the template for fallback error responses\n\n\n\ninlineStyleThreshold\n\n\ndefault\n 0\n\n\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 and smaller than this value are merged and inlined in a <style> block.\n\nThis results in fewer initial requests and can improve your First Contentful Paint score. However, it generates larger HTML output and reduces the effectiveness of browser caches. Use it advisedly.\n\n\n\n\nmoduleExtensions\n\n\ndefault\n [".js", ".ts"]\n\n\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.\n\n\n\noutDir\n\n\ndefault\n ".svelte-kit"\n\n\nThe directory that SvelteKit writes files to during dev and build. You should exclude this directory from version control.\n\n\n\noutput\n\n\nOptions related to the build output format\n\n\n\n// @noErrors\npreloadStrategy?: 'modulepreload' | 'preload-js' | 'preload-mjs';\n\n\ndefault\n "modulepreload"\n\n\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:\n\nmodulepreload - 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.\npreload-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.\npreload-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\n\n\npaths\n\n\n\n\n// @noErrors\nassets?: '' | `http://${string}` | `https://${string}`;\n\n\ndefault\n ""\n\n\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\n\n// @noErrors\nbase?: '' | `/${string}`;\n\n\ndefault\n ""\n\n\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\n\n// @noErrors\nrelative?: boolean;\n\n\ndefault\n true\n\n\nWhether to use relative asset paths.\n\nIf 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 URL\n\nSingle-page app fallback pages will always use absolute paths, regardless of this setting.\n\nIf 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.\n\nIn 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.\n\n\n\nprerender\n\n\nSee Prerendering.\n\n\n\n// @noErrors\nconcurrency?: number;\n\n\ndefault\n 1\n\n\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\n\n// @noErrors\ncrawl?: boolean;\n\n\ndefault\n true\n\n\nWhether SvelteKit should find pages to prerender by following links from entries.\n\n\n// @noErrors\nentries?: Array<'*' | `/${string}`>;\n\n\ndefault\n ["*"]\n\n\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\n\n// @noErrors\nhandleHttpError?: PrerenderHttpErrorHandlerValue;\n\n\ndefault\n "fail"\n\n\nHow to respond to HTTP errors encountered while prerendering the app.\n\n'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\n// @noErrors\nhandleMissingId?: PrerenderMissingIdHandlerValue;\n\n\ndefault\n "fail"\n\n\nHow to respond when hash links from one prerendered page to another don't correspond to an id on the destination page.\n\n'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\n\n// @noErrors\nhandleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;\n\n\ndefault\n "fail"\n\n\nHow to respond when an entry generated by the entries export doesn't match the route it was generated from.\n\n'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\n\n// @noErrors\norigin?: string;\n\n\ndefault\n "http://sveltekit-prerender"\n\n\nThe value of url.origin during prerendering; useful if it is included in rendered content.\n\n\n\nserviceWorker\n\n\n\n\n// @noErrors\nregister?: boolean;\n\n\ndefault\n true\n\n\nWhether to automatically register the service worker, if it exists.\n\n\n// @noErrors\nfiles?(filepath: string): boolean;\n\n\ndefault\n (filename) => !/\\.DS_Store/.test(filename)\n\n\nDetermine which files in your static directory will be available in $service-worker.files.\n\n\n\ntypescript\n\n\n\n\n// @noErrors\nconfig?: (config: Record<string, any>) => Record<string, any> | void;\n\n\ndefault\n (config) => config\n\n\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.\n\n\n\nversion\n\n\nClient-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\nIf you set pollInterval to a non-zero value, SvelteKit will poll for new versions in the background and set the value of the updated store to true when it detects one.\n\n\n\n// @noErrors\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.\n\nFor example, to use the current commit hash, you could do use git rev-parse HEAD:\n\n\n// @noErrors\npollInterval?: number;\n\n\ndefault\n 0\n\n\nThe interval in milliseconds to poll for version changes. If this is 0, no polling occurs."},{"breadcrumbs":["Command Line Interface"],"href":"/docs/cli","content":"SvelteKit projects use Vite, meaning you'll mostly use its CLI (albeit via npm run dev/build/preview scripts):\n\nvite dev — start a development server\nvite build — build a production version of your app\nvite preview — run the production version locally\n\nHowever SvelteKit includes its own CLI for initialising your project:"},{"breadcrumbs":["Command Line Interface","svelte-kit sync"],"href":"/docs/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."},{"breadcrumbs":["Modules"],"href":"/docs/modules","content":"SvelteKit makes a number of modules available to your application."},{"breadcrumbs":["Modules","$app/environment"],"href":"/docs/modules#$app-environment","content":"// @noErrors\nimport { browser, building, dev, version } from '$app/environment';"},{"breadcrumbs":["Modules","$app/environment","browser"],"href":"/docs/modules#$app-environment-browser","content":"true if the app is running in the browser.\n\n\n// @noErrors\nconst browser: boolean;"},{"breadcrumbs":["Modules","$app/environment","building"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nconst building: boolean;"},{"breadcrumbs":["Modules","$app/environment","dev"],"href":"/docs/modules#$app-environment-dev","content":"Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.\n\n\n// @noErrors\nconst dev: boolean;"},{"breadcrumbs":["Modules","$app/environment","version"],"href":"/docs/modules#$app-environment-version","content":"The value of config.kit.version.name.\n\n\n// @noErrors\nconst version: string;"},{"breadcrumbs":["Modules","$app/forms"],"href":"/docs/modules#$app-forms","content":"// @noErrors\nimport { applyAction, deserialize, enhance } from '$app/forms';"},{"breadcrumbs":["Modules","$app/forms","applyAction"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nfunction applyAction<\n Success extends Record<string, unknown> | undefined,\n Failure extends Record<string, unknown> | undefined\n>(\n result: import('@sveltejs/kit').ActionResult<\n Success,\n Failure\n >\n): Promise<void>;"},{"breadcrumbs":["Modules","$app/forms","deserialize"],"href":"/docs/modules#$app-forms-deserialize","content":"Use this function to deserialize the response from a form submission.\nUsage:\n\n\n// @noErrors\nfunction deserialize<\n Success extends Record<string, unknown> | undefined,\n Failure extends Record<string, unknown> | undefined\n>(\n result: string\n): import('@sveltejs/kit').ActionResult<Success, Failure>;"},{"breadcrumbs":["Modules","$app/forms","enhance"],"href":"/docs/modules#$app-forms-enhance","content":"This action enhances a <form> element that otherwise would work without JavaScript.\n\nThe 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.\n\nIf this function or its return value isn't set, it\n\nfalls 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 error\n\nIf you provide a custom function with a callback and want to use the default behavior, invoke update in your callback.\n\n\n// @noErrors\nfunction enhance<\n Success extends Record<string, unknown> | undefined,\n Failure extends Record<string, unknown> | undefined\n>(\n form_element: HTMLFormElement,\n submit?: import('@sveltejs/kit').SubmitFunction<\n Success,\n Failure\n >\n): {\n destroy(): void;\n};"},{"breadcrumbs":["Modules","$app/navigation"],"href":"/docs/modules#$app-navigation","content":"// @noErrors\nimport {\n afterNavigate,\n beforeNavigate,\n disableScrollHandling,\n goto,\n invalidate,\n invalidateAll,\n onNavigate,\n preloadCode,\n preloadData,\n pushState,\n replaceState\n} from '$app/navigation';"},{"breadcrumbs":["Modules","$app/navigation","afterNavigate"],"href":"/docs/modules#$app-navigation-afternavigate","content":"A lifecycle function that runs the supplied callback when the current component mounts, and also whenever we navigate to a new URL.\n\nafterNavigate must be called during a component initialization. It remains active as long as the component is mounted.\n\n\n// @noErrors\nfunction afterNavigate(\n callback: (\n navigation: import('@sveltejs/kit').AfterNavigate\n ) => void\n): void;"},{"breadcrumbs":["Modules","$app/navigation","beforeNavigate"],"href":"/docs/modules#$app-navigation-beforenavigate","content":"A navigation interceptor that triggers before we navigate to a new URL, whether by clicking a link, calling goto(...), or using the browser back/forward controls.\n\nCalling 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.\n\nWhen 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.\n\nIf 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.\n\nbeforeNavigate must be called during a component initialization. It remains active as long as the component is mounted.\n\n\n// @noErrors\nfunction beforeNavigate(\n callback: (\n navigation: import('@sveltejs/kit').BeforeNavigate\n ) => void\n): void;"},{"breadcrumbs":["Modules","$app/navigation","disableScrollHandling"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nfunction disableScrollHandling(): void;"},{"breadcrumbs":["Modules","$app/navigation","goto"],"href":"/docs/modules#$app-navigation-goto","content":"Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified url.\nFor external URLs, use window.location = url instead of calling goto(url).\n\n\n// @noErrors\nfunction goto(\n url: string | URL,\n opts?:\n | {\n replaceState?: boolean | undefined;\n noScroll?: boolean | undefined;\n keepFocus?: boolean | undefined;\n invalidateAll?: boolean | undefined;\n state?: App.PageState | undefined;\n }\n | undefined\n): Promise<void>;"},{"breadcrumbs":["Modules","$app/navigation","invalidate"],"href":"/docs/modules#$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.\n\nIf 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.\n\nThe 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.\n\n// Example: Match '/path' regardless of the query parameters\nimport { invalidate } from '$app/navigation';\n\ninvalidate((url) => url.pathname === '/path');\n// @noErrors\nfunction invalidate(\n resource: string | URL | ((url: URL) => boolean)\n): Promise<void>;"},{"breadcrumbs":["Modules","$app/navigation","invalidateAll"],"href":"/docs/modules#$app-navigation-invalidateall","content":"Causes all load functions belonging to the currently active page to re-run. Returns a Promise that resolves when the page is subsequently updated.\n\n\n// @noErrors\nfunction invalidateAll(): Promise<void>;"},{"breadcrumbs":["Modules","$app/navigation","onNavigate"],"href":"/docs/modules#$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.\n\nIf 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.\n\nIf a function (or a Promise that resolves to a function) is returned from the callback, it will be called once the DOM has updated.\n\nonNavigate must be called during a component initialization. It remains active as long as the component is mounted.\n\n\n// @noErrors\nfunction onNavigate(\n callback: (\n navigation: import('@sveltejs/kit').OnNavigate\n ) => MaybePromise<(() => void) | void>\n): void;"},{"breadcrumbs":["Modules","$app/navigation","preloadCode"],"href":"/docs/modules#$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.\n\nYou 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).\n\nUnlike preloadData, this won't call load functions.\nReturns a Promise that resolves when the modules have been imported.\n\n\n// @noErrors\nfunction preloadCode(pathname: string): Promise<void>;"},{"breadcrumbs":["Modules","$app/navigation","preloadData"],"href":"/docs/modules#$app-navigation-preloaddata","content":"Programmatically preloads the given page, which means\n\nensuring that the code for the page is loaded, and\ncalling the page's load function with the appropriate options.\n\nThis 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.\n\n\n// @noErrors\nfunction preloadData(href: string): Promise<\n | {\n type: 'loaded';\n status: number;\n data: Record<string, any>;\n }\n | {\n type: 'redirect';\n location: string;\n }\n>;"},{"breadcrumbs":["Modules","$app/navigation","pushState"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nfunction pushState(\n url: string | URL,\n state: App.PageState\n): void;"},{"breadcrumbs":["Modules","$app/navigation","replaceState"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nfunction replaceState(\n url: string | URL,\n state: App.PageState\n): void;"},{"breadcrumbs":["Modules","$app/paths"],"href":"/docs/modules#$app-paths","content":"// @noErrors\nimport { assets, base, resolveRoute } from '$app/paths';"},{"breadcrumbs":["Modules","$app/paths","assets"],"href":"/docs/modules#$app-paths-assets","content":"An absolute path that matches config.kit.paths.assets.\n\nIf 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.\n\n\n\n// @noErrors\nlet assets:\n | ''\n | `https://${string}`\n | `http://${string}`\n | '/_svelte_kit_assets';"},{"breadcrumbs":["Modules","$app/paths","base"],"href":"/docs/modules#$app-paths-base","content":"A string that matches config.kit.paths.base.\n\nExample usage: <a href="{base}/your-page">Link</a>\n\n\n// @noErrors\nlet base: '' | `/${string}`;"},{"breadcrumbs":["Modules","$app/paths","resolveRoute"],"href":"/docs/modules#$app-paths-resolveroute","content":"Populate a route ID with params to resolve a pathname.\n\n\n// @noErrors\nfunction resolveRoute(\n id: string,\n params: Record<string, string | undefined>\n): string;"},{"breadcrumbs":["Modules","$app/server"],"href":"/docs/modules#$app-server","content":"// @noErrors\nimport { read } from '$app/server';"},{"breadcrumbs":["Modules","$app/server","read"],"href":"/docs/modules#$app-server-read","content":"Read the contents of an imported asset from the filesystem\n\n\n// @noErrors\nfunction read(asset: string): Response;"},{"breadcrumbs":["Modules","$app/stores"],"href":"/docs/modules#$app-stores","content":"// @noErrors\nimport { getStores, navigating, page, updated } from '$app/stores';"},{"breadcrumbs":["Modules","$app/stores","getStores"],"href":"/docs/modules#$app-stores-getstores","content":"// @noErrors\nfunction getStores(): {\n page: typeof page;\n\n navigating: typeof navigating;\n\n updated: typeof updated;\n};"},{"breadcrumbs":["Modules","$app/stores","navigating"],"href":"/docs/modules#$app-stores-navigating","content":"A 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.\n\nOn the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\n\n\n// @noErrors\nconst navigating: import('svelte/store').Readable<\n import('@sveltejs/kit').Navigation | null\n>;"},{"breadcrumbs":["Modules","$app/stores","page"],"href":"/docs/modules#$app-stores-page","content":"A readable store whose value contains page data.\n\nOn the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\n\n\n// @noErrors\nconst page: import('svelte/store').Readable<\n import('@sveltejs/kit').Page\n>;"},{"breadcrumbs":["Modules","$app/stores","updated"],"href":"/docs/modules#$app-stores-updated","content":"A 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.\n\nOn the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.\n\n\n// @noErrors\nconst updated: import('svelte/store').Readable<boolean> & {\n check(): Promise<boolean>;\n};"},{"breadcrumbs":["Modules","$env/dynamic/private"],"href":"/docs/modules#$env-dynamic-private","content":"This module provides access to runtime environment variables, as 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. This module only includes variables that do not begin with config.kit.env.publicPrefix and do start with config.kit.env.privatePrefix (if configured).\n\nThis module cannot be imported into client-side code.\n\nDynamic environment variables cannot be used during prerendering.\n\nimport { env } from '$env/dynamic/private';\nconsole.log(env.DEPLOYMENT_SPECIFIC_VARIABLE);In dev, $env/dynamic always includes environment variables from .env. In prod, this behavior will depend on your adapter."},{"breadcrumbs":["Modules","$env/dynamic/public"],"href":"/docs/modules#$env-dynamic-public","content":"Similar to $env/dynamic/private, but only includes variables that begin with config.kit.env.publicPrefix (which defaults to PUBLIC_), and can therefore safely be exposed to client-side code.\n\nNote that public dynamic environment variables must all be sent from the server to the client, causing larger network requests — when possible, use $env/static/public instead.\n\nDynamic environment variables cannot be used during prerendering.\n\nimport { env } from '$env/dynamic/public';\nconsole.log(env.PUBLIC_DEPLOYMENT_SPECIFIC_VARIABLE);"},{"breadcrumbs":["Modules","$env/static/private"],"href":"/docs/modules#$env-static-private","content":"Environment variables loaded by Vite from .env files and process.env. Like $env/dynamic/private, this module cannot be imported into client-side code. This module only includes variables that do not begin with config.kit.env.publicPrefix and do start with config.kit.env.privatePrefix (if configured).\n\nUnlike $env/dynamic/private, the values exported from this module are statically injected into your bundle at build time, enabling optimisations like dead code elimination.\n\nimport { API_KEY } from '$env/static/private';Note that all environment variables referenced in your code should be declared (for example in an .env file), even if they don't have a value until the app is deployed:\n\nMY_FEATURE_FLAG=\"\"You can override .env values from the command line like so:\n\nMY_FEATURE_FLAG=\"enabled\" npm run dev"},{"breadcrumbs":["Modules","$env/static/public"],"href":"/docs/modules#$env-static-public","content":"Similar to $env/static/private, except that it only includes environment variables that begin with config.kit.env.publicPrefix (which defaults to PUBLIC_), and can therefore safely be exposed to client-side code.\n\nValues are replaced statically at build time.\n\nimport { PUBLIC_BASE_URL } from '$env/static/public';"},{"breadcrumbs":["Modules","$lib"],"href":"/docs/modules#$lib","content":"This is a simple alias to src/lib, or whatever directory is specified as config.kit.files.lib. It allows you to access common components and utility modules without ../../../../ nonsense."},{"breadcrumbs":["Modules","$lib","`$lib/server`"],"href":"/docs/modules#$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."},{"breadcrumbs":["Modules","$service-worker"],"href":"/docs/modules#$service-worker","content":"// @noErrors\nimport { base, build, files, prerendered, version } from '$service-worker';This module is only available to service workers."},{"breadcrumbs":["Modules","$service-worker","base"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nconst base: string;"},{"breadcrumbs":["Modules","$service-worker","build"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nconst build: string[];"},{"breadcrumbs":["Modules","$service-worker","files"],"href":"/docs/modules#$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\n\n\n// @noErrors\nconst files: string[];"},{"breadcrumbs":["Modules","$service-worker","prerendered"],"href":"/docs/modules#$service-worker-prerendered","content":"An array of pathnames corresponding to prerendered pages and endpoints.\nDuring development, this is an empty array.\n\n\n// @noErrors\nconst prerendered: string[];"},{"breadcrumbs":["Modules","$service-worker","version"],"href":"/docs/modules#$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.\n\n\n// @noErrors\nconst version: string;"},{"breadcrumbs":["Modules","@sveltejs/kit"],"href":"/docs/modules#sveltejs-kit","content":"// @noErrors\nimport {\n VERSION,\n error,\n fail,\n isHttpError,\n isRedirect,\n json,\n redirect,\n text\n} from '@sveltejs/kit';"},{"breadcrumbs":["Modules","@sveltejs/kit","VERSION"],"href":"/docs/modules#sveltejs-kit-version","content":"// @noErrors\nconst VERSION: string;"},{"breadcrumbs":["Modules","@sveltejs/kit","error"],"href":"/docs/modules#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.\n\n\n// @noErrors\nfunction error(status: number, body: App.Error): never;"},{"breadcrumbs":["Modules","@sveltejs/kit","error"],"href":"/docs/modules#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.\n\n\n// @noErrors\nfunction error(\n status: number,\n body?: {\n message: string;\n } extends App.Error\n ? App.Error | string | undefined\n : never\n): never;"},{"breadcrumbs":["Modules","@sveltejs/kit","fail"],"href":"/docs/modules#sveltejs-kit-fail","content":"Create an ActionFailure object.\n\n\n// @noErrors\nfunction fail(status: number): ActionFailure<undefined>;"},{"breadcrumbs":["Modules","@sveltejs/kit","fail"],"href":"/docs/modules#sveltejs-kit-fail","content":"Create an ActionFailure object.\n\n\n// @noErrors\nfunction fail<\n T extends Record<string, unknown> | undefined = undefined\n>(status: number, data: T): ActionFailure<T>;"},{"breadcrumbs":["Modules","@sveltejs/kit","isHttpError"],"href":"/docs/modules#sveltejs-kit-ishttperror","content":"Checks whether this is an error thrown by error.\n\n\n// @noErrors\nfunction isHttpError<T extends number>(\n e: unknown,\n status?: T | undefined\n): e is HttpError_1 & {\n status: T extends undefined ? never : T;\n};"},{"breadcrumbs":["Modules","@sveltejs/kit","isRedirect"],"href":"/docs/modules#sveltejs-kit-isredirect","content":"Checks whether this is a redirect thrown by redirect.\n\n\n// @noErrors\nfunction isRedirect(e: unknown): e is Redirect_1;"},{"breadcrumbs":["Modules","@sveltejs/kit","json"],"href":"/docs/modules#sveltejs-kit-json","content":"Create a JSON Response object from the supplied data.\n\n\n// @noErrors\nfunction json(\n data: any,\n init?: ResponseInit | undefined\n): Response;"},{"breadcrumbs":["Modules","@sveltejs/kit","redirect"],"href":"/docs/modules#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.\n\n\n// @noErrors\nfunction redirect(\n status:\n | 300\n | 301\n | 302\n | 303\n | 304\n | 305\n | 306\n | 307\n | 308\n | ({} & number),\n location: string | URL\n): never;"},{"breadcrumbs":["Modules","@sveltejs/kit","text"],"href":"/docs/modules#sveltejs-kit-text","content":"Create a Response object from the supplied body.\n\n\n// @noErrors\nfunction text(\n body: string,\n init?: ResponseInit | undefined\n): Response;"},{"breadcrumbs":["Modules","@sveltejs/kit/hooks"],"href":"/docs/modules#sveltejs-kit-hooks","content":"// @noErrors\nimport { sequence } from '@sveltejs/kit/hooks';"},{"breadcrumbs":["Modules","@sveltejs/kit/hooks","sequence"],"href":"/docs/modules#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:\n\ntransformPageChunk is applied in reverse order and merged\npreload is applied in forward order, the first option "wins" and no preload options after it are called\nfilterSerializedResponseHeaders behaves the same as preload\n\nThe example above would print:\n\nfirst pre-processing\nfirst preload\nsecond pre-processing\nsecond filterSerializedResponseHeaders\nsecond transform\nfirst transform\nsecond post-processing\nfirst post-processing\n// @noErrors\nfunction sequence(\n ...handlers: import('@sveltejs/kit').Handle[]\n): import('@sveltejs/kit').Handle;"},{"breadcrumbs":["Modules","@sveltejs/kit/node"],"href":"/docs/modules#sveltejs-kit-node","content":"// @noErrors\nimport {\n createReadableStream,\n getRequest,\n setResponse\n} from '@sveltejs/kit/node';"},{"breadcrumbs":["Modules","@sveltejs/kit/node","createReadableStream"],"href":"/docs/modules#sveltejs-kit-node-createreadablestream","content":"Converts a file on disk to a readable stream\n\n\n// @noErrors\nfunction createReadableStream(file: string): ReadableStream;"},{"breadcrumbs":["Modules","@sveltejs/kit/node","getRequest"],"href":"/docs/modules#sveltejs-kit-node-getrequest","content":"// @noErrors\nfunction getRequest({\n request,\n base,\n bodySizeLimit\n}: {\n request: import('http').IncomingMessage;\n base: string;\n bodySizeLimit?: number;\n}): Promise<Request>;"},{"breadcrumbs":["Modules","@sveltejs/kit/node","setResponse"],"href":"/docs/modules#sveltejs-kit-node-setresponse","content":"// @noErrors\nfunction setResponse(\n res: import('http').ServerResponse,\n response: Response\n): Promise<void>;"},{"breadcrumbs":["Modules","@sveltejs/kit/node/polyfills"],"href":"/docs/modules#sveltejs-kit-node-polyfills","content":"// @noErrors\nimport { installPolyfills } from '@sveltejs/kit/node/polyfills';"},{"breadcrumbs":["Modules","@sveltejs/kit/node/polyfills","installPolyfills"],"href":"/docs/modules#sveltejs-kit-node-polyfills-installpolyfills","content":"Make various web APIs available as globals:\n\ncrypto\nFile\n\n\n// @noErrors\nfunction installPolyfills(): void;"},{"breadcrumbs":["Modules","@sveltejs/kit/vite"],"href":"/docs/modules#sveltejs-kit-vite","content":"// @noErrors\nimport { sveltekit } from '@sveltejs/kit/vite';"},{"breadcrumbs":["Modules","@sveltejs/kit/vite","sveltekit"],"href":"/docs/modules#sveltejs-kit-vite-sveltekit","content":"Returns the SvelteKit Vite plugins.\n\n\n// @noErrors\nfunction sveltekit(): Promise<import('vite').Plugin[]>;"},{"breadcrumbs":["Types"],"href":"/docs/types","content":""},{"breadcrumbs":["Types","Public types"],"href":"/docs/types#public-types","content":"The following types can be imported from @sveltejs/kit:"},{"breadcrumbs":["Types","Public types","Action"],"href":"/docs/types#public-types-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.\n\n\ntype Action<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n OutputData extends Record<string, any> | void = Record<\n string,\n any\n > | void,\n RouteId extends string | null = string | null\n> = (\n event: RequestEvent<Params, RouteId>\n) => MaybePromise<OutputData>;"},{"breadcrumbs":["Types","Public types","ActionFailure"],"href":"/docs/types#public-types-actionfailure","content":"interface ActionFailure<\n T extends Record<string, unknown> | undefined = undefined\n> {/*…*/}\nstatus: number;\n\n\ndata: T;\n\n\n[uniqueSymbol]: true;"},{"breadcrumbs":["Types","Public types","ActionResult"],"href":"/docs/types#public-types-actionresult","content":"When calling a form action via fetch, the response will be one of these shapes.\n\n<form method=\"post\" use:enhance={() => {\n return ({ result }) => {\n // result is of type ActionResult\n };\n}}\ntype ActionResult<\n Success extends\n | Record<string, unknown>\n | undefined = Record<string, any>,\n Failure extends\n | Record<string, unknown>\n | undefined = Record<string, any>\n> =\n | { type: 'success'; status: number; data?: Success }\n | { type: 'failure'; status: number; data?: Failure }\n | { type: 'redirect'; status: number; location: string }\n | { type: 'error'; status?: number; error: any };"},{"breadcrumbs":["Types","Public types","Actions"],"href":"/docs/types#public-types-actions","content":"Shape of the export const actions = {..} object in +page.server.js.\nSee form actions for more information.\n\n\ntype Actions<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n OutputData extends Record<string, any> | void = Record<\n string,\n any\n > | void,\n RouteId extends string | null = string | null\n> = Record<string, Action<Params, OutputData, RouteId>>;"},{"breadcrumbs":["Types","Public types","Adapter"],"href":"/docs/types#public-types-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.\n\n\ninterface Adapter {/*…*/}\nname: string;\nThe name of the adapter, using for logging. Will typically correspond to the package name.\n\n\n\nadapt(builder: Builder): MaybePromise<void>;\n\nbuilder An object provided by SvelteKit that contains methods for adapting the app\n\n\nThis function is called after SvelteKit has built your app.\n\n\n\nsupports?: {/*…*/}\nChecks called during dev and build to determine whether specific features will work in production with this adapter\n\n\nread?: (details: { config: any; route: { id: string } }) => boolean;\n\nconfig The merged route config\n\n\nTest support for read from $app/server\n\n\n\nemulate?(): MaybePromise<Emulator>;\nCreates an Emulator, which allows the adapter to influence the environment\nduring dev, build and prerendering"},{"breadcrumbs":["Types","Public types","AfterNavigate"],"href":"/docs/types#public-types-afternavigate","content":"The argument passed to afterNavigate callbacks.\n\n\ninterface AfterNavigate extends Omit<Navigation, 'type'> {/*…*/}\ntype: Exclude<NavigationType, 'leave'>;\nThe type of navigation:\n\nenter: The app has hydrated\nform: The user submitted a <form>\nlink: Navigation was triggered by a link click\ngoto: Navigation was triggered by a goto(...) call or a redirect\npopstate: Navigation was triggered by back/forward navigation\n\n\n\nwillUnload: false;\nSince afterNavigate callbacks are called after a navigation completes, they will never be called with a navigation that unloads the page."},{"breadcrumbs":["Types","Public types","AwaitedActions"],"href":"/docs/types#public-types-awaitedactions","content":"type AwaitedActions<\n T extends Record<string, (...args: any) => any>\n> = OptionalUnion<\n {\n [Key in keyof T]: UnpackValidationError<\n Awaited<ReturnType<T[Key]>>\n >;\n }[keyof T]\n>;"},{"breadcrumbs":["Types","Public types","BeforeNavigate"],"href":"/docs/types#public-types-beforenavigate","content":"The argument passed to beforeNavigate callbacks.\n\n\ninterface BeforeNavigate extends Navigation {/*…*/}\ncancel(): void;\nCall this to prevent the navigation from starting."},{"breadcrumbs":["Types","Public types","Builder"],"href":"/docs/types#public-types-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.\n\n\ninterface Builder {/*…*/}\nlog: Logger;\nPrint messages to the console. log.info and log.minor are silent unless Vite's logLevel is info.\n\n\n\nrimraf(dir: string): void;\nRemove dir and all its contents.\n\n\n\nmkdirp(dir: string): void;\nCreate dir and any required parent directories.\n\n\n\nconfig: ValidatedConfig;\nThe fully resolved svelte.config.js.\n\n\n\nprerendered: Prerendered;\nInformation about prerendered pages and assets, if any.\n\n\n\nroutes: RouteDefinition[];\nAn array of all routes (including prerendered)\n\n\n\ncreateEntries(fn: (route: RouteDefinition) => AdapterEntry): Promise<void>;\n\nfn A function that groups a set of routes into an entry point\n\ndeprecated\n Use builder.routes instead\n\n\nCreate separate functions that map to one or more routes of your app.\n\n\n\nfindServerAssets(routes: RouteDefinition[]): string[];\nFind all the assets imported by server files belonging to routes\n\n\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\n\n\ngenerateEnvModule(): void;\nGenerate a module exposing build-time environment variables as $env/dynamic/public.\n\n\n\ngenerateManifest(opts: { relativePath: string; routes?: RouteDefinition[] }): string;\n\nopts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated\n\n\nGenerate a server-side manifest to initialise the SvelteKit server with.\n\n\n\ngetBuildDirectory(name: string): string;\n\nname path to the file, relative to the build directory\n\n\nResolve a path to the name directory inside outDir, e.g. /path/to/.svelte-kit/my-adapter.\n\n\n\ngetClientDirectory(): string;\nGet the fully resolved path to the directory containing client-side assets, including the contents of your static directory.\n\n\n\ngetServerDirectory(): string;\nGet the fully resolved path to the directory containing server-side code.\n\n\n\ngetAppPath(): string;\nGet the application path including any configured base path, e.g. my-base-path/_app.\n\n\n\nwriteClient(dest: string): string[];\n\ndest the destination folder\n\nreturns\n an array of files written to dest\n\n\nWrite client assets to dest.\n\n\n\nwritePrerendered(dest: string): string[];\n\ndest the destination folder\n\nreturns\n an array of files written to dest\n\n\nWrite prerendered files to dest.\n\n\n\nwriteServer(dest: string): string[];\n\ndest the destination folder\n\nreturns\n an array of files written to dest\n\n\nWrite server-side code to dest.\n\n\n\ncopy(\n from: string,\n to: string,\n opts?: {\n filter?(basename: string): boolean;\n replace?: Record<string, string>;\n }\n): string[];\n\nfrom the source file or directory\nto the destination file or directory\nopts.filter a function to determine whether a file or directory should be copied\nopts.replace a map of strings to replace\n\nreturns\n an array of files that were copied\n\n\nCopy a file or directory.\n\n\n\ncompress(directory: string): Promise<void>;\n\ndirectory The directory containing the files to be compressed\n\n\nCompress files in directory with gzip and brotli, where appropriate. Generates .gz and .br files alongside the originals."},{"breadcrumbs":["Types","Public types","Config"],"href":"/docs/types#public-types-config","content":"interface Config {/*…*/}\nSee the configuration reference for details."},{"breadcrumbs":["Types","Public types","Cookies"],"href":"/docs/types#public-types-cookies","content":"interface Cookies {/*…*/}\nget(name: string, opts?: import('cookie').CookieParseOptions): string | undefined;\n\nname the name of the cookie\nopts the options, passed directly to cookie.parse. See documentation here\n\n\nGets a cookie that was previously set with cookies.set, or from the request headers.\n\n\n\ngetAll(opts?: import('cookie').CookieParseOptions): Array<{ name: string; value: string }>;\n\nopts the options, passed directly to cookie.parse. See documentation here\n\n\nGets all cookies that were previously set with cookies.set, or from the request headers.\n\n\n\nset(\n name: string,\n value: string,\n opts: import('cookie').CookieSerializeOptions & { path: string }\n): void;\n\nname the name of the cookie\nvalue the cookie value\nopts the options, passed directly to cookie.serialize. See documentation here\n\n\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.\n\nThe 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.\n\nYou 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\n\n\ndelete(name: string, opts: import('cookie').CookieSerializeOptions & { path: string }): void;\n\nname the name of the cookie\nopts the options, passed directly to cookie.serialize. The path must match the path of the cookie you want to delete. See documentation here\n\n\nDeletes a cookie by setting its value to an empty string and setting the expiry date in the past.\n\nYou 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\n\n\nserialize(\n name: string,\n value: string,\n opts: import('cookie').CookieSerializeOptions & { path: string }\n): string;\n\nname the name of the cookie\nvalue the cookie value\nopts the options, passed directly to cookie.serialize. See documentation here\n\n\nSerialize a cookie name-value pair into a Set-Cookie header string, but don't apply it to the response.\n\nThe 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.\n\nYou 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"},{"breadcrumbs":["Types","Public types","Emulator"],"href":"/docs/types#public-types-emulator","content":"A collection of functions that influence the environment during dev, build and prerendering\n\n\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"},{"breadcrumbs":["Types","Public types","Handle"],"href":"/docs/types#public-types-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).\n\n\ntype Handle = (input: {\n event: RequestEvent;\n resolve(\n event: RequestEvent,\n opts?: ResolveOptions\n ): MaybePromise<Response>;\n}) => MaybePromise<Response>;"},{"breadcrumbs":["Types","Public types","HandleClientError"],"href":"/docs/types#public-types-handleclienterror","content":"The client-side handleError hook runs when an unexpected error is thrown while navigating.\n\nIf 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.\n\n\ntype HandleClientError = (input: {\n error: unknown;\n event: NavigationEvent;\n status: number;\n message: string;\n}) => MaybePromise<void | App.Error>;"},{"breadcrumbs":["Types","Public types","HandleFetch"],"href":"/docs/types#public-types-handlefetch","content":"The handleFetch hook allows you to modify (or replace) a fetch request that happens inside a load function that runs on the server (or during pre-rendering)\n\n\ntype HandleFetch = (input: {\n event: RequestEvent;\n request: Request;\n fetch: typeof fetch;\n}) => MaybePromise<Response>;"},{"breadcrumbs":["Types","Public types","HandleServerError"],"href":"/docs/types#public-types-handleservererror","content":"The server-side handleError hook runs when an unexpected error is thrown while responding to a request.\n\nIf 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.\n\n\ntype HandleServerError = (input: {\n error: unknown;\n event: RequestEvent;\n status: number;\n message: string;\n}) => MaybePromise<void | App.Error>;"},{"breadcrumbs":["Types","Public types","HttpError"],"href":"/docs/types#public-types-httperror","content":"The object returned by the error function.\n\n\ninterface HttpError {/*…*/}\nstatus: number;\nThe HTTP status code, in the range 400-599.\n\n\n\nbody: App.Error;\nThe content of the error."},{"breadcrumbs":["Types","Public types","KitConfig"],"href":"/docs/types#public-types-kitconfig","content":"interface KitConfig {/*…*/}\nSee the configuration reference for details."},{"breadcrumbs":["Types","Public types","LessThan"],"href":"/docs/types#public-types-lessthan","content":"type LessThan<\n TNumber extends number,\n TArray extends any[] = []\n> = TNumber extends TArray['length']\n ? TArray[number]\n : LessThan<TNumber, [...TArray, TArray['length']]>;"},{"breadcrumbs":["Types","Public types","Load"],"href":"/docs/types#public-types-load","content":"The generic form of PageLoad and LayoutLoad. You should import those from ./$types (see generated types)\nrather than using Load directly.\n\n\ntype Load<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n InputData extends Record<string, unknown> | null = Record<\n string,\n any\n > | null,\n ParentData extends Record<string, unknown> = Record<\n string,\n any\n >,\n OutputData extends Record<\n string,\n unknown\n > | void = Record<string, any> | void,\n RouteId extends string | null = string | null\n> = (\n event: LoadEvent<Params, InputData, ParentData, RouteId>\n) => MaybePromise<OutputData>;"},{"breadcrumbs":["Types","Public types","LoadEvent"],"href":"/docs/types#public-types-loadevent","content":"The generic form of PageLoadEvent and LayoutLoadEvent. You should import those from ./$types (see generated types)\nrather than using LoadEvent directly.\n\n\ninterface LoadEvent<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n Data extends Record<string, unknown> | null = Record<\n string,\n any\n > | null,\n ParentData extends Record<string, unknown> = Record<\n string,\n any\n >,\n RouteId extends string | null = string | null\n> extends NavigationEvent<Params, RouteId> {/*…*/}\nfetch: typeof fetch;\nfetch is equivalent to the native fetch web API, with a few additional features:\n\nIt 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\nDuring hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.\n\nYou can learn more about making credentialed requests with cookies here\n\n\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\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\nSetting the same header multiple times (even in separate load functions) is an error — you can only set a given header once.\n\nYou cannot add a set-cookie header with setHeaders — use the cookies API in a server-only load function instead.\n\nsetHeaders has no effect when a load function runs in the browser.\n\n\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.\n\nBe 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\n\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.\n\nMost 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.\n\nURLs can be absolute or relative to the page being loaded, and must be encoded.\n\nCustom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the URI specification.\n\nThe 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\n\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:"},{"breadcrumbs":["Types","Public types","LoadProperties"],"href":"/docs/types#public-types-loadproperties","content":"type LoadProperties<\n input extends Record<string, any> | void\n> = input extends void\n ? undefined // needs to be undefined, because void will break intellisense\n : input extends Record<string, any>\n ? input\n : unknown;"},{"breadcrumbs":["Types","Public types","Navigation"],"href":"/docs/types#public-types-navigation","content":"interface Navigation {/*…*/}\nfrom: NavigationTarget | null;\nWhere navigation was triggered from\n\n\n\nto: NavigationTarget | null;\nWhere navigation is going to/has gone to\n\n\n\ntype: Exclude<NavigationType, 'enter'>;\nThe type of navigation:\n\nform: The user submitted a <form>\nleave: The app is being left either because the tab is being closed or a navigation to a different document is occurring\nlink: Navigation was triggered by a link click\ngoto: Navigation was triggered by a goto(...) call or a redirect\npopstate: Navigation was triggered by back/forward navigation\n\n\n\nwillUnload: boolean;\nWhether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)\n\n\n\ndelta?: number;\nIn case of a history back/forward navigation, the number of steps to go back/forward\n\n\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"},{"breadcrumbs":["Types","Public types","NavigationEvent"],"href":"/docs/types#public-types-navigationevent","content":"interface NavigationEvent<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n RouteId extends string | null = string | null\n> {/*…*/}\nparams: Params;\nThe parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object\n\n\n\nroute: {/*…*/}\nInfo about the current route\n\n\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]\n\n\n\nurl: URL;\nThe URL of the current page"},{"breadcrumbs":["Types","Public types","NavigationTarget"],"href":"/docs/types#public-types-navigationtarget","content":"Information about the target of a specific navigation.\n\n\ninterface NavigationTarget {/*…*/}\nparams: Record<string, string> | 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\n\n\nroute: { id: string | null };\nInfo about the target route\n\n\n\nurl: URL;\nThe URL that is navigated to"},{"breadcrumbs":["Types","Public types","NavigationType"],"href":"/docs/types#public-types-navigationtype","content":"enter: The app has hydrated\nform: The user submitted a <form> with a GET method\nleave: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document\nlink: Navigation was triggered by a link click\ngoto: Navigation was triggered by a goto(...) call or a redirect\npopstate: Navigation was triggered by back/forward navigation\n\n\ntype NavigationType =\n | 'enter'\n | 'form'\n | 'leave'\n | 'link'\n | 'goto'\n | 'popstate';"},{"breadcrumbs":["Types","Public types","NumericRange"],"href":"/docs/types#public-types-numericrange","content":"type NumericRange<\n TStart extends number,\n TEnd extends number\n> = Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>;"},{"breadcrumbs":["Types","Public types","OnNavigate"],"href":"/docs/types#public-types-onnavigate","content":"The argument passed to onNavigate callbacks.\n\n\ninterface OnNavigate extends Navigation {/*…*/}\ntype: Exclude<NavigationType, 'enter' | 'leave'>;\nThe type of navigation:\n\nform: The user submitted a <form>\nlink: Navigation was triggered by a link click\ngoto: Navigation was triggered by a goto(...) call or a redirect\npopstate: Navigation was triggered by back/forward navigation\n\n\n\nwillUnload: false;\nSince onNavigate callbacks are called immediately before a client-side navigation, they will never be called with a navigation that unloads the page."},{"breadcrumbs":["Types","Public types","Page"],"href":"/docs/types#public-types-page","content":"The shape of the $page store\n\n\ninterface Page<\n Params extends Record<string, string> = Record<\n string,\n string\n >,\n RouteId extends string | null = string | null\n> {/*…*/}\nurl: URL;\nThe URL of the current page\n\n\n\nparams: Params;\nThe parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object\n\n\n\nroute: {/*…*/}\nInfo about the current route\n\n\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]\n\n\n\nstatus: number;\nHttp status code of the current page\n\n\n\nerror: App.Error | null;\nThe error object of the current page, if any. Filled from the handleError hooks.\n\n\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\n\n\nstate: App.PageState;\nThe page state, which can be manipulated using the pushState and replaceState functions from $app/navigation.\n\n\n\nform: any;\nFilled only after a form submission. See form actions for more info."},{"breadcrumbs":["Types","Public types","ParamMatcher"],"href":"/docs/types#public-types-parammatcher","content":"The shape of a param matcher. See matching for more info.\n\n\ntype ParamMatcher = (param: string) => boolean;"},{"breadcrumbs":["Types","Public types","PrerenderOption"],"href":"/docs/types#public-types-prerenderoption","content":"type PrerenderOption = boolean | 'auto';"},{"breadcrumbs":["Types","Public types","Redirect"],"href":"/docs/types#public-types-redirect","content":"The object returned by the redirect function\n\n\ninterface Redirect {/*…*/}\nstatus: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;\nThe HTTP status code, in the range 300-308.\n\n\n\nlocation: string;\nThe location to redirect to."},{"breadcrumbs":["Types","Public types","RequestEvent"],"href":"/docs/types#public-types-requestevent","content":"interface RequestEvent<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n RouteId extends string | null = string | null\n> {/*…*/}\ncookies: Cookies;\nGet or set cookies related to the current request\n\n\n\nfetch: typeof fetch;\nfetch is equivalent to the native fetch web API, with a few additional features:\n\nIt 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\nDuring hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.\n\nYou can learn more about making credentialed requests with cookies here\n\n\n\ngetClientAddress(): string;\nThe client's IP address, set by the adapter.\n\n\n\nlocals: App.Locals;\nContains custom data that was added to the request within the handle hook.\n\n\n\nparams: Params;\nThe parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object\n\n\n\nplatform: Readonly<App.Platform> | undefined;\nAdditional data made available through the adapter.\n\n\n\nrequest: Request;\nThe original request object\n\n\n\nroute: {/*…*/}\nInfo about the current route\n\n\nid: RouteId;\nThe ID of the current route - e.g. for src/routes/blog/[slug], it would be /blog/[slug]\n\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\nSetting the same header multiple times (even in separate load functions) is an error — you can only set a given header once.\n\nYou cannot add a set-cookie header with setHeaders — use the cookies API instead.\n\n\n\nurl: URL;\nThe requested URL.\n\n\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\n\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."},{"breadcrumbs":["Types","Public types","RequestHandler"],"href":"/docs/types#public-types-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.\n\nIt receives Params as the first generic argument, which you can skip by using generated types instead.\n\n\ntype RequestHandler<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n RouteId extends string | null = string | null\n> = (\n event: RequestEvent<Params, RouteId>\n) => MaybePromise<Response>;"},{"breadcrumbs":["Types","Public types","Reroute"],"href":"/docs/types#public-types-reroute","content":"The reroute hook allows you to modify the URL before it is used to determine which route to render.\n\n\ntype Reroute = (event: { url: URL }) => void | string;"},{"breadcrumbs":["Types","Public types","ResolveOptions"],"href":"/docs/types#public-types-resolveoptions","content":"interface ResolveOptions {/*…*/}\ntransformPageChunk?(input: { html: string; done: boolean }): MaybePromise<string | undefined>;\n\ninput the html chunk and the info if this is the last chunk\n\n\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\n\n\nfilterSerializedResponseHeaders?(name: string, value: string): boolean;\n\nname header name\nvalue header value\n\n\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\n\n\npreload?(input: { type: 'font' | 'css' | 'js' | 'asset'; path: string }): boolean;\n\ninput the type of the file and its path\n\n\nDetermines what should be added to the <head> tag to preload it.\nBy default, js and css files will be preloaded."},{"breadcrumbs":["Types","Public types","RouteDefinition"],"href":"/docs/types#public-types-routedefinition","content":"interface RouteDefinition<Config = any> {/*…*/}\nid: string;\n\n\napi: {\n methods: Array<HttpMethod | '*'>;\n};\n\n\npage: {\n methods: Array<Extract<HttpMethod, 'GET' | 'POST'>>;\n};\n\n\npattern: RegExp;\n\n\nprerender: PrerenderOption;\n\n\nsegments: RouteSegment[];\n\n\nmethods: Array<HttpMethod | '*'>;\n\n\nconfig: Config;"},{"breadcrumbs":["Types","Public types","SSRManifest"],"href":"/docs/types#public-types-ssrmanifest","content":"interface SSRManifest {/*…*/}\nappDir: string;\n\n\nappPath: string;\n\n\nassets: Set<string>;\n\n\nmimeTypes: Record<string, string>;\n\n\n_: {/*…*/}\nprivate fields\n\n\nclient: NonNullable<BuildData['client']>;\n\nnodes: SSRNodeLoader[];\n\nroutes: SSRRoute[];\n\nmatchers(): Promise<Record<string, ParamMatcher>>;\n\nserver_assets: Record<string, number>;\nA [file]: size map of all assets imported by server code"},{"breadcrumbs":["Types","Public types","Server"],"href":"/docs/types#public-types-server","content":"class Server {/*…*/}\nconstructor(manifest: SSRManifest);\n\n\ninit(options: ServerInitOptions): Promise<void>;\n\n\nrespond(request: Request, options: RequestOptions): Promise<Response>;"},{"breadcrumbs":["Types","Public types","ServerInitOptions"],"href":"/docs/types#public-types-serverinitoptions","content":"interface ServerInitOptions {/*…*/}\nenv: Record<string, string>;\nA map of environment variables\n\n\n\nread?: (file: string) => ReadableStream;\nA function that turns an asset filename into a ReadableStream. Required for the read export from $app/server to work"},{"breadcrumbs":["Types","Public types","ServerLoad"],"href":"/docs/types#public-types-serverload","content":"The generic form of PageServerLoad and LayoutServerLoad. You should import those from ./$types (see generated types)\nrather than using ServerLoad directly.\n\n\ntype ServerLoad<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n ParentData extends Record<string, any> = Record<\n string,\n any\n >,\n OutputData extends Record<string, any> | void = Record<\n string,\n any\n > | void,\n RouteId extends string | null = string | null\n> = (\n event: ServerLoadEvent<Params, ParentData, RouteId>\n) => MaybePromise<OutputData>;"},{"breadcrumbs":["Types","Public types","ServerLoadEvent"],"href":"/docs/types#public-types-serverloadevent","content":"interface ServerLoadEvent<\n Params extends Partial<Record<string, string>> = Partial<\n Record<string, string>\n >,\n ParentData extends Record<string, any> = Record<\n string,\n any\n >,\n RouteId extends string | null = string | null\n> extends RequestEvent<Params, RouteId> {/*…*/}\nparent(): Promise<ParentData>;\nawait parent() returns data from parent +layout.server.js load functions.\n\nBe 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\n\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.\n\nMost 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.\n\nURLs can be absolute or relative to the page being loaded, and must be encoded.\n\nCustom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the URI specification.\n\nThe 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\n\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:"},{"breadcrumbs":["Types","Public types","Snapshot"],"href":"/docs/types#public-types-snapshot","content":"The type of export const snapshot exported from a page or layout component.\n\n\ninterface Snapshot<T = any> {/*…*/}\ncapture: () => T;\n\n\nrestore: (snapshot: T) => void;"},{"breadcrumbs":["Types","Public types","SubmitFunction"],"href":"/docs/types#public-types-submitfunction","content":"type SubmitFunction<\n Success extends\n | Record<string, unknown>\n | undefined = Record<string, any>,\n Failure extends\n | Record<string, unknown>\n | undefined = Record<string, any>\n> = (input: {\n action: URL;\n formData: FormData;\n formElement: HTMLFormElement;\n controller: AbortController;\n submitter: HTMLElement | null;\n cancel(): void;\n}) => MaybePromise<\n | void\n | ((opts: {\n formData: FormData;\n formElement: HTMLFormElement;\n action: URL;\n result: ActionResult<Success, Failure>;\n /**\n * Call this to get the default behavior of a form submission response.\n * @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission.\n * @param invalidateAll Set `invalidateAll: false` if you don't want the action to call `invalidateAll` after submission.\n */\n update(options?: {\n reset?: boolean;\n invalidateAll?: boolean;\n }): Promise<void>;\n }) => void)\n>;"},{"breadcrumbs":["Types","Private types"],"href":"/docs/types#private-types","content":"The following are referenced by the public types documented above, but cannot be imported directly:"},{"breadcrumbs":["Types","Private types","AdapterEntry"],"href":"/docs/types#private-types-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\n\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.\n\nUse cases:\n\nFallback 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\n\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."},{"breadcrumbs":["Types","Private types","Csp"],"href":"/docs/types#private-types-csp","content":"namespace Csp {\n type ActionSource = 'strict-dynamic' | 'report-sample';\n type BaseSource =\n | 'self'\n | 'unsafe-eval'\n | 'unsafe-hashes'\n | 'unsafe-inline'\n | 'wasm-unsafe-eval'\n | 'none';\n type CryptoSource =\n `${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;\n type FrameSource =\n | HostSource\n | SchemeSource\n | 'self'\n | 'none';\n type HostNameScheme = `${string}.${string}` | 'localhost';\n type HostSource =\n `${HostProtocolSchemes}${HostNameScheme}${PortScheme}`;\n type HostProtocolSchemes = `${string}://` | '';\n type HttpDelineator = '/' | '?' | '#' | '\\\\';\n type PortScheme = `:${number}` | '' | ':*';\n type SchemeSource =\n | 'http:'\n | 'https:'\n | 'data:'\n | 'mediastream:'\n | 'blob:'\n | 'filesystem:';\n type Source =\n | HostSource\n | SchemeSource\n | CryptoSource\n | BaseSource;\n type Sources = Source[];\n}"},{"breadcrumbs":["Types","Private types","CspDirectives"],"href":"/docs/types#private-types-cspdirectives","content":"interface CspDirectives {/*…*/}\n'child-src'?: Csp.Sources;\n\n\n'default-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n\n'frame-src'?: Csp.Sources;\n\n\n'worker-src'?: Csp.Sources;\n\n\n'connect-src'?: Csp.Sources;\n\n\n'font-src'?: Csp.Sources;\n\n\n'img-src'?: Csp.Sources;\n\n\n'manifest-src'?: Csp.Sources;\n\n\n'media-src'?: Csp.Sources;\n\n\n'object-src'?: Csp.Sources;\n\n\n'prefetch-src'?: Csp.Sources;\n\n\n'script-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n\n'script-src-elem'?: Csp.Sources;\n\n\n'script-src-attr'?: Csp.Sources;\n\n\n'style-src'?: Array<Csp.Source | Csp.ActionSource>;\n\n\n'style-src-elem'?: Csp.Sources;\n\n\n'style-src-attr'?: Csp.Sources;\n\n\n'base-uri'?: Array<Csp.Source | Csp.ActionSource>;\n\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\n'form-action'?: Array<Csp.Source | Csp.ActionSource>;\n\n\n'frame-ancestors'?: Array<Csp.HostSource | Csp.SchemeSource | Csp.FrameSource>;\n\n\n'navigate-to'?: Array<Csp.Source | Csp.ActionSource>;\n\n\n'report-uri'?: string[];\n\n\n'report-to'?: string[];\n\n\n'require-trusted-types-for'?: Array<'script'>;\n\n\n'trusted-types'?: Array<'none' | 'allow-duplicates' | '*' | string>;\n\n\n'upgrade-insecure-requests'?: boolean;\n\n\n'require-sri-for'?: Array<'script' | 'style' | 'script style'>;\n\n\ndeprecated\n \n\n\n\n\n'block-all-mixed-content'?: boolean;\n\n\ndeprecated\n \n\n\n\n\n'plugin-types'?: Array<`${string}/${string}` | 'none'>;\n\n\ndeprecated\n \n\n\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\ndeprecated"},{"breadcrumbs":["Types","Private types","HttpMethod"],"href":"/docs/types#private-types-httpmethod","content":"type HttpMethod =\n | 'GET'\n | 'HEAD'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'PATCH'\n | 'OPTIONS';"},{"breadcrumbs":["Types","Private types","Logger"],"href":"/docs/types#private-types-logger","content":"interface Logger {/*…*/}\n(msg: string): void;\n\n\nsuccess(msg: string): void;\n\n\nerror(msg: string): void;\n\n\nwarn(msg: string): void;\n\n\nminor(msg: string): void;\n\n\ninfo(msg: string): void;"},{"breadcrumbs":["Types","Private types","MaybePromise"],"href":"/docs/types#private-types-maybepromise","content":"type MaybePromise<T> = T | Promise<T>;"},{"breadcrumbs":["Types","Private types","PrerenderEntryGeneratorMismatchHandler"],"href":"/docs/types#private-types-prerenderentrygeneratormismatchhandler","content":"interface PrerenderEntryGeneratorMismatchHandler {/*…*/}\n(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;"},{"breadcrumbs":["Types","Private types","PrerenderEntryGeneratorMismatchHandlerValue"],"href":"/docs/types#private-types-prerenderentrygeneratormismatchhandlervalue","content":"type PrerenderEntryGeneratorMismatchHandlerValue =\n | 'fail'\n | 'warn'\n | 'ignore'\n | PrerenderEntryGeneratorMismatchHandler;"},{"breadcrumbs":["Types","Private types","PrerenderHttpErrorHandler"],"href":"/docs/types#private-types-prerenderhttperrorhandler","content":"interface PrerenderHttpErrorHandler {/*…*/}\n(details: {\nstatus: number;\npath: string;\nreferrer: string | null;\nreferenceType: 'linked' | 'fetched';\nmessage: string;\n}): void;"},{"breadcrumbs":["Types","Private types","PrerenderHttpErrorHandlerValue"],"href":"/docs/types#private-types-prerenderhttperrorhandlervalue","content":"type PrerenderHttpErrorHandlerValue =\n | 'fail'\n | 'warn'\n | 'ignore'\n | PrerenderHttpErrorHandler;"},{"breadcrumbs":["Types","Private types","PrerenderMap"],"href":"/docs/types#private-types-prerendermap","content":"type PrerenderMap = Map<string, PrerenderOption>;"},{"breadcrumbs":["Types","Private types","PrerenderMissingIdHandler"],"href":"/docs/types#private-types-prerendermissingidhandler","content":"interface PrerenderMissingIdHandler {/*…*/}\n(details: { path: string; id: string; referrers: string[]; message: string }): void;"},{"breadcrumbs":["Types","Private types","PrerenderMissingIdHandlerValue"],"href":"/docs/types#private-types-prerendermissingidhandlervalue","content":"type PrerenderMissingIdHandlerValue =\n | 'fail'\n | 'warn'\n | 'ignore'\n | PrerenderMissingIdHandler;"},{"breadcrumbs":["Types","Private types","PrerenderOption"],"href":"/docs/types#private-types-prerenderoption","content":"type PrerenderOption = boolean | 'auto';"},{"breadcrumbs":["Types","Private types","Prerendered"],"href":"/docs/types#private-types-prerendered","content":"interface Prerendered {/*…*/}\npages: Map<\nstring,\n{\n /** The location of the .html file relative to the output directory */\n file: 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\n\n\nassets: Map<\nstring,\n{\n /** The MIME type of the asset */\n type: string;\n}\n>;\nA map of path to { type } objects.\n\n\n\nredirects: Map<\nstring,\n{\n status: number;\n location: string;\n}\n>;\nA map of redirects encountered during prerendering.\n\n\n\npaths: string[];\nAn array of prerendered paths (without trailing slashes, regardless of the trailingSlash config)"},{"breadcrumbs":["Types","Private types","RequestOptions"],"href":"/docs/types#private-types-requestoptions","content":"interface RequestOptions {/*…*/}\ngetClientAddress(): string;\n\n\nplatform?: App.Platform;"},{"breadcrumbs":["Types","Private types","RouteSegment"],"href":"/docs/types#private-types-routesegment","content":"interface RouteSegment {/*…*/}\ncontent: string;\n\n\ndynamic: boolean;\n\n\nrest: boolean;"},{"breadcrumbs":["Types","Private types","TrailingSlash"],"href":"/docs/types#private-types-trailingslash","content":"type TrailingSlash = 'never' | 'always' | 'ignore';"},{"breadcrumbs":["Types","Generated types"],"href":"/docs/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\nNeedless 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).\n\nTo solve this problem, SvelteKit generates .d.ts files for each of your endpoints and pages:\n\nThese files can be imported into your endpoints and pages as siblings, thanks to the rootDirs option in your TypeScript configuration:\n\n/** @type {import('./$types').PageServerLoad} */\nexport async function GET({ params }) {\n // ...\n}/** @type {import('./$types').PageLoad} */\nexport async function load({ params, fetch }) {\n // ...\n}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) and TypeScript should be installed as a dependency:\n\n{ "extends": "./.svelte-kit/tsconfig.json" }"},{"breadcrumbs":["Types","Generated types","Default tsconfig.json"],"href":"/docs/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\nOthers are required for SvelteKit to work properly, and should also be left untouched unless you know what you're doing:"},{"breadcrumbs":["Types","App"],"href":"/docs/types#app","content":""},{"breadcrumbs":["Types","App","Error"],"href":"/docs/types#app-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.\n\n\ninterface Error {/*…*/}\nmessage: string;"},{"breadcrumbs":["Types","App","Locals"],"href":"/docs/types#app-locals","content":"The interface that defines event.locals, which can be accessed in hooks (handle, and handleError), server-only load functions, and +server.js files.\n\n\ninterface Locals {}"},{"breadcrumbs":["Types","App","PageData"],"href":"/docs/types#app-pagedata","content":"Defines the common shape of the $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).\n\n\ninterface PageData {}"},{"breadcrumbs":["Types","App","PageState"],"href":"/docs/types#app-pagestate","content":"The shape of the $page.state object, which can be manipulated using the pushState and replaceState functions from $app/navigation.\n\n\ninterface PageState {}"},{"breadcrumbs":["Types","App","Platform"],"href":"/docs/types#app-platform","content":"If your adapter provides platform-specific context via event.platform, you can specify it here.\n\n\ninterface Platform {}"},{"breadcrumbs":["Frequently asked questions"],"href":"/docs/faq","content":""},{"breadcrumbs":["Frequently asked questions","Other resources"],"href":"/docs/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."},{"breadcrumbs":["Frequently asked questions","What can I make with SvelteKit?"],"href":"/docs/faq#what-can-i-make-with-sveltekit","content":"SvelteKit can be used to create most kinds of applications. Out of the box, SvelteKit supports many features including:\n\nDynamic page content with load functions and API routes.\nSEO-friendly dynamic content with server-side rendering (SSR).\nUser-friendly progressively-enhanced interactive pages with SSR and Form Actions.\nStatic pages with prerendering.\n\nSvelteKit can also be deployed to a wide spectrum of hosted architectures via adapters. In cases where SSR is used (or server-side logic is added without prerendering), those functions will be adapted to the target backend. Some examples include:\n\nSelf-hosted dynamic web applications with a Node.js backend.\nServerless web applications with backend loaders and APIs deployed as remote functions. See zero-config deployments for popular deployment options.\nStatic pre-rendered sites such as a blog or multi-page site hosted on a CDN or static host. Statically-generated sites are shipped without a backend.\nSingle-page Applications (SPAs) with client-side routing and rendering for API-driven dynamic content. SPAs are shipped without a backend and are not server-rendered. This option is commonly chosen when bundling SvelteKit with an app written in PHP, .Net, Java, C, Golang, Rust, etc.\nA mix of the above; some routes can be static, and some routes can use backend functions to fetch dynamic information. This can be configured with page options that includes the option to opt out of SSR.\n\nIn order to support SSR, a JS backend — such as Node.js or Deno-based server, serverless function, or edge function — is required.\n\nIt is also possible to write custom adapters or leverage community adapters to deploy SvelteKit to more platforms such as specialized server environments, browser extensions, or native applications. See integrations for more examples and integrations."},{"breadcrumbs":["Frequently asked questions","How do I use HMR with SvelteKit?"],"href":"/docs/faq#how-do-i-use-hmr-with-sveltekit","content":"SvelteKit has HMR enabled by default powered by svelte-hmr. If you saw Rich's presentation at the 2020 Svelte Summit, you may have seen a more powerful-looking version of HMR presented. This demo had svelte-hmr's preserveLocalState flag on. This flag is now off by default because it may lead to unexpected behaviour and edge cases. But don't worry, you are still getting HMR with SvelteKit! If you'd like to preserve local state you can use the @hmr:keep or @hmr:keep-all directives as documented on the svelte-hmr page."},{"breadcrumbs":["Frequently asked questions","How do I include details from package.json in my application?"],"href":"/docs/faq#how-do-i-include-details-from-package-json-in-my-application","content":"You cannot directly require JSON files, since SvelteKit expects svelte.config.js to be an ES module. 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 { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\n\nconst path = fileURLToPath(new URL('package.json', import.meta.url));\nconst pkg = JSON.parse(readFileSync(path, 'utf8'));"},{"breadcrumbs":["Frequently asked questions","How do I fix the error I'm getting trying to include a package?"],"href":"/docs/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.\n\nHere are a few things to keep in mind when checking if a library is packaged correctly:\n\nexports 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.\nmain 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 for packaging Svelte libraries, which will do this for you.\n\nLibraries 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.\n\nIf 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."},{"breadcrumbs":["Frequently asked questions","How do I use the view transitions API with SvelteKit?"],"href":"/docs/faq#how-do-i-use-the-view-transitions-api-with-sveltekit","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.\n\nFor more, see "Unlocking view transitions" on the Svelte blog."},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit","content":"Make sure you've read the documentation section on integrations. If you're still having trouble, solutions to common issues are listed below."},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","How do I setup a database?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-how-do-i-setup-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."},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","How do I use a client-side only library that depends on `document` or `window`?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-a-client-side-only-library-that-depends-on-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:\n\nimport { browser } from '$app/environment';\n\nif (browser) {\n // 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:\n\nimport { onMount } from 'svelte';\n\nonMount(async () => {\n const { method } = await import('some-browser-only-library');\n method('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:\n\nimport { onMount } from 'svelte';\nimport { method } from 'some-browser-only-library';\n\nonMount(() => {\n method('hello world');\n});Finally, you may also consider using an {#await} block:\n\n<!--- file: index.svelte --->\n<script>\n import { browser } from '$app/environment';\n\n const ComponentConstructor = browser ?\n import('some-browser-only-library').then((module) => module.Component) :\n new Promise(() => {});\n</script>\n\n{#await ComponentConstructor}\n <p>Loading...</p>\n{:then component}\n <svelte:component this={component} />\n{:catch error}\n <p>Something went wrong: {error.message}</p>\n{/await}"},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","How do I use a different backend API server?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-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.\n\nAnother 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.\n\nHow to setup rewrites in production will depend on your deployment platform. If rewrites aren't an option, you could alternatively add an API route:\n\n(Note that you may also need to proxy POST/PATCH etc requests, and forward request.headers, depending on your needs.)"},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","How do I use middleware?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-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:\n\nimport { sveltekit } from '@sveltejs/kit/vite';\n\n/** @type {import('vite').Plugin} */\nconst myPlugin = {\n name: 'log-request-middleware',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n console.log(`Got request ${req.url}`);\n next();\n });\n }\n};\n\n/** @type {import('vite').UserConfig} */\nconst config = {\n plugins: [myPlugin, sveltekit()]\n};\n\nexport default config;See Vite's configureServer docs for more details including how to control ordering."},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","Does it work with Yarn 2?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-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."},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","How do I use with Yarn 3?"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-with-yarn-3","content":"Currently ESM Support within the latest Yarn (version 3) is considered experimental.\n\nThe below seems to work although your results may vary.\n\nFirst create a new application:\n\nyarn create svelte myapp\ncd myappAnd enable Yarn Berry:\n\nyarn set version berry\nyarn install"},{"breadcrumbs":["Frequently asked questions","How do I use X with SvelteKit?","Yarn 3 global cache"],"href":"/docs/faq#how-do-i-use-x-with-sveltekit-yarn-3-global-cache","content":"One of the more interesting features of Yarn Berry is the ability to have a single global cache for packages, instead of having multiple copies for each project on the disk. However, setting enableGlobalCache to true causes building to fail, so it is recommended to add the following to the .yarnrc.yml file:\n\nnodeLinker: 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."},{"breadcrumbs":["Integrations"],"href":"/docs/integrations","content":""},{"breadcrumbs":["Integrations","`vitePreprocess`"],"href":"/docs/integrations#vitepreprocess","content":"Including vitePreprocess in your project will allow you to use the various flavors of JS and CSS that Vite supports: TypeScript, PostCSS, SCSS, Less, Stylus, and SugarSS. If you set your project up with TypeScript it will be included by default:\n\n// svelte.config.js\nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\nexport default {\n preprocess: [vitePreprocess()]\n};"},{"breadcrumbs":["Integrations","Adders"],"href":"/docs/integrations#adders","content":"Run npx svelte-add to setup many different complex integrations with a single command including:\n\nCSS - Tailwind, Bootstrap, Bulma\ndatabase - Drizzle ORM\nmarkdown - mdsvex\nStorybook"},{"breadcrumbs":["Integrations","Directory"],"href":"/docs/integrations#directory","content":"See sveltesociety.dev for a full listing of packages and templates available for use with Svelte and SvelteKit."},{"breadcrumbs":["Integrations","Additional integrations"],"href":"/docs/integrations#additional-integrations","content":""},{"breadcrumbs":["Integrations","Additional integrations","`svelte-preprocess`"],"href":"/docs/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.\n\nYou will need to install svelte-preprocess with npm install --save-dev svelte-preprocess and add it to your svelte.config.js. After that, you will often need to install the corresponding library such as npm install -D sass or npm install -D less."},{"breadcrumbs":["Integrations","Vite plugins"],"href":"/docs/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."},{"breadcrumbs":["Integrations","Integration FAQs"],"href":"/docs/integrations#integration-faqs","content":"The SvelteKit FAQ has a how to do X with SvelteKit, which may be helpful if you still have questions."},{"breadcrumbs":["Breakpoint Debugging"],"href":"/docs/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.\n\nThe following guides assume your JavaScript runtime environment is Node.js."},{"breadcrumbs":["Breakpoint Debugging","Visual Studio Code"],"href":"/docs/debugging#visual-studio-code","content":"With the built-in debug terminal, you can set up breakpoints in source files within VSCode.\n\nOpen 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."},{"breadcrumbs":["Breakpoint Debugging","Visual Studio Code","Launch via debug pane"],"href":"/docs/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:\n\nGo 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.\n\nHere's an example launch.json:\n\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"command\": \"npm run dev\",\n \"name\": \"Run development server\",\n \"request\": \"launch\",\n \"type\": \"node-terminal\"\n }\n ]\n}Further reading: https://code.visualstudio.com/docs/editor/debugging."},{"breadcrumbs":["Breakpoint Debugging","Other Editors"],"href":"/docs/debugging#other-editors","content":"If you use a different editor, these community guides might be useful for you:\n\nWebStorm Svelte: Debug Your Application\nDebugging JavaScript Frameworks in Neovim"},{"breadcrumbs":["Breakpoint Debugging","Google Chrome and Microsoft Edge Developer Tools"],"href":"/docs/debugging#google-chrome-and-microsoft-edge-developer-tools","content":"It's possible to debug Node.js applications using a browser-based debugger.\n\nNote this only works with debugging client-side SvelteKit source maps.\n\n\nRun 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.\n\nYou may alternatively open the debugger devtools by navigating to chrome://inspect in Google Chrome, or edge://inspect in Microsoft Edge."},{"breadcrumbs":["Breakpoint Debugging","References"],"href":"/docs/debugging#references","content":"Debugging Node.js"},{"breadcrumbs":["Migrating to SvelteKit v2"],"href":"/docs/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 svelte-migrate@latest sveltekit-2 to migrate some of these changes automatically.\n\nWe 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."},{"breadcrumbs":["Migrating to SvelteKit v2","`redirect` and `error` are no longer thrown by you"],"href":"/docs/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.\n\nimport { 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.\n\nIf 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."},{"breadcrumbs":["Migrating to SvelteKit v2","path is required when setting cookies"],"href":"/docs/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.\n\nAs 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'.\n\nexport function load({ cookies }) {\n- cookies.set(name, value);\n+ cookies.set(name, value, { path: '/' });\n return { response }\n}svelte-migrate will add comments highlighting the locations that need to be adjusted."},{"breadcrumbs":["Migrating to SvelteKit v2","Top-level promises are no longer awaited"],"href":"/docs/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.\n\nAs 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):\n\n// If you have a single promise\nexport function load({ fetch }) {\n- const response = fetch(...).then(r => r.json());\n+ const response = await fetch(...).then(r => r.json());\n return { response }\n}// If you have multiple promises\nexport function load({ fetch }) {\n- const a = fetch(...).then(r => r.json());\n- const b = fetch(...).then(r => r.json());\n+ const [a, b] = await Promise.all([\n+ fetch(...).then(r => r.json()),\n+ fetch(...).then(r => r.json()),\n+ ]);\n return { a, b };\n}"},{"breadcrumbs":["Migrating to SvelteKit v2","goto(...) changes"],"href":"/docs/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."},{"breadcrumbs":["Migrating to SvelteKit v2","paths are now relative by default"],"href":"/docs/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.\n\nThis 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."},{"breadcrumbs":["Migrating to SvelteKit v2","Server fetches are not trackable anymore"],"href":"/docs/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 as such it was behind the dangerZone.trackServerFetches setting, which is now removed."},{"breadcrumbs":["Migrating to SvelteKit v2","`preloadCode` arguments must be prefixed with `base`"],"href":"/docs/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.\n\nThis is fixed in SvelteKit 2 — in both cases, the path should be prefixed with base if it is set.\n\nAdditionally, preloadCode now takes a single argument rather than n arguments."},{"breadcrumbs":["Migrating to SvelteKit v2","`resolvePath` has been removed"],"href":"/docs/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.\n\nAs such, SvelteKit 2 replaces resolvePath with a (slightly better named) function called resolveRoute, which is imported from $app/paths and which takes base into account.\n\n-import { resolvePath } from '@sveltejs/kit';\n-import { 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."},{"breadcrumbs":["Migrating to SvelteKit v2","Improved error handling"],"href":"/docs/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.\n\nSvelteKit 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."},{"breadcrumbs":["Migrating to SvelteKit v2","Dynamic environment variables cannot be used during prerendering"],"href":"/docs/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.\n\nDuring prerendering in SvelteKit 1, they are one and the same. As such, prerendered pages that make use of 'dynamic' environment variables are really 'baking in' build time values, which is incorrect. Worse, $env/dynamic/public is populated in the browser with these stale values if the user happens to land on a prerendered page before navigating to dynamically-rendered pages.\n\nBecause 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 _env.js — this can be configured with config.kit.env.publicModule) instead of reading them from the server-rendered HTML."},{"breadcrumbs":["Migrating to SvelteKit v2","`form` and `data` have been removed from `use:enhance` callbacks"],"href":"/docs/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.\n\nIn 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."},{"breadcrumbs":["Migrating to SvelteKit v2","Forms containing file inputs must use `multipart/form-data`"],"href":"/docs/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."},{"breadcrumbs":["Migrating to SvelteKit v2","Generated `tsconfig.json` is more strict"],"href":"/docs/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."},{"breadcrumbs":["Migrating to SvelteKit v2","`getRequest` no longer throws errors"],"href":"/docs/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.\n\nIn 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."},{"breadcrumbs":["Migrating to SvelteKit v2","`vitePreprocess` is no longer exported from `@sveltejs/kit/vite`"],"href":"/docs/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."},{"breadcrumbs":["Migrating to SvelteKit v2","Updated dependency requirements"],"href":"/docs/migrating-to-sveltekit-2#updated-dependency-requirements","content":"SvelteKit 2 requires Node 18.13 or higher, and the following minimum dependency versions:\n\nsvelte@4\nvite@5\ntypescript@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\n\nsvelte-migrate will update your package.json for you.\n\nAs 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)."},{"breadcrumbs":["Migrating from Sapper"],"href":"/docs/migrating","content":"SvelteKit is the successor to Sapper and shares many elements of its design.\n\nIf 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":["Migrating from Sapper","package.json"],"href":"/docs/migrating#package-json","content":"","rank":1},{"breadcrumbs":["Migrating from Sapper","package.json","type: \"module\""],"href":"/docs/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":["Migrating from Sapper","package.json","dependencies"],"href":"/docs/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":["Migrating from Sapper","package.json","devDependencies"],"href":"/docs/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":["Migrating from Sapper","package.json","scripts"],"href":"/docs/migrating#package-json-scripts","content":"Any scripts that reference sapper should be updated:\n\nsapper build should become vite build using the Node adapter\nsapper export should become vite build using the static adapter\nsapper dev should become vite dev\nnode __sapper__/build should become node build","rank":1},{"breadcrumbs":["Migrating from Sapper","Project files"],"href":"/docs/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":["Migrating from Sapper","Project files","Configuration"],"href":"/docs/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.\n\nYou 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.\n\nIf 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":["Migrating from Sapper","Project files","src/client.js"],"href":"/docs/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":["Migrating from Sapper","Project files","src/server.js"],"href":"/docs/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":["Migrating from Sapper","Project files","src/service-worker.js"],"href":"/docs/migrating#project-files-src-service-worker-js","content":"Most imports from @sapper/service-worker have equivalents in $service-worker:\n\nfiles is unchanged\nroutes has been removed\nshell is now build\ntimestamp is now version","rank":1},{"breadcrumbs":["Migrating from Sapper","Project files","src/template.html"],"href":"/docs/migrating#project-files-src-template-html","content":"The src/template.html file should be renamed src/app.html.\n\nRemove %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":["Migrating from Sapper","Project files","src/node_modules"],"href":"/docs/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":["Migrating from Sapper","Pages and layouts"],"href":"/docs/migrating#pages-and-layouts","content":"","rank":1},{"breadcrumbs":["Migrating from Sapper","Pages and layouts","Renamed files"],"href":"/docs/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 old/new comparison:\n\nOld New \n\nYour 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":["Migrating from Sapper","Pages and layouts","Imports"],"href":"/docs/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.\n\nThe stores import from @sapper/app should be replaced — see the Stores section below.\n\nAny files you previously imported from directories in src/node_modules will need to be replaced with $lib imports.","rank":1},{"breadcrumbs":["Migrating from Sapper","Pages and layouts","Preload"],"href":"/docs/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.\n\nThis 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.\n\nThere 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":["Migrating from Sapper","Pages and layouts","Stores"],"href":"/docs/migrating#pages-and-layouts-stores","content":"In Sapper, you would get references to provided stores like so:\n\nimport { 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.\n\nYou 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.","rank":1},{"breadcrumbs":["Migrating from Sapper","Pages and layouts","Routing"],"href":"/docs/migrating#pages-and-layouts-routing","content":"Regex routes are no longer supported. Instead, use advanced route matching.","rank":1},{"breadcrumbs":["Migrating from Sapper","Pages and layouts","Segments"],"href":"/docs/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 value to derive the segment you're interested in.","rank":1},{"breadcrumbs":["Migrating from Sapper","Pages and layouts","URLs"],"href":"/docs/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.\n\nThis 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":["Migrating from Sapper","Pages and layouts","<a> attributes"],"href":"/docs/migrating#pages-and-layouts-a-attributes","content":"sapper:prefetch is now data-sveltekit-preload-data\nsapper:noscroll is now data-sveltekit-noscroll","rank":1},{"breadcrumbs":["Migrating from Sapper","Endpoints"],"href":"/docs/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).\n\nSvelteKit 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.\n\nTo 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":["Migrating from Sapper","Integrations"],"href":"/docs/migrating#integrations","content":"See integrations for detailed information about integrations.","rank":1},{"breadcrumbs":["Migrating from Sapper","Integrations","HTML minifier"],"href":"/docs/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:\n\nimport { minify } from 'html-minifier';\nimport { building } from '$app/environment';\n\nconst minification_options = {\n collapseBooleanAttributes: true,\n collapseWhitespace: true,\n conservativeCollapse: true,\n decodeEntities: true,\n html5: true,\n ignoreCustomComments: [/^#/],\n minifyCSS: true,\n minifyJS: false,\n removeAttributeQuotes: true,\n removeComments: false, // some hydration code needs comments, so leave them in\n removeOptionalTags: true,\n removeRedundantAttributes: true,\n removeScriptTypeAttributes: true,\n removeStyleLinkTypeAttributes: true,\n sortAttributes: true,\n sortClassName: true\n};\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport async function handle({ event, resolve }) {\n let page = '';\n\n return resolve(event, {\n transformPageChunk: ({ html, done }) => {\n page += html;\n if (done) {\n return building ? minify(page, minification_options) : page;\n }\n }\n });\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":["Additional resources"],"href":"/docs/additional-resources","content":""},{"breadcrumbs":["Additional resources","FAQs"],"href":"/docs/additional-resources#faqs","content":"Please see the SvelteKit FAQ for solutions to common issues and helpful tips and tricks.\n\nThe Svelte FAQ and vite-plugin-svelte FAQ may also be helpful for questions deriving from those libraries."},{"breadcrumbs":["Additional resources","Examples"],"href":"/docs/additional-resources#examples","content":"We've written and published a few different SvelteKit sites as examples:\n\nsveltejs/realworld contains an example blog site\nA HackerNews clone\nkit.svelte.dev\nsvelte.dev\n\nSvelteKit 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."},{"breadcrumbs":["Additional resources","Support"],"href":"/docs/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."},{"breadcrumbs":["Glossary"],"href":"/docs/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."},{"breadcrumbs":["Glossary","CSR"],"href":"/docs/glossary#csr","content":"Client-side rendering (CSR) is the generation of the page contents in the web browser using JavaScript.\n\nIn SvelteKit, client-side rendering will be used by default, but you can turn off JavaScript with the csr = false page option."},{"breadcrumbs":["Glossary","Hydration"],"href":"/docs/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.\n\nIn SvelteKit, pages will be hydrated by default, but you can turn off JavaScript with the csr = false page option."},{"breadcrumbs":["Glossary","Prerendering"],"href":"/docs/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.\n\nNot all pages can be prerendered. The basic rule is this: for content to be prerenderable, any two users hitting it directly must get the same content from the server, and the page must not contain actions. 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.\n\nPre-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.\n\nIn SvelteKit, you can control prerendering with the prerender page option and prerender config in svelte.config.js."},{"breadcrumbs":["Glossary","Routing"],"href":"/docs/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.\n\nIn SvelteKit, client-side routing will be used by default, but you can skip it with data-sveltekit-reload."},{"breadcrumbs":["Glossary","SPA"],"href":"/docs/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 of the requested contents based on the requested URL. All navigation is handled on the client-side in a process called client-side routing with per-page contents being updated and common layout elements remaining largely unchanged. SPAs do not provide SSR, which has the shortcoming described above. However, some applications are not greatly impacted by these shortcomings such as a complex business application behind a login where SEO would not be important and it is known that users will be accessing the application from a consistent computing environment.\n\nIn SvelteKit, you can build an SPA with adapter-static."},{"breadcrumbs":["Glossary","SSG"],"href":"/docs/glossary#ssg","content":"Static Site Generation (SSG) is a term that refers to a site where every page is prerendered. SvelteKit was not built to do only static site generation like some tools and so may not scale as well to efficiently render a very large number of pages as tools built specifically for that purpose. However, in contrast to most purpose-built SSGs, SvelteKit does nicely allow for mixing and matching different rendering types on different pages. 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.\n\nIn 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."},{"breadcrumbs":["Glossary","SSR"],"href":"/docs/glossary#ssr","content":"Server-side rendering (SSR) is the generation of the page contents on the server. SSR is generally preferred for SEO. While some search engines can index content that is dynamically generated on the client-side it may take longer even in these cases. It also tends to improve perceived performance and makes your app accessible to users if JavaScript fails or is disabled (which happens more often than you probably think).\n\nIn SvelteKit, pages are server-side rendered by default. You can disable SSR with the ssr page option."}]}