Hooks
'Hooks' are app-wide functions you declare that SvelteKit will call in response to specific events, giving you fine-grained control over the framework's behaviour.
There are three hooks files, all optional:
src/hooks.server.js— your app's server hookssrc/hooks.client.js— your app's client hookssrc/hooks.js— your app's hooks that run on both the client and server
Code in these modules will run when the application starts up, making them useful for initializing database clients and so on.
handle
Can be added to
src/hooks.server.js
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).
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}): MaybePromise<Response>
handle({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) {
if (event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.url: URLThe requested URL.
Inside query functions (including query.batch and query.live), accessing this property throws an error.
Pass values from the page as arguments to the query instead. Inside form and command functions it relates to the page
the remote function was called from, not the URL of the endpoint SvelteKit creates for the remote function. Never use it
to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
url.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('/custom')) {
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => ResponseThe Response interface of the Fetch API represents the response to a request.
Response('custom response');
}
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event);
return const response: Responseresponse;
}import type { type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle } from '@sveltejs/kit';
export const const handle: Handlehandle: type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle = async ({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) => {
if (event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.url: URLThe requested URL.
Inside query functions (including query.batch and query.live), accessing this property throws an error.
Pass values from the page as arguments to the query instead. Inside form and command functions it relates to the page
the remote function was called from, not the URL of the endpoint SvelteKit creates for the remote function. Never use it
to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
url.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('/custom')) {
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => ResponseThe Response interface of the Fetch API represents the response to a request.
Response('custom response');
}
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event);
return const response: Responseresponse;
};Requests for static assets — which includes pages that were already prerendered — are not handled by SvelteKit.
If the handle hook runs as part of a remote function request initiated by the client, route, params and url relate to the page the remote function was called from, not the URL of the endpoint SvelteKit creates for the remote function. Never use them to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated. Queries are also not re-run when the user navigates (unless the argument to the query changes as a result of navigation), and so you should be mindful of how you use these values.
If unimplemented, defaults to ({ event, resolve }) => resolve(event).
During prerendering, SvelteKit crawls your pages for links and renders each route it finds. Rendering the route invokes the handle function (and all other route dependencies, like load). If you need to exclude some code from running during this phase, check that the app is not building beforehand.
You can define multiple handle functions and execute them with the sequence helper function.
resolve also supports a second, optional parameter that gives you more control over how the response will be rendered. That parameter is an object that can have the following fields:
transformPageChunk(opts: { html: string, done: boolean }): MaybePromise<string | undefined>— applies custom transforms to HTML. Ifdoneis 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.filterSerializedResponseHeaders(name: string, value: string): boolean— determines which headers should be included in serialized responses when aloadfunction loads a resource withfetch. By default, none will be included.preload(input: { type: 'js' | 'css' | 'font' | 'asset', path: string }): boolean— determines which files should be preloaded. Files are preloaded via<link>tags added to the<head>tag; ifoutput.linkHeaderPreloadis enabled, dynamically rendered pages use theLinkresponse header instead. The method is called with each file that was found at build time while constructing the code chunks — so if you for example haveimport './styles.cssin your+page.svelte,preloadwill be called with the resolved path to that CSS file when visiting that page. Note that in dev modepreloadis 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,jsandcssfiles will be preloaded.assetfiles are not preloaded at all currently, but we may add this later after evaluating feedback.
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}): MaybePromise<Response>
handle({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) {
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event, {
ResolveOptions.transformPageChunk?: ((input: {
html: string;
done: boolean;
}) => MaybePromise<string | undefined>) | 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.
transformPageChunk: ({ html: stringhtml }) => html: stringhtml.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)Replaces text in a string, using a regular expression or search string.
replace('old', 'new'),
ResolveOptions.filterSerializedResponseHeaders?: ((name: string, value: string) => boolean) | undefinedDetermines which headers should be included in serialized responses when a load function loads a resource with fetch.
By default, none will be included.
filterSerializedResponseHeaders: (name: stringname) => name: stringname.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('x-'),
ResolveOptions.preload?: ((input: {
type: "font" | "css" | "js" | "asset";
path: string;
}) => boolean) | undefined
Determines which files should be preloaded. Files are preloaded via <link> tags added to the
<head> tag; if output.linkHeaderPreload is enabled, dynamically rendered pages use the
Link response header instead.
By default, js and css files will be preloaded.
preload: ({ type: "font" | "css" | "js" | "asset"type, path: stringpath }) => type: "font" | "css" | "js" | "asset"type === 'js' || path: stringpath.String.includes(searchString: string, position?: number): booleanReturns true if searchString appears as a substring of the result of converting this
object to a String, at one or more positions that are
greater than or equal to position; otherwise, returns false.
includes('/important/')
});
return const response: Responseresponse;
}import type { type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle } from '@sveltejs/kit';
export const const handle: Handlehandle: type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle = async ({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) => {
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event, {
ResolveOptions.transformPageChunk?: ((input: {
html: string;
done: boolean;
}) => MaybePromise<string | undefined>) | 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.
transformPageChunk: ({ html: stringhtml }) => html: stringhtml.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)Replaces text in a string, using a regular expression or search string.
replace('old', 'new'),
ResolveOptions.filterSerializedResponseHeaders?: ((name: string, value: string) => boolean) | undefinedDetermines which headers should be included in serialized responses when a load function loads a resource with fetch.
By default, none will be included.
filterSerializedResponseHeaders: (name: stringname) => name: stringname.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('x-'),
ResolveOptions.preload?: ((input: {
type: "font" | "css" | "js" | "asset";
path: string;
}) => boolean) | undefined
Determines which files should be preloaded. Files are preloaded via <link> tags added to the
<head> tag; if output.linkHeaderPreload is enabled, dynamically rendered pages use the
Link response header instead.
By default, js and css files will be preloaded.
preload: ({ type: "font" | "css" | "js" | "asset"type, path: stringpath }) => type: "font" | "css" | "js" | "asset"type === 'js' || path: stringpath.String.includes(searchString: string, position?: number): booleanReturns true if searchString appears as a substring of the result of converting this
object to a String, at one or more positions that are
greater than or equal to position; otherwise, returns false.
includes('/important/')
});
return const response: Responseresponse;
};Note that resolve(...) will never throw an error, it will always return a Promise<Response> with the appropriate status code. If an error is thrown elsewhere during handle, it is treated as fatal, and SvelteKit will respond with a JSON representation of the error or a fallback error page — which can be customised via src/error.html — depending on the Accept header. You can read more about error handling here.
locals
To add custom data to the request, which is passed to handlers in +server.js and server load functions, populate the event.locals object, as shown below.
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}): MaybePromise<Response>
handle({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) {
event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.locals: App.LocalsContains custom data that was added to the request within the server handle hook.
locals.App.Locals.user: Useruser = await const getUserInformation: (cookie: string | void) => Promise<User>getUserInformation(event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.cookies: CookiesGet or set cookies related to the current request
cookies.Cookies.get: (name: string, opts?: ParseOptions) => string | undefinedGets a cookie that was previously set with cookies.set, or from the request headers.
get('sessionid'));
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event);
// Note that modifying response headers isn't always safe.
// Response objects can have immutable headers
// (e.g. Response.redirect() returned from an endpoint).
// Modifying immutable headers throws a TypeError.
// In that case, clone the response or avoid creating a
// response object with immutable headers.
const response: Responseresponse.Response.headers: HeadersThe headers read-only property of the Response interface contains the Headers object associated with the response.
headers.Headers.set(name: string, value: string): voidThe set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.
set('x-custom-header', 'potato');
return const response: Responseresponse;
}import type { type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle } from '@sveltejs/kit';
export const const handle: Handlehandle: type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>;
}) => MaybePromise<Response>
The handle hook runs every time the SvelteKit server receives a request 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).
Handle = async ({ event: RequestEvent<Record<string, string>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve }) => {
event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.locals: App.LocalsContains custom data that was added to the request within the server handle hook.
locals.App.Locals.user: Useruser = await const getUserInformation: (cookie: string | void) => Promise<User>getUserInformation(event: RequestEvent<Record<string, string>, string | null>event.RequestEvent<Record<string, string>, string | null>.cookies: CookiesGet or set cookies related to the current request
cookies.Cookies.get: (name: string, opts?: ParseOptions) => string | undefinedGets a cookie that was previously set with cookies.set, or from the request headers.
get('sessionid'));
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>resolve(event: RequestEvent<Record<string, string>, string | null>event);
// Note that modifying response headers isn't always safe.
// Response objects can have immutable headers
// (e.g. Response.redirect() returned from an endpoint).
// Modifying immutable headers throws a TypeError.
// In that case, clone the response or avoid creating a
// response object with immutable headers.
const response: Responseresponse.Response.headers: HeadersThe headers read-only property of the Response interface contains the Headers object associated with the response.
headers.Headers.set(name: string, value: string): voidThe set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.
set('x-custom-header', 'potato');
return const response: Responseresponse;
};handleFetch
Can be added to
src/hooks.server.js
This function allows you to modify (or replace) the result of an event.fetch call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.
For example, your load function might make a request to a public URL like https://api.yourapp.com when the user performs a client-side navigation to the respective page, but during SSR it might make sense to hit the API directly (bypassing whatever proxies and load balancers sit between it and the public internet).
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function function handleFetch(input: {
event: RequestEvent;
request: Request;
fetch: typeof globalThis.fetch;
}): MaybePromise<Response>
handleFetch({ request: Requestrequest, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) {
if (request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('https://api.yourapp.com/')) {
// clone the original request, but change the URL
request: Requestrequest = new var Request: new (input: RequestInfo | URL, init?: RequestInit) => RequestThe Request interface of the Fetch API represents a resource request.
Request(
request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)Replaces text in a string, using a regular expression or search string.
replace('https://api.yourapp.com/', 'http://localhost:9999/'),
request: Requestrequest
);
}
return fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
}import type { type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>
The handleFetch hook allows you to modify (or replace) the result of an event.fetch call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.
HandleFetch } from '@sveltejs/kit';
export const const handleFetch: HandleFetchhandleFetch: type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>
The handleFetch hook allows you to modify (or replace) the result of an event.fetch call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.
HandleFetch = async ({ request: Requestrequest, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
if (request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('https://api.yourapp.com/')) {
// clone the original request, but change the URL
request: Requestrequest = new var Request: new (input: RequestInfo | URL, init?: RequestInit) => RequestThe Request interface of the Fetch API represents a resource request.
Request(
request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)Replaces text in a string, using a regular expression or search string.
replace('https://api.yourapp.com/', 'http://localhost:9999/'),
request: Requestrequest
);
}
return fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
};Requests made with event.fetch follow the browser's credentials model — for same-origin requests, cookie and authorization headers are forwarded unless the credentials option is set to "omit". For cross-origin requests, cookie will be included if the request URL belongs to a subdomain of the app — for example if your app is on my-domain.com, and your API is on api.my-domain.com, cookies will be included in the request.
There is one caveat: if your app and your API are on sibling subdomains — www.my-domain.com and api.my-domain.com for example — then a cookie belonging to a common parent domain like my-domain.com will not be included, because SvelteKit has no way to know which domain the cookie belongs to. In these cases you will need to manually include the cookie using handleFetch:
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function function handleFetch(input: {
event: RequestEvent;
request: Request;
fetch: typeof globalThis.fetch;
}): MaybePromise<Response>
handleFetch({ event: RequestEvent<Record<string, string>, string | null>event, request: Requestrequest, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) {
if (request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('https://api.my-domain.com/')) {
request: Requestrequest.Request.headers: HeadersThe headers read-only property of the Request interface contains the Headers object associated with the request.
headers.Headers.set(name: string, value: string): voidThe set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.
set('cookie', event.request.headers.get('cookie'));
}
return fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
}import type { type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>
The handleFetch hook allows you to modify (or replace) the result of an event.fetch call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.
HandleFetch } from '@sveltejs/kit';
export const const handleFetch: HandleFetchhandleFetch: type HandleFetch = (input: {
event: RequestEvent;
request: Request;
fetch: typeof fetch;
}) => MaybePromise<Response>
The handleFetch hook allows you to modify (or replace) the result of an event.fetch call that runs on the server (or during prerendering) inside an endpoint, load, action, handle, handleError or reroute.
HandleFetch = async ({ event: RequestEvent<Record<string, string>, string | null>event, request: Requestrequest, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
if (request: Requestrequest.Request.url: stringThe url read-only property of the Request interface contains the URL of the request.
url.String.startsWith(searchString: string, position?: number): booleanReturns true if the sequence of elements of searchString converted to a String is the
same as the corresponding elements of this object (converted to a String) starting at
position. Otherwise returns false.
startsWith('https://api.my-domain.com/')) {
request: Requestrequest.Request.headers: HeadersThe headers read-only property of the Request interface contains the Headers object associated with the request.
headers.Headers.set(name: string, value: string): voidThe set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.
set('cookie', event.request.headers.get('cookie'));
}
return fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
};handleError
Can be added to
src/hooks.server.jsandsrc/hooks.client.js
This function is called for every error thrown while loading, rendering, or responding to a request. This allows for two things:
- you can log the error
- you 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 becomes the value of
page.error.
Alongside the event, the hook receives a kind discriminant that tells you where the error came from, and the error itself:
'app'— the error came from your app viaerror(...)erroris the error body, which matchesApp.Error- defaults to the error body itself
'framework'— the error came from SvelteKit, such as a 404, 405 or 413erroris{ status, message }, wheremessageis safe text likeNot Found- defaults to that same
{ status, message }
'validation'(server only) — the error came from validating a remote function argument against its Standard Schemaerroris{ status: 400, message: 'Bad Request' }, andissuescontains the validation issues- defaults to the
errorobject; the issues are not exposed unless you explicitly return them - to access validation-library-specific issue properties, parameterise
HandleServerErrorwith the issue type, for exampleHandleServerError<CustomIssue>
'unknown'— we don't know what went wrong; the error was thrown by your code, or code it callserroris the thrown value, which may contain information unsafe to expose- defaults to
{ status: 500, message: 'Internal Error' }
The next section, Errors, explains the other categories in more detail. Redirects are not errors, and never reach the hook.
The hook returns an object matching App.Error, in which status and message are optional — return them only to override the defaults in the list above.
If you augment
App.Errorwith additional required properties, the hook must return them.
To add more information to the page.error object in a type-safe way, augment the existing App.Error interface with your additional properties. The built-in status and message properties are already present and do not need to be redeclared. For example, you can add a tracking ID for users to quote when contacting support:
declare global {
namespace App {
interface interface App.ErrorDefines the common shape of expected and unexpected errors. Expected errors are thrown using the error function. Every error passes through the handleError hooks, which must return this shape (with status and message optional, since they default to those of the caught error).
Error {
App.Error.errorId: stringerrorId: string;
}
}
}
export {};import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
module "@sentry/sveltekit"Sentry.const init: (opts: any) => voidinit({/*...*/})
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function function handleError(input: CaughtError<StandardSchemaV1<Input = unknown, Output = Input>.Issue> & {
event: RequestEvent;
}): MaybePromise<void | AppErrorWithOptionalDefaults>
handleError({ kind: "app" | "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind, error: unknownThe caught error. Its type depends on kind
error, event: RequestEvent<Record<string, string>, string | null>event }) {
if (kind: "app" | "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind === 'app') {
// you created this error with `error(...)`, so it already
// matches `App.Error` — pass it through unchanged
return error: App.ErrorThe caught error. Its type depends on kind
error;
}
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
Available only in secure contexts.
randomUUID();
if (kind: "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind === 'framework') {
// a 404 (or similar) — `error.status` and `error.message` are safe to
// expose, so we keep them and just add our own property
return { ...error: {
status: number;
message: string;
}
The caught error. Its type depends on kind
error, errorId };
}
// example integration with https://sentry.io/
module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownThe caught error. Its type depends on kind
error, {
extra: {
event: RequestEvent<Record<string, string>, string | null>;
errorId: `${string}-${string}-${string}-${string}-${string}`;
}
extra: { event: RequestEvent<Record<string, string>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId }
});
// `status` and `message` are optional — we only override `message`,
// so the status stays at its default of 500
return {
message?: string | undefinedmessage: 'Whoops!',
errorId
};
}import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
import type { type HandleServerError<Issue extends StandardSchemaV1.Issue = StandardSchemaV1.Issue> = (input: CaughtError<Issue> & {
event: RequestEvent;
}) => MaybePromise<void | AppErrorWithOptionalDefaults>
The server-side handleError hook runs for every error thrown while responding to a request, except redirects.
The kind property discriminates between app errors (thrown with the error helper),
framework errors (generated by SvelteKit itself, such as 404s), validation errors (caused by invalid remote function arguments)
and unknown errors (thrown by your code, or code it calls).
The hook returns an object matching App.Error, in which status and message are optional — return them only to
override the defaults. Omitted properties are inherited from the caught error: the body passed to error(...) for app errors,
the status and safe message for framework and validation errors, and 500 / 'Internal Error' for unknown errors. Return nothing to
keep the defaults entirely (if you augment App.Error with required properties, you must return those).
Make sure that this function never throws an error.
HandleServerError } from '@sveltejs/kit';
module "@sentry/sveltekit"Sentry.const init: (opts: any) => voidinit({/*...*/})
export const const handleError: HandleServerErrorhandleError: type HandleServerError<Issue extends StandardSchemaV1.Issue = StandardSchemaV1.Issue> = (input: CaughtError<Issue> & {
event: RequestEvent;
}) => MaybePromise<void | AppErrorWithOptionalDefaults>
The server-side handleError hook runs for every error thrown while responding to a request, except redirects.
The kind property discriminates between app errors (thrown with the error helper),
framework errors (generated by SvelteKit itself, such as 404s), validation errors (caused by invalid remote function arguments)
and unknown errors (thrown by your code, or code it calls).
The hook returns an object matching App.Error, in which status and message are optional — return them only to
override the defaults. Omitted properties are inherited from the caught error: the body passed to error(...) for app errors,
the status and safe message for framework and validation errors, and 500 / 'Internal Error' for unknown errors. Return nothing to
keep the defaults entirely (if you augment App.Error with required properties, you must return those).
Make sure that this function never throws an error.
HandleServerError = async ({ kind: "app" | "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind, error: unknownThe caught error. Its type depends on kind
error, event: RequestEvent<Record<string, string>, string | null>event }) => {
if (kind: "app" | "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind === 'app') {
// you created this error with `error(...)`, so it already
// matches `App.Error` — pass it through unchanged
return error: App.ErrorThe caught error. Its type depends on kind
error;
}
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
Available only in secure contexts.
randomUUID();
if (kind: "framework" | "unknown" | "validation"Identifies the category and origin of the error
kind === 'framework') {
// a 404 (or similar) — `error.status` and `error.message` are safe to
// expose, so we keep them and just add our own property
return { ...error: {
status: number;
message: string;
}
The caught error. Its type depends on kind
error, errorId: `${string}-${string}-${string}-${string}-${string}`errorId };
}
// example integration with https://sentry.io/
module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownThe caught error. Its type depends on kind
error, {
extra: {
event: RequestEvent<Record<string, string>, string | null>;
errorId: `${string}-${string}-${string}-${string}-${string}`;
}
extra: { event: RequestEvent<Record<string, string>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId }
});
// `status` and `message` are optional — we only override `message`,
// so the status stays at its default of 500
return {
message?: string | undefinedmessage: 'Whoops!',
errorId: `${string}-${string}-${string}-${string}-${string}`errorId
};
};import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
module "@sentry/sveltekit"Sentry.const init: (opts: any) => voidinit({/*...*/})
/** @type {import('@sveltejs/kit').HandleClientError} */
export async function function handleError(input: ClientCaughtError & {
event: NavigationEvent;
}): MaybePromise<void | AppErrorWithOptionalDefaults>
handleError({ kind: "app" | "framework" | "unknown"Identifies the category and origin of the error
kind, error: unknownThe caught error. Its type depends on kind
error, event: NavigationEvent<Record<string, string>, string | null>event }) {
if (kind: "app" | "framework" | "unknown"Identifies the category and origin of the error
kind === 'app') {
return error: App.ErrorThe caught error. Its type depends on kind
error;
}
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
Available only in secure contexts.
randomUUID();
if (kind: "framework" | "unknown"Identifies the category and origin of the error
kind === 'framework') {
return { ...error: {
status: number;
message: string;
}
The caught error. Its type depends on kind
error, errorId };
}
// example integration with https://sentry.io/
module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownThe caught error. Its type depends on kind
error, {
extra: {
event: NavigationEvent<Record<string, string>, string | null>;
errorId: `${string}-${string}-${string}-${string}-${string}`;
}
extra: { event: NavigationEvent<Record<string, string>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId }
});
return {
message?: string | undefinedmessage: 'Whoops!',
errorId
};
}import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
import type { type HandleClientError = (input: ClientCaughtError & {
event: NavigationEvent;
}) => MaybePromise<void | AppErrorWithOptionalDefaults>
The client-side handleError hook runs for every error thrown while navigating, except redirects.
Errors that were already transformed by the server-side hook are not passed to it a second time.
The kind property discriminates between app errors (thrown with the error helper),
framework errors (generated by SvelteKit itself, such as 404s) and unknown errors (thrown by your code, or code it calls).
The hook returns an object matching App.Error, in which status and message are optional — return them only to
override the defaults. Omitted properties are inherited from the caught error: the body passed to error(...) for app errors,
the status and safe message for framework errors, and 500 / 'Internal Error' for unknown errors. Return nothing to
keep the defaults entirely (if you augment App.Error with required properties, you must return those).
Make sure that this function never throws an error.
HandleClientError } from '@sveltejs/kit';
module "@sentry/sveltekit"Sentry.const init: (opts: any) => voidinit({/*...*/})
export const const handleError: HandleClientErrorhandleError: type HandleClientError = (input: ClientCaughtError & {
event: NavigationEvent;
}) => MaybePromise<void | AppErrorWithOptionalDefaults>
The client-side handleError hook runs for every error thrown while navigating, except redirects.
Errors that were already transformed by the server-side hook are not passed to it a second time.
The kind property discriminates between app errors (thrown with the error helper),
framework errors (generated by SvelteKit itself, such as 404s) and unknown errors (thrown by your code, or code it calls).
The hook returns an object matching App.Error, in which status and message are optional — return them only to
override the defaults. Omitted properties are inherited from the caught error: the body passed to error(...) for app errors,
the status and safe message for framework errors, and 500 / 'Internal Error' for unknown errors. Return nothing to
keep the defaults entirely (if you augment App.Error with required properties, you must return those).
Make sure that this function never throws an error.
HandleClientError = async ({ kind: "app" | "framework" | "unknown"Identifies the category and origin of the error
kind, error: unknownThe caught error. Its type depends on kind
error, event: NavigationEvent<Record<string, string>, string | null>event }) => {
if (kind: "app" | "framework" | "unknown"Identifies the category and origin of the error
kind === 'app') {
return error: App.ErrorThe caught error. Its type depends on kind
error;
}
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
Available only in secure contexts.
randomUUID();
if (kind: "framework" | "unknown"Identifies the category and origin of the error
kind === 'framework') {
return { ...error: {
status: number;
message: string;
}
The caught error. Its type depends on kind
error, errorId: `${string}-${string}-${string}-${string}-${string}`errorId };
}
// example integration with https://sentry.io/
module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownThe caught error. Its type depends on kind
error, {
extra: {
event: NavigationEvent<Record<string, string>, string | null>;
errorId: `${string}-${string}-${string}-${string}-${string}`;
}
extra: { event: NavigationEvent<Record<string, string>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId }
});
return {
message?: string | undefinedmessage: 'Whoops!',
errorId: `${string}-${string}-${string}-${string}-${string}`errorId
};
};In
src/hooks.client.js, the type ofhandleErrorisHandleClientErrorinstead ofHandleServerError, andeventis aNavigationEventrather than aRequestEvent.
Errors that were already transformed by the server-side hook are not passed to the client-side hook a second time.
During development, if an error occurs because of a syntax error in your Svelte code, the passed in error has a frame property appended highlighting the location of the error.
Make sure that
handleErrornever throws an error
init
Can be added to
src/hooks.server.jsandsrc/hooks.client.js
This function runs once, when the server is created or the app starts in the browser, and is a useful place to do asynchronous work such as initializing a database connection.
If your environment supports top-level await, the
initfunction is really no different from writing your initialisation logic at the top level of the module, but some environments — most notably, Safari — don't.
import * as import dbdb from '#lib/server/database';
/** @type {import('@sveltejs/kit').ServerInit} */
export async function function init(): MaybePromise<void>init() {
await import dbdb.connect();
}import * as import dbdb from '#lib/server/database';
import type { type ServerInit = () => MaybePromise<void>The init will be invoked before the server responds to its first request
ServerInit } from '@sveltejs/kit';
export const const init: ServerInitinit: type ServerInit = () => MaybePromise<void>The init will be invoked before the server responds to its first request
ServerInit = async () => {
await import dbdb.connect();
};In the browser, asynchronous work in
initwill delay hydration, so be mindful of what you put in there.
reroute
Can be added to
src/hooks.js; it runs on both server and client
This function runs before handle and allows you to change how URLs are translated into routes. The returned pathname (which defaults to url.pathname) is used to select the route and its parameters.
For example, you might have a src/routes/[[lang]]/about/+page.svelte page, which should be accessible as /en/about or /de/ueber-uns or /fr/a-propos. You could implement this with reroute:
/** @type {Record<string, string>} */
const const translated: Record<string, string>translated = {
'/en/about': '/en/about',
'/de/ueber-uns': '/de/about',
'/fr/a-propos': '/fr/about',
};
/** @type {import('@sveltejs/kit').Reroute} */
export function function reroute(event: {
url: URL;
fetch: typeof fetch;
}): MaybePromise<string | void>
reroute({ url: URLurl }) {
if (url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname in const translated: Record<string, string>translated) {
return const translated: Record<string, string>translated[url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname];
}
}import type { type Reroute = (event: {
url: URL;
fetch: typeof fetch;
}) => MaybePromise<string | void>
The reroute hook allows you to modify the URL before it is used to determine which route to render.
Reroute } from '@sveltejs/kit';
const const translated: Record<string, string>translated: type Record<K extends keyof any, T> = { [P in K]: T; }Construct a type with a set of properties K of type T
Record<string, string> = {
'/en/about': '/en/about',
'/de/ueber-uns': '/de/about',
'/fr/a-propos': '/fr/about',
};
export const const reroute: Reroutereroute: type Reroute = (event: {
url: URL;
fetch: typeof fetch;
}) => MaybePromise<string | void>
The reroute hook allows you to modify the URL before it is used to determine which route to render.
Reroute = ({ url: URLurl }) => {
if (url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname in const translated: Record<string, string>translated) {
return const translated: Record<string, string>translated[url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname];
}
};The lang parameter will be correctly derived from the returned pathname.
Using reroute will not change the contents of the browser's address bar, or the value of event.url.
Since version 2.18, the reroute hook can be asynchronous, allowing it to (for example) fetch data from your backend to decide where to reroute to. Use this carefully and make sure it's fast, as it will delay navigation otherwise. If you need to fetch data, use the fetch provided as an argument. It has the same benefits as the fetch provided to load functions, with the caveat that params and id are unavailable to handleFetch because the route is not yet known.
/** @type {import('@sveltejs/kit').Reroute} */
export async function function reroute(event: {
url: URL;
fetch: typeof globalThis.fetch;
}): MaybePromise<string | void>
reroute({ url: URLurl, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) {
// Ask a special endpoint within your app about the destination
if (url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname === '/api/reroute') return;
const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URLThe URL interface is used to parse, construct, normalize, and encode URLs. It works by providing properties which allow you to easily read and modify the components of a URL.
URL class is a global reference for import { URL } from 'url'
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: URLurl);
const api: URLapi.URL.searchParams: URLSearchParamsThe searchParams read-only property of the URL interface returns a URLSearchParams object allowing access to the GET decoded query arguments contained in the URL.
searchParams.URLSearchParams.set(name: string, value: string): voidThe set() method of the URLSearchParams interface sets the value associated with a given search parameter to the given value. If there were several matching values, this method deletes the others. If the search parameter doesn't exist, this method creates it.
set('pathname', url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname);
const const result: anyresult = await fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(const api: URLapi).Promise<Response>.then<any, never>(onfulfilled?: ((value: Response) => any) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<any>Attaches callbacks for the resolution and/or rejection of the Promise.
then(r: Responser => r: Responser.Body.json(): Promise<any>json());
return const result: anyresult.pathname;
}import type { type Reroute = (event: {
url: URL;
fetch: typeof fetch;
}) => MaybePromise<string | void>
The reroute hook allows you to modify the URL before it is used to determine which route to render.
Reroute } from '@sveltejs/kit';
export const const reroute: Reroutereroute: type Reroute = (event: {
url: URL;
fetch: typeof fetch;
}) => MaybePromise<string | void>
The reroute hook allows you to modify the URL before it is used to determine which route to render.
Reroute = async ({ url: URLurl, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
// Ask a special endpoint within your app about the destination
if (url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname === '/api/reroute') return;
const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URLThe URL interface is used to parse, construct, normalize, and encode URLs. It works by providing properties which allow you to easily read and modify the components of a URL.
URL class is a global reference for import { URL } from 'url'
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: URLurl);
const api: URLapi.URL.searchParams: URLSearchParamsThe searchParams read-only property of the URL interface returns a URLSearchParams object allowing access to the GET decoded query arguments contained in the URL.
searchParams.URLSearchParams.set(name: string, value: string): voidThe set() method of the URLSearchParams interface sets the value associated with a given search parameter to the given value. If there were several matching values, this method deletes the others. If the search parameter doesn't exist, this method creates it.
set('pathname', url: URLurl.URL.pathname: stringThe pathname property of the URL interface represents a location in a hierarchical structure. It is a string constructed from a list of path segments, each of which is prefixed by a / character.
pathname);
const const result: anyresult = await fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(const api: URLapi).Promise<Response>.then<any, never>(onfulfilled?: ((value: Response) => any) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<any>Attaches callbacks for the resolution and/or rejection of the Promise.
then(r: Responser => r: Responser.Body.json(): Promise<any>json());
return const result: anyresult.pathname;
};
rerouteis considered a pure, idempotent function. As such, it must always return the same output for the same input and not have side effects. Under these assumptions, SvelteKit caches the result ofrerouteon the client so it is only called once per unique URL.
transport
Can be added to
src/hooks.js; it runs on both server and client
This is a collection of transporters, which allow you to pass custom types — returned from load and form actions — across the server/client boundary. Each transporter contains an encode function, which encodes values on the server (or returns a falsy value for anything that isn't an instance of the type) and a corresponding decode function:
import { import VectorVector } from '#lib/math';
/** @type {import('@sveltejs/kit').Transport} */
export const const transport: Transporttransport = {
type Vector: {
encode: (value: any) => false | any[];
decode: ([x, y]: any) => any;
}
Vector: {
Transporter<any, any>.encode: (value: any) => anyencode: (value: anyvalue) => value: anyvalue instanceof import VectorVector && [value: anyvalue.x, value: anyvalue.y],
Transporter<any, any>.decode: (data: any) => anydecode: ([x: anyx, y: anyy]) => new import VectorVector(x: anyx, y: anyy)
}
};import { import VectorVector } from '#lib/math';
import type { type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { Transport } from '@sveltejs/kit';
declare class MyCustomType {
data: any
}
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
Transport } from '@sveltejs/kit';
declare class class MyCustomTypeMyCustomType {
MyCustomType.data: anydata: any
}
// hooks.js
export const const transport: Transporttransport: type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { Transport } from '@sveltejs/kit';
declare class MyCustomType {
data: any
}
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
Transport = {
type MyCustomType: {
encode: (value: any) => false | any[];
decode: ([data]: any) => MyCustomType;
}
MyCustomType: {
Transporter<any, any>.encode: (value: any) => anyencode: (value: anyvalue) => value: anyvalue instanceof class MyCustomTypeMyCustomType && [value: MyCustomTypevalue.MyCustomType.data: anydata],
Transporter<any, any>.decode: (data: any) => anydecode: ([data: anydata]) => new constructor MyCustomType(): MyCustomTypeMyCustomType(data: anydata)
}
};
Transport } from '@sveltejs/kit';
export const const transport: Transporttransport: type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { Transport } from '@sveltejs/kit';
declare class MyCustomType {
data: any
}
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
Transport } from '@sveltejs/kit';
declare class class MyCustomTypeMyCustomType {
MyCustomType.data: anydata: any
}
// hooks.js
export const const transport: Transporttransport: type Transport = {
[x: string]: Transporter<any, any>;
}
The transport hook allows you to transport custom types across the server/client boundary.
Each transporter has a pair of encode and decode functions. On the server, encode determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or false otherwise).
In the browser, decode turns the encoding back into an instance of the custom type.
import type { Transport } from '@sveltejs/kit';
declare class MyCustomType {
data: any
}
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
Transport = {
type MyCustomType: {
encode: (value: any) => false | any[];
decode: ([data]: any) => MyCustomType;
}
MyCustomType: {
Transporter<any, any>.encode: (value: any) => anyencode: (value: anyvalue) => value: anyvalue instanceof class MyCustomTypeMyCustomType && [value: MyCustomTypevalue.MyCustomType.data: anydata],
Transporter<any, any>.decode: (data: any) => anydecode: ([data: anydata]) => new constructor MyCustomType(): MyCustomTypeMyCustomType(data: anydata)
}
};
Transport = {
type Vector: {
encode: (value: any) => false | any[];
decode: ([x, y]: any) => any;
}
Vector: {
Transporter<any, any>.encode: (value: any) => anyencode: (value: anyvalue) => value: anyvalue instanceof import VectorVector && [value: anyvalue.x, value: anyvalue.y],
Transporter<any, any>.decode: (data: any) => anydecode: ([x: anyx, y: anyy]) => new import VectorVector(x: anyx, y: anyy)
}
};Further reading
Edit this page on GitHub llms.txt