@sveltejs/kit
Version:
SvelteKit is the fastest way to build Svelte apps
1,094 lines (1,050 loc) • 110 kB
TypeScript
/// <reference types="svelte" />
/// <reference types="vite/client" />
declare module '@sveltejs/kit' {
import type { CompileOptions } from 'svelte/compiler';
import type { PluginOptions } from '@sveltejs/vite-plugin-svelte';
/**
* [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing.
*/
export interface Adapter {
/**
* The name of the adapter, using for logging. Will typically correspond to the package name.
*/
name: string;
/**
* This function is called after SvelteKit has built your app.
* @param builder An object provided by SvelteKit that contains methods for adapting the app
*/
adapt: (builder: Builder) => MaybePromise<void>;
/**
* Checks called during dev and build to determine whether specific features will work in production with this adapter
*/
supports?: {
/**
* Test support for `read` from `$app/server`
* @param config The merged route config
*/
read?: (details: { config: any; route: { id: string } }) => boolean;
};
/**
* Creates an `Emulator`, which allows the adapter to influence the environment
* during dev, build and prerendering
*/
emulate?: () => MaybePromise<Emulator>;
}
export type LoadProperties<input extends Record<string, any> | void> = input extends void
? undefined // needs to be undefined, because void will break intellisense
: input extends Record<string, any>
? input
: unknown;
export type AwaitedActions<T extends Record<string, (...args: any) => any>> = OptionalUnion<
{
[Key in keyof T]: UnpackValidationError<Awaited<ReturnType<T[Key]>>>;
}[keyof T]
>;
// Takes a union type and returns a union type where each type also has all properties
// of all possible types (typed as undefined), making accessing them more ergonomic
type OptionalUnion<
U extends Record<string, any>, // not unknown, else interfaces don't satisfy this constraint
A extends keyof U = U extends U ? keyof U : never
> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;
const uniqueSymbol: unique symbol;
export interface ActionFailure<T extends Record<string, unknown> | undefined = undefined> {
status: number;
data: T;
[uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
}
type UnpackValidationError<T> =
T extends ActionFailure<infer X>
? X
: T extends void
? undefined // needs to be undefined, because void will corrupt union type
: T;
/**
* This object is passed to the `adapt` function of adapters.
* It contains various methods and properties that are useful for adapting the app.
*/
export interface Builder {
/** Print messages to the console. `log.info` and `log.minor` are silent unless Vite's `logLevel` is `info`. */
log: Logger;
/** Remove `dir` and all its contents. */
rimraf: (dir: string) => void;
/** Create `dir` and any required parent directories. */
mkdirp: (dir: string) => void;
/** The fully resolved `svelte.config.js`. */
config: ValidatedConfig;
/** Information about prerendered pages and assets, if any. */
prerendered: Prerendered;
/** An array of all routes (including prerendered) */
routes: RouteDefinition[];
// TODO 3.0 remove this method
/**
* Create separate functions that map to one or more routes of your app.
* @param fn A function that groups a set of routes into an entry point
* @deprecated Use `builder.routes` instead
*/
createEntries: (fn: (route: RouteDefinition) => AdapterEntry) => Promise<void>;
/**
* Find all the assets imported by server files belonging to `routes`
*/
findServerAssets: (routes: RouteDefinition[]) => string[];
/**
* Generate a fallback page for a static webserver to use when no route is matched. Useful for single-page apps.
*/
generateFallback: (dest: string) => Promise<void>;
/**
* Generate a module exposing build-time environment variables as `$env/dynamic/public`.
*/
generateEnvModule: () => void;
/**
* Generate a server-side manifest to initialise the SvelteKit [server](https://svelte.dev/docs/kit/@sveltejs-kit#Server) with.
* @param opts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated
*/
generateManifest: (opts: { relativePath: string; routes?: RouteDefinition[] }) => string;
/**
* Resolve a path to the `name` directory inside `outDir`, e.g. `/path/to/.svelte-kit/my-adapter`.
* @param name path to the file, relative to the build directory
*/
getBuildDirectory: (name: string) => string;
/** Get the fully resolved path to the directory containing client-side assets, including the contents of your `static` directory. */
getClientDirectory: () => string;
/** Get the fully resolved path to the directory containing server-side code. */
getServerDirectory: () => string;
/** Get the application path including any configured `base` path, e.g. `my-base-path/_app`. */
getAppPath: () => string;
/**
* Write client assets to `dest`.
* @param dest the destination folder
* @returns an array of files written to `dest`
*/
writeClient: (dest: string) => string[];
/**
* Write prerendered files to `dest`.
* @param dest the destination folder
* @returns an array of files written to `dest`
*/
writePrerendered: (dest: string) => string[];
/**
* Write server-side code to `dest`.
* @param dest the destination folder
* @returns an array of files written to `dest`
*/
writeServer: (dest: string) => string[];
/**
* Copy a file or directory.
* @param from the source file or directory
* @param to the destination file or directory
* @param opts.filter a function to determine whether a file or directory should be copied
* @param opts.replace a map of strings to replace
* @returns an array of files that were copied
*/
copy: (
from: string,
to: string,
opts?: {
filter?(basename: string): boolean;
replace?: Record<string, string>;
}
) => string[];
/**
* Compress files in `directory` with gzip and brotli, where appropriate. Generates `.gz` and `.br` files alongside the originals.
* @param directory The directory containing the files to be compressed
*/
compress: (directory: string) => Promise<void>;
}
export interface Config {
/**
* Options passed to [`svelte.compile`](https://svelte.dev/docs/svelte/svelte-compiler#CompileOptions).
* @default {}
*/
compilerOptions?: CompileOptions;
/**
* List of file extensions that should be treated as Svelte files.
* @default [".svelte"]
*/
extensions?: string[];
/** SvelteKit options */
kit?: KitConfig;
/** Preprocessor options, if any. Preprocessing can alternatively also be done through Vite's preprocessor capabilities. */
preprocess?: any;
/** `vite-plugin-svelte` plugin options. */
vitePlugin?: PluginOptions;
/** Any additional options required by tooling that integrates with Svelte. */
[key: string]: any;
}
export interface Cookies {
/**
* Gets a cookie that was previously set with `cookies.set`, or from the request headers.
* @param name the name of the cookie
* @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options)
*/
get: (name: string, opts?: import('cookie').CookieParseOptions) => string | undefined;
/**
* Gets all cookies that were previously set with `cookies.set`, or from the request headers.
* @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options)
*/
getAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string; value: string }>;
/**
* Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request.
*
* The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.
*
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
* @param name the name of the cookie
* @param value the cookie value
* @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
*/
set: (
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
) => void;
/**
* Deletes a cookie by setting its value to an empty string and setting the expiry date in the past.
*
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
* @param name the name of the cookie
* @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
*/
delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void;
/**
* Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response.
*
* The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.
*
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
*
* @param name the name of the cookie
* @param value the cookie value
* @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
*/
serialize: (
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
) => string;
}
/**
* A collection of functions that influence the environment during dev, build and prerendering
*/
export interface Emulator {
/**
* A function that is called with the current route `config` and `prerender` option
* and returns an `App.Platform` object
*/
platform?(details: { config: any; prerender: PrerenderOption }): MaybePromise<App.Platform>;
}
export interface KitConfig {
/**
* Your [adapter](https://svelte.dev/docs/kit/adapters) is run when executing `vite build`. It determines how the output is converted for different platforms.
* @default undefined
*/
adapter?: Adapter;
/**
* An object containing zero or more aliases used to replace values in `import` statements. These aliases are automatically passed to Vite and TypeScript.
*
* ```js
* /// file: svelte.config.js
* /// type: import('@sveltejs/kit').Config
* const config = {
* kit: {
* alias: {
* // this will match a file
* 'my-file': 'path/to/my-file.js',
*
* // this will match a directory and its contents
* // (`my-directory/x` resolves to `path/to/my-directory/x`)
* 'my-directory': 'path/to/my-directory',
*
* // an alias ending /* will only match
* // the contents of a directory, not the directory itself
* 'my-directory/*': 'path/to/my-directory/*'
* }
* }
* };
* ```
*
* > [!NOTE] The built-in `$lib` alias is controlled by `config.kit.files.lib` as it is used for packaging.
*
* > [!NOTE] You will need to run `npm run dev` to have SvelteKit automatically generate the required alias configuration in `jsconfig.json` or `tsconfig.json`.
* @default {}
*/
alias?: Record<string, string>;
/**
* The directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes.
*
* If `paths.assets` is specified, there will be two app directories — `${paths.assets}/${appDir}` and `${paths.base}/${appDir}`.
* @default "_app"
*/
appDir?: string;
/**
* [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) configuration. CSP helps to protect your users against cross-site scripting (XSS) attacks, by limiting the places resources can be loaded from. For example, a configuration like this...
*
* ```js
* /// file: svelte.config.js
* /// type: import('@sveltejs/kit').Config
* const config = {
* kit: {
* csp: {
* directives: {
* 'script-src': ['self']
* },
* // must be specified with either the `report-uri` or `report-to` directives, or both
* reportOnly: {
* 'script-src': ['self'],
* 'report-uri': ['/']
* }
* }
* }
* };
*
* export default config;
* ```
*
* ...would prevent scripts loading from external sites. SvelteKit will augment the specified directives with nonces or hashes (depending on `mode`) for any inline styles and scripts it generates.
*
* To add a nonce for scripts and links manually included in `src/app.html`, you may use the placeholder `%sveltekit.nonce%` (for example `<script nonce="%sveltekit.nonce%">`).
*
* When pages are prerendered, the CSP header is added via a `<meta http-equiv>` tag (note that in this case, `frame-ancestors`, `report-uri` and `sandbox` directives will be ignored).
*
* > [!NOTE] When `mode` is `'auto'`, SvelteKit will use nonces for dynamically rendered pages and hashes for prerendered pages. Using nonces with prerendered pages is insecure and therefore forbidden.
*
* > [!NOTE] Note that most [Svelte transitions](https://svelte.dev/tutorial/svelte/transition) work by creating an inline `<style>` element. If you use these in your app, you must either leave the `style-src` directive unspecified or add `unsafe-inline`.
*
* If this level of configuration is insufficient and you have more dynamic requirements, you can use the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle) to roll your own CSP.
*/
csp?: {
/**
* Whether to use hashes or nonces to restrict `<script>` and `<style>` elements. `'auto'` will use hashes for prerendered pages, and nonces for dynamically rendered pages.
*/
mode?: 'hash' | 'nonce' | 'auto';
/**
* Directives that will be added to `Content-Security-Policy` headers.
*/
directives?: CspDirectives;
/**
* Directives that will be added to `Content-Security-Policy-Report-Only` headers.
*/
reportOnly?: CspDirectives;
};
/**
* Protection against [cross-site request forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) attacks.
*/
csrf?: {
/**
* Whether to check the incoming `origin` header for `POST`, `PUT`, `PATCH`, or `DELETE` form submissions and verify that it matches the server's origin.
*
* To allow people to make `POST`, `PUT`, `PATCH`, or `DELETE` requests with a `Content-Type` of `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain` to your app from other origins, you will need to disable this option. Be careful!
* @default true
*/
checkOrigin?: boolean;
};
/**
* Whether 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`.
* Note 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).
* @default false
*/
embedded?: boolean;
/**
* Environment variable configuration
*/
env?: {
/**
* The directory to search for `.env` files.
* @default "."
*/
dir?: string;
/**
* A prefix that signals that an environment variable is safe to expose to client-side code. See [`$env/static/public`](https://svelte.dev/docs/kit/$env-static-public) and [`$env/dynamic/public`](https://svelte.dev/docs/kit/$env-dynamic-public). Note that Vite's [`envPrefix`](https://vitejs.dev/config/shared-options.html#envprefix) must be set separately if you are using Vite's environment variable handling - though use of that feature should generally be unnecessary.
* @default "PUBLIC_"
*/
publicPrefix?: string;
/**
* A 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`](https://svelte.dev/docs/kit/$env-static-private) and [`$env/dynamic/private`](https://svelte.dev/docs/kit/$env-dynamic-private).
* @default ""
* @since 1.21.0
*/
privatePrefix?: string;
};
/**
* Where to find various files within your project.
*/
files?: {
/**
* a place to put static files that should have stable URLs and undergo no processing, such as `favicon.ico` or `manifest.json`
* @default "static"
*/
assets?: string;
hooks?: {
/**
* The location of your client [hooks](https://svelte.dev/docs/kit/hooks).
* @default "src/hooks.client"
*/
client?: string;
/**
* The location of your server [hooks](https://svelte.dev/docs/kit/hooks).
* @default "src/hooks.server"
*/
server?: string;
/**
* The location of your universal [hooks](https://svelte.dev/docs/kit/hooks).
* @default "src/hooks"
* @since 2.3.0
*/
universal?: string;
};
/**
* your app's internal library, accessible throughout the codebase as `$lib`
* @default "src/lib"
*/
lib?: string;
/**
* a directory containing [parameter matchers](https://svelte.dev/docs/kit/advanced-routing#Matching)
* @default "src/params"
*/
params?: string;
/**
* the files that define the structure of your app (see [Routing](https://svelte.dev/docs/kit/routing))
* @default "src/routes"
*/
routes?: string;
/**
* the location of your service worker's entry point (see [Service workers](https://svelte.dev/docs/kit/service-workers))
* @default "src/service-worker"
*/
serviceWorker?: string;
/**
* the location of the template for HTML responses
* @default "src/app.html"
*/
appTemplate?: string;
/**
* the location of the template for fallback error responses
* @default "src/error.html"
*/
errorTemplate?: string;
};
/**
* Inline 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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.
*
* > [!NOTE] This results in fewer initial requests and can improve your [First Contentful Paint](https://web.dev/first-contentful-paint) score. However, it generates larger HTML output and reduces the effectiveness of browser caches. Use it advisedly.
* @default 0
*/
inlineStyleThreshold?: number;
/**
* An 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.
* @default [".js", ".ts"]
*/
moduleExtensions?: string[];
/**
* The directory that SvelteKit writes files to during `dev` and `build`. You should exclude this directory from version control.
* @default ".svelte-kit"
*/
outDir?: string;
/**
* Options related to the build output format
*/
output?: {
/**
* SvelteKit will preload the JavaScript modules needed for the initial page to avoid import 'waterfalls', resulting in faster application startup. There
* are three strategies with different trade-offs:
* - `modulepreload` - uses `<link rel="modulepreload">`. This delivers the best results in Chromium-based browsers, in Firefox 115+, and Safari 17+. It is ignored in older browsers.
* - `preload-js` - uses `<link rel="preload">`. Prevents waterfalls in Chromium and Safari, but Chromium will parse each module twice (once as a script, once as a module). Causes modules to be requested twice in Firefox. This is a good setting if you want to maximise performance for users on iOS devices at the cost of a very slight degradation for Chromium users.
* - `preload-mjs` - uses `<link rel="preload">` but with the `.mjs` extension which prevents double-parsing in Chromium. Some static webservers will fail to serve .mjs files with a `Content-Type: application/javascript` header, which will cause your application to break. If that doesn't apply to you, this is the option that will deliver the best performance for the largest number of users, until `modulepreload` is more widely supported.
* @default "modulepreload"
* @since 1.8.4
*/
preloadStrategy?: 'modulepreload' | 'preload-js' | 'preload-mjs';
/**
* The bundle strategy option affects how your app's JavaScript and CSS files are loaded.
* - If `'split'`, splits the app up into multiple .js/.css files so that they are loaded lazily as the user navigates around the app. This is the default, and is recommended for most scenarios.
* - If `'single'`, creates just one .js bundle and one .css file containing code for the entire app.
* - If `'inline'`, inlines all JavaScript and CSS of the entire app into the HTML. The result is usable without a server (i.e. you can just open the file in your browser).
*
* When using `'split'`, you can also adjust the bundling behaviour by setting [`output.experimentalMinChunkSize`](https://rollupjs.org/configuration-options/#output-experimentalminchunksize) and [`output.manualChunks`](https://rollupjs.org/configuration-options/#output-manualchunks) inside your Vite config's [`build.rollupOptions`](https://vite.dev/config/build-options.html#build-rollupoptions).
*
* If you want to inline your assets, you'll need to set Vite's [`build.assetsInlineLimit`](https://vite.dev/config/build-options.html#build-assetsinlinelimit) option to an appropriate size then import your assets through Vite.
*
* ```js
* /// file: vite.config.js
* import { sveltekit } from '@sveltejs/kit/vite';
* import { defineConfig } from 'vite';
*
* export default defineConfig({
* plugins: [sveltekit()],
* build: {
* // inline all imported assets
* assetsInlineLimit: Infinity
* }
* });
* ```
*
* ```svelte
* /// file: src/routes/+layout.svelte
* <script>
* // import the asset through Vite
* import favicon from './favicon.png';
* </script>
*
* <svelte:head>
* <!-- this asset will be inlined as a base64 URL -->
* <link rel="icon" href={favicon} />
* </svelte:head>
* ```
* @default 'split'
* @since 2.13.0
*/
bundleStrategy?: 'split' | 'single' | 'inline';
};
paths?: {
/**
* An 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.
* @default ""
*/
assets?: '' | `http://${string}` | `https://${string}`;
/**
* A 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`](https://svelte.dev/docs/kit/$app-paths#base) 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.
* @default ""
*/
base?: '' | `/${string}`;
/**
* Whether to use relative asset paths.
*
* If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML.
* If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL
*
* [Single-page app](https://svelte.dev/docs/kit/single-page-apps) fallback pages will always use absolute paths, regardless of this setting.
*
* If your app uses a `<base>` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `<base>` URL rather than the current page.
*
* In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config.
*
* @default true
* @since 1.9.0
*/
relative?: boolean;
};
/**
* See [Prerendering](https://svelte.dev/docs/kit/page-options#prerender).
*/
prerender?: {
/**
* How 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.
* @default 1
*/
concurrency?: number;
/**
* Whether SvelteKit should find pages to prerender by following links from `entries`.
* @default true
*/
crawl?: boolean;
/**
* An 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).
* @default ["*"]
*/
entries?: Array<'*' | `/${string}`>;
/**
* How to respond to HTTP errors encountered while prerendering the app.
*
* - `'fail'` — fail the build
* - `'ignore'` - silently ignore the failure and continue
* - `'warn'` — continue, but print a warning
* - `(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
*
* ```js
* /// file: svelte.config.js
* /// type: import('@sveltejs/kit').Config
* const config = {
* kit: {
* prerender: {
* handleHttpError: ({ path, referrer, message }) => {
* // ignore deliberate link to shiny 404 page
* if (path === '/not-found' && referrer === '/blog/how-we-built-our-404-page') {
* return;
* }
*
* // otherwise fail the build
* throw new Error(message);
* }
* }
* }
* };
* ```
*
* @default "fail"
* @since 1.15.7
*/
handleHttpError?: PrerenderHttpErrorHandlerValue;
/**
* How to respond when hash links from one prerendered page to another don't correspond to an `id` on the destination page.
*
* - `'fail'` — fail the build
* - `'ignore'` - silently ignore the failure and continue
* - `'warn'` — continue, but print a warning
* - `(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
*
* @default "fail"
* @since 1.15.7
*/
handleMissingId?: PrerenderMissingIdHandlerValue;
/**
* How to respond when an entry generated by the `entries` export doesn't match the route it was generated from.
*
* - `'fail'` — fail the build
* - `'ignore'` - silently ignore the failure and continue
* - `'warn'` — continue, but print a warning
* - `(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
*
* @default "fail"
* @since 1.16.0
*/
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
/**
* The value of `url.origin` during prerendering; useful if it is included in rendered content.
* @default "http://sveltekit-prerender"
*/
origin?: string;
};
router?: {
/**
* What type of client-side router to use.
* - `'pathname'` is the default and means the current URL pathname determines the route
* - `'hash'` means the route is determined by `location.hash`. In this case, SSR and prerendering are disabled. This is only recommended if `pathname` is not an option, for example because you don't control the webserver where your app is deployed.
* It comes with some caveats: you can't use server-side rendering (or indeed any server logic), and you have to make sure that the links in your app all start with #/, or they won't work. Beyond that, everything works exactly like a normal SvelteKit app.
*
* @default "pathname"
* @since 2.14.0
*/
type?: 'pathname' | 'hash';
/**
* How to determine which route to load when navigating to a new page.
*
* By default, SvelteKit will serve a route manifest to the browser.
* When navigating, this manifest is used (along with the `reroute` hook, if it exists) to determine which components to load and which `load` functions to run.
* Because everything happens on the client, this decision can be made immediately. The drawback is that the manifest needs to be
* loaded and parsed before the first navigation can happen, which may have an impact if your app contains many routes.
*
* Alternatively, SvelteKit can determine the route on the server. This means that for every navigation to a path that has not yet been visited, the server will be asked to determine the route.
* This has several advantages:
* - The client does not need to load the routing manifest upfront, which can lead to faster initial page loads
* - The list of routes is hidden from public view
* - The server has an opportunity to intercept each navigation (for example through a middleware), enabling (for example) A/B testing opaque to SvelteKit
* The drawback is that for unvisited paths, resolution will take slightly longer (though this is mitigated by [preloading](https://svelte.dev/docs/kit/link-options#data-sveltekit-preload-data)).
*
* > [!NOTE] When using server-side route resolution and prerendering, the resolution is prerendered along with the route itself.
*
* @default "client"
* @since 2.17.0
*/
resolution?: 'client' | 'server';
};
serviceWorker?: {
/**
* Whether to automatically register the service worker, if it exists.
* @default true
*/
register?: boolean;
/**
* Determine which files in your `static` directory will be available in `$service-worker.files`.
* @default (filename) => !/\.DS_Store/.test(filename)
*/
files?(filepath: string): boolean;
};
typescript?: {
/**
* A function that allows you to edit the generated `tsconfig.json`. You can mutate the config (recommended) or return a new one.
* This is useful for extending a shared `tsconfig.json` in a monorepo root, for example.
* @default (config) => config
* @since 1.3.0
*/
config?: (config: Record<string, any>) => Record<string, any> | void;
};
/**
* Client-side navigation can be buggy if you deploy a new version of your app while people are using it. If the code for the new page is already loaded, it may have stale content; if it isn't, the app's route manifest may point to a JavaScript file that no longer exists.
* SvelteKit helps you solve this problem through version management.
* If 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.
* Not 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`:
* ```html
* /// file: +layout.svelte
* <script>
* import { beforeNavigate } from '$app/navigation';
* import { updated } from '$app/state';
*
* beforeNavigate(({ willUnload, to }) => {
* if (updated.current && !willUnload && to?.url) {
* location.href = to.url.href;
* }
* });
* </script>
* ```
*
* If you set `pollInterval` to a non-zero value, SvelteKit will poll for new versions in the background and set the value of [`updated.current`](https://svelte.dev/docs/kit/$app-state#updated) `true` when it detects one.
*/
version?: {
/**
* The current app version string. If specified, this must be deterministic (e.g. a commit ref rather than `Math.random()` or `Date.now().toString()`), otherwise defaults to a timestamp of the build.
*
* For example, to use the current commit hash, you could do use `git rev-parse HEAD`:
*
* ```js
* /// file: svelte.config.js
* import * as child_process from 'node:child_process';
*
* export default {
* kit: {
* version: {
* name: child_process.execSync('git rev-parse HEAD').toString().trim()
* }
* }
* };
* ```
*/
name?: string;
/**
* The interval in milliseconds to poll for version changes. If this is `0`, no polling occurs.
* @default 0
*/
pollInterval?: number;
};
}
/**
* The [`handle`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle) hook runs every time the SvelteKit server receives a [request](https://svelte.dev/docs/kit/web-standards#Fetch-APIs-Request) and
* determines the [response](https://svelte.dev/docs/kit/web-standards#Fetch-APIs-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).
*/
export type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}) => MaybePromise<Response>;
/**
* The server-side [`handleError`](https://svelte.dev/docs/kit/hooks#Shared-hooks-handleError) hook runs when an unexpected error is thrown while responding to a request.
*
* If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event.
* Make sure that this function _never_ throws an error.
*/
export type HandleServerError = (input: {
error: unknown;
event: RequestEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;
/**
* The client-side [`handleError`](https://svelte.dev/docs/kit/hooks#Shared-hooks-handleError) hook runs when an unexpected error is thrown while navigating.
*
* If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event.
* Make sure that this function _never_ throws an error.
*/
export type HandleClientError = (input: {
error: unknown;
event: NavigationEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;
/**
* The [`handleFetch`](https://svelte.dev/docs/kit/hooks#Server-hooks-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)
*/
export type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>;
/**
* The [`init`](https://svelte.dev/docs/kit/hooks#Shared-hooks-init) will be invoked before the server responds to its first request
* @since 2.10.0
*/
export type ServerInit = () => MaybePromise<void>;
/**
* The [`init`](https://svelte.dev/docs/kit/hooks#Shared-hooks-init) will be invoked once the app starts in the browser
* @since 2.10.0
*/
export type ClientInit = () => MaybePromise<void>;
/**
* The [`reroute`](https://svelte.dev/docs/kit/hooks#Universal-hooks-reroute) hook allows you to modify the URL before it is used to determine which route to render.
* @since 2.3.0
*/
export type Reroute = (event: { url: URL; fetch: typeof fetch }) => MaybePromise<void | string>;
/**
* The [`transport`](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport) hook allows you to transport custom types across the server/client boundary.
*
* Each transporter has a pair of `encode` and `decode` functions. On the server, `encode` determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or `false` otherwise).
*
* In the browser, `decode` turns the encoding back into an instance of the custom type.
*
* ```ts
* import type { Transport } from '@sveltejs/kit';
*
* declare class MyCustomType {
* data: any
* }
*
* // hooks.js
* export const transport: Transport = {
* MyCustomType: {
* encode: (value) => value instanceof MyCustomType && [value.data],
* decode: ([data]) => new MyCustomType(data)
* }
* };
* ```
* @since 2.11.0
*/
export type Transport = Record<string, Transporter>;
/**
* A member of the [`transport`](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport) hook.
*/
export interface Transporter<
T = any,
U = Exclude<any, false | 0 | '' | null | undefined | typeof NaN>
> {
encode: (value: T) => false | U;
decode: (data: U) => T;
}
/**
* The generic form of `PageLoad` and `LayoutLoad`. You should import those from `./$types` (see [generated types](https://svelte.dev/docs/kit/types#Generated-types))
* rather than using `Load` directly.
*/
export type Load<
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
InputData extends Record<string, unknown> | null = Record<string, any> | null,
ParentData extends Record<string, unknown> = Record<string, any>,
OutputData extends Record<string, unknown> | void = Record<string, any> | void,
RouteId extends string | null = string | null
> = (event: LoadEvent<Params, InputData, ParentData, RouteId>) => MaybePromise<OutputData>;
/**
* The generic form of `PageLoadEvent` and `LayoutLoadEvent`. You should import those from `./$types` (see [generated types](https://svelte.dev/docs/kit/types#Generated-types))
* rather than using `LoadEvent` directly.
*/
export interface LoadEvent<
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
Data extends Record<string, unknown> | null = Record<string, any> | null,
ParentData extends Record<string, unknown> = Record<string, any>,
RouteId extends string | null = string | null
> extends NavigationEvent<Params, RouteId> {
/**
* `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:
*
* - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
* - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
* - Internal 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.
* - During 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`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle)
* - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.
*
* You can learn more about making credentialed requests with cookies [here](https://svelte.dev/docs/kit/load#Cookies)
*/
fetch: typeof fetch;
/**
* Contains the data returned by the route's server `load` function (in `+layout.server.js` or `+page.server.js`), if any.
*/
data: Data;
/**
* If 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:
*
* ```js
* /// file: src/routes/blog/+page.js
* export async function load({ fetch, setHeaders }) {
* const url = `https://cms.example.com/articles.json`;
* const response = await fetch(url);
*
* setHeaders({
* age: response.headers.get('age'),
* 'cache-control': response.headers.get('cache-control')
* });
*
* return response.json();
* }
* ```
*
* Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.
*
* You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API in a server-only `load` function instead.
*
* `setHeaders` has no effect when a `load` function runs in the browser.
*/
setHeaders: (headers: Record<string, string>) => void;
/**
* `await parent()` returns data from parent `+layout.js` `load` functions.
* Implicitly, a missing `+layout.js` is treated as a `({ data }) => data` function, meaning that it will return and forward data from parent `+layout.server.js` files.
*
* Be careful not to introduce accidental waterfalls when using `await parent()`. If for example you only want to merge parent data into the returned output, call it _after_ fetching your other data.
*/
parent: () => Promise<ParentData>;
/**
* This function declares that the `load` function has a _dependency_ on one or more URLs or custom identifiers, which can subsequently be used with [`invalidate()`](https://svelte.dev/docs/kit/$app-navigation#invalidate) to cause `load` to rerun.
*
* Most of the time you won't need this, as `fetch` calls `depends` on your behalf — it's only necessary if you're using a custom API client that bypasses `fetch`.
*
* URLs can be absolute or relative to the page being loaded, and must be [encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).
*
* Custom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the [URI specification](https://www.rfc-editor.org/rfc/rfc3986.html).
*
* The following example shows how to use `depends` to register a dependency on a custom identifier, which is `invalidate`d after a button click, making the `load` function rerun.
*
* ```js
* /// file: src/routes/+page.js
* let count = 0;
* export async function load({ depends }) {
* depends('increase:count');
*
* return { count: count++ };
* }
* ```
*
* ```html
* /// file: src/routes/+page.svelte
* <script>
* import { invalidate } from '$app/navigation';
*
* let { data } = $props();
*
* const increase = async () => {
* await invalidate('increase:count');
* }
* </script>
*
* <p>{data.count}<p>
* <button on:click={increase}>Increase Count</button>
* ```
*/
depends: (...deps: Array<`${string}:${string}`>) => void;
/**
* Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example:
*
* ```js
* /// file: src/routes/+page.server.js
* export async function load({ untrack, url }) {
* // Untrack url.pathname so that path changes don't trigger a rerun
* if (untrack(() => url.pathname === '/')) {
* return { message: 'Welcome!' };
* }
* }
* ```
*/
untrack: <T>(fn: () => T) => T;
}
export interface NavigationEvent<
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
RouteId extends string | null = string | null
> {
/**
* The parameters of the current page - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object
*/
params: Params;
/**
* Info about the current route
*/
route: {
/**
* The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
*/
id: RouteId;
};
/**
* The URL of the current page
*/
url: URL;
}
/**
* Information about the target of a specific navigation.
*/
export interface NavigationTarget {
/**
* Parameters of the target page - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object.
* Is `null` if the target is not part of the SvelteKit app (could not be resolved to a route).
*/
params: Record<string, string> | null;
/**
* Info about the target route
*/
route: {
/**
* The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
*/
id: string | null;
};
/**
* The URL that is navigated to
*/
url: URL;
}
/**
* - `enter`: The app has hydrated/started
* - `form`: The user submitted a `<form>` with a GET method
* - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document
* - `link`: Navigation was triggered by a link click
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
* - `popstate`: Navigation was triggered by back/forward navigation
*/
export type NavigationType = 'enter' | 'form' | 'leave' | 'link' | 'goto' | 'popstate';
export interface Navigation {
/**
* Where navigation was triggered from
*/
from: NavigationTarget | null;
/**
* Where navigation is going to/has gone to
*/
to: NavigationTarget | null;
/**
* The type of navigation:
* - `form`: The user submitted a `<form>`
* - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring
* - `link`: Navigation was triggered by a link click
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
* - `popstate`: Navigation was triggered by back/forward navigation
*/
type: Exclude<NavigationType, 'enter'>;
/**
* Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)
*/
willUnload: boolean;
/**
* In case of a history back/forward navigation, the number of steps to go back/forward
*/
delta?: number;
/**
* A promise that resolves once the navigation is complete, and rejects if the navigation
* fails or is aborted. In the case of a `willUnload` navigation, the promise will never resolve
*/
complete: Promise<void>;
}
/**
* The argument passed to [`beforeNavigate`](https://svelte.dev/docs/kit/$app-navigation#beforeNavigate) callbacks.
*/
export interface BeforeNavigate extends Navigation {
/**
* Call this to prevent the navigation from starting.
*/
cancel: () => void;
}
/**
* The argument passed to [`onNavigate`](https://svelte.dev/docs/kit/$app-navigation#onNavigate) callbacks.
*/
export interface OnNavigate extends Navigation {
/**
* The type of navigation:
* - `form`: The user submitted a `<form>`
* - `link`: Navigation was triggered by a link click
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
* - `popstate`: Navigation was triggered by back/forward navigation
*/
type: Exclude<NavigationType, 'enter' | 'leave'>;
/**
* Since `onNavigate` callbacks are called immediately before a client-side navigation, they will never be called with a navigation that unloads the page.
*/
willUnload: false;
}
/**
* The argument passed to [`afterNavigate`](https://svelte.dev/docs/kit/$app-navigation#afterNavigate) callbacks.
*/
export interface AfterNavigate extends Omit<Navigation, 'type'> {
/**
* The type of navigation:
* - `enter`: The app has hydrated/started
* - `form`: The user submitted a `<form>`
* - `link`: Navigation was triggered by a link click
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
* - `popstate`: Navigation was triggered by back/forward navigation
*/
type: Exclude<NavigationType, 'leave'>;
/**
* Since `afterNavigate` callbacks are called after a nav