Skip to main content

Hooks

‘Hooks’ は、特定のイベントに対して SvelteKit がレスポンスを呼び出すことを宣言するアプリ全体の関数で、これによってフレームワークの動作をきめ細やかに制御できるようになります。

hooks ファイルは2つあり、どちらもオプションです:

  • src/hooks.server.js — アプリのサーバーの hooks
  • src/hooks.client.js — アプリのクライアントの hooks
  • src/hooks.js — サーバーとクライアントの両方で実行される hooks

これらのモジュールのコードはアプリケーションの起動時に実行されるので、データベースクライアントの初期化などに有用です。

これらのファイルの場所は config.kit.files.hooks で設定できます。

Server hooks

以下の hooks は src/hooks.server.js に追加することができます:

handle

この関数は SvelteKit のサーバーが リクエスト を受けるたびに (アプリの実行中であろうと、プリレンダリングであろうと) 実行され、レスポンス を決定します。リクエストを表す event オブジェクトと、ルート(route)をレンダリングしレスポンスを生成する resolve という関数を受け取ります。これにより、レスポンスのヘッダーやボディを変更したり、SvelteKitを完全にバイパスすることができます (例えば、プログラムでルート(routes)を実装する場合など)。

src/hooks.server
/** @type {import('@sveltejs/kit').Handle} */
export async function 
function handle({ event, resolve }: {
    event: any;
    resolve: any;
}): Promise<any>
@type{import('@sveltejs/kit').Handle}
handle
({ event: anyevent, resolve: anyresolve }) {
if (event: anyevent.url.pathname.startsWith('/custom')) { return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
('custom response');
} const const response: anyresponse = await resolve: anyresolve(event: anyevent); return const response: anyresponse; }
import type { 
type Handle = (input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}) => MaybePromise<...>

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): MaybePromise<Response>;
}) => MaybePromise<...>

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<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) => {
if (event: RequestEvent<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.url: URL

The requested URL.

url
.URL.pathname: stringpathname.String.startsWith(searchString: string, position?: number): boolean

Returns 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) => Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
('custom response');
} const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event); return const response: Responseresponse; };

静的アセット(プリレンダリング済みのページを含む)に対するリクエストは SvelteKit では処理されません。

未実装の場合、デフォルトは ({ event, resolve }) => resolve(event) となります。

locals

カスタムデータをリクエストに追加し、+server.js のハンドラや server load 関数に渡すには、以下のように event.locals オブジェクトに埋め込んでください。

src/hooks.server
/** @type {import('@sveltejs/kit').Handle} */
export async function 
function handle(input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}): MaybePromise<...>
@type{import('@sveltejs/kit').Handle}
handle
({ event: RequestEvent<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) {
event: RequestEvent<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.locals: App.Locals

Contains 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<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.cookies: Cookies

Get or set cookies related to the current request

cookies
.Cookies.get(name: string, opts?: CookieParseOptions): string | undefined

Gets a cookie that was previously set with cookies.set, or from the request headers.

@paramname the name of the cookie
@paramopts the options, passed directly to cookie.parse. See documentation here
get
('sessionid'));
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event); const response: Responseresponse.Response.headers: Headersheaders.Headers.set(name: string, value: string): voidset('x-custom-header', 'potato'); return const response: Responseresponse; }
import type { 
type Handle = (input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}) => MaybePromise<...>

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): MaybePromise<Response>;
}) => MaybePromise<...>

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<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) => {
event: RequestEvent<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.locals: App.Locals

Contains 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<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.cookies: Cookies

Get or set cookies related to the current request

cookies
.Cookies.get(name: string, opts?: CookieParseOptions): string | undefined

Gets a cookie that was previously set with cookies.set, or from the request headers.

@paramname the name of the cookie
@paramopts the options, passed directly to cookie.parse. See documentation here
get
('sessionid'));
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event); const response: Responseresponse.Response.headers: Headersheaders.Headers.set(name: string, value: string): voidset('x-custom-header', 'potato'); return const response: Responseresponse; };

sequence ヘルパー関数を使用すると、複数の handle 関数を定義することができます。

resolve はオプションの第2引数をサポートしており、レスポンスのレンダリング方法をより詳細にコントロールすることができます。そのパラメータは、以下のフィールドを持つオブジェクトです:

  • transformPageChunk(opts: { html: string, done: boolean }): MaybePromise<string | undefined> — カスタムの変換を HTML に適用します。done が true である場合、それは最後のチャンクです。チャンクが整形された HTML であることは保証されませんが (例えば、要素の開始タグは含むが終了タグは含まれない、など)、常に %sveltekit.head% やレイアウト(layout)/ページ(page)コンポーネントなどのような理にかなった境界 (sensible boundaries) で分割されます。
  • filterSerializedResponseHeaders(name: string, value: string): booleanload 関数が fetch でリソースを読み込むときに、シリアライズされるレスポンスにどのヘッダーを含めるかを決定します。デフォルトでは何も含まれません。
  • preload(input: { type: 'js' | 'css' | 'font' | 'asset', path: string }): boolean<head> タグにどのファイルをプリロードの対象として追加するか決定します。このメソッドはビルド時、コードチャンクを構築している際に見つかったファイルごとに呼び出されます。これにより、例えば +page.svelteimport './styles.css がある場合、そのページに訪れたときにその CSS ファイルへの解決されたパスを以て preload が呼び出されるようになります。これはビルド時の分析によって行われるため、開発モードでは preload が呼ばれないことにご注意ください。プリロードによってその対象がより早くダウンロードされるようになるためパフォーマンスが改善しますが、不必要に多くのものをダウンロードしてしまうと、core web vitals を悪化させてしまいます。デフォルトでは、jscss ファイルがプリロードされます。現時点では asset ファイルはプリロードされませんが、フィードバックによっては追加されるかもしれません。
src/hooks.server
/** @type {import('@sveltejs/kit').Handle} */
export async function 
function handle({ event, resolve }: {
    event: any;
    resolve: any;
}): Promise<any>
@type{import('@sveltejs/kit').Handle}
handle
({ event: anyevent, resolve: anyresolve }) {
const const response: anyresponse = await resolve: anyresolve(event: anyevent, {
transformPageChunk: ({ html }: {
    html: any;
}) => any
transformPageChunk
: ({ html: anyhtml }) => html: anyhtml.replace('old', 'new'),
filterSerializedResponseHeaders: (name: any) => anyfilterSerializedResponseHeaders: (name: anyname) => name: anyname.startsWith('x-'),
preload: ({ type, path }: {
    type: any;
    path: any;
}) => any
preload
: ({ type: anytype, path: anypath }) => type: anytype === 'js' || path: anypath.includes('/important/')
}); return const response: anyresponse; }
import type { 
type Handle = (input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}) => MaybePromise<...>

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): MaybePromise<Response>;
}) => MaybePromise<...>

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<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) => {
const const response: Responseresponse = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event, {
ResolveOptions.transformPageChunk?(input: {
    html: string;
    done: boolean;
}): MaybePromise<string | undefined>

Applies custom transforms to HTML. If done is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML (they could include an element’s opening tag but not its closing tag, for example) but they will always be split at sensible boundaries such as %sveltekit.head% or layout/page components.

@paraminput the html chunk and the info if this is the last chunk
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.

@paramsearchValue A string or regular expression to search for.
@paramreplaceValue A string containing the text to replace. When the {@linkcode searchValue} is a RegExp, all matches are replaced if the g flag is set (or only those matches at the beginning, if the y flag is also present). Otherwise, only the first match of {@linkcode searchValue} is replaced.
replace
('old', 'new'),
ResolveOptions.filterSerializedResponseHeaders?(name: string, value: string): boolean

Determines which headers should be included in serialized responses when a load function loads a resource with fetch. By default, none will be included.

@paramname header name
@paramvalue header value
filterSerializedResponseHeaders
: (name: stringname) => name: stringname.String.startsWith(searchString: string, position?: number): boolean

Returns 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

Determines what should be added to the &#x3C;head> tag to preload it. By default, js and css files will be preloaded.

@paraminput the type of the file and its path
preload
: ({ type: "font" | "css" | "js" | "asset"type, path: stringpath }) => type: "font" | "css" | "js" | "asset"type === 'js' || path: stringpath.String.includes(searchString: string, position?: number): boolean

Returns 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.

@paramsearchString search string
@paramposition If position is undefined, 0 is assumed, so as to search all of the String.
includes
('/important/')
}); return const response: Responseresponse; };

resolve(...) は決してエラーをスローせず、適切なステータスコードと Promise<Response> を返すことにご注意ください。もし handle 中に他の場所でエラーがスローされた場合、それは致命的(fatal)なものとして扱われ、SvelteKit は Accept ヘッダーに応じて、そのエラーの JSON 表現か、src/error.html でカスタマイズ可能なフォールバックエラーページをレスポンスとして返します。エラーハンドリングの詳細は こちら からお読み頂けます。

handleFetch

この関数は、サーバー上で (またはプリレンダリング中に) 実行される load 関数や action 関数の中で発生する fetch リクエストを変更 (または置換) することできます。

例えば、ユーザーがクライアントサイドでそれぞれのページに移動する際に、load 関数で https://api.yourapp.com のようなパブリックな URL にリクエストを行うかもしれませんが、SSR の場合には (パブリックなインターネットとの間にあるプロキシやロードバランサーをバイパスして) API を直接呼ぶほうが理にかなっているでしょう。

src/hooks.server
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function 
function handleFetch({ request, fetch }: {
    request: any;
    fetch: any;
}): Promise<any>
@type{import('@sveltejs/kit').HandleFetch}
handleFetch
({ request: anyrequest, fetch: anyfetch }) {
if (request: anyrequest.url.startsWith('https://api.yourapp.com/')) { // clone the original request, but change the URL request: anyrequest = new var Request: new (input: RequestInfo | URL, init?: RequestInit) => Request

This Fetch API interface represents a resource request.

MDN Reference

Request
(
request: anyrequest.url.replace('https://api.yourapp.com/', 'http://localhost:9999/'), request: anyrequest ); } return fetch: anyfetch(request: anyrequest); }
import type { 
type HandleFetch = (input: {
    event: RequestEvent;
    request: Request;
    fetch: typeof fetch;
}) => MaybePromise<Response>

The handleFetch hook allows you to modify (or replace) a fetch request that happens inside a load function that runs on the server (or during pre-rendering)

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) a fetch request that happens inside a load function that runs on the server (or during pre-rendering)

HandleFetch
= async ({ request: Requestrequest,
fetch: {
    (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
    (input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch
}) => {
if (request: Requestrequest.Request.url: string

Returns the URL of request as a string.

MDN Reference

url
.String.startsWith(searchString: string, position?: number): boolean

Returns 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) => Request

This Fetch API interface represents a resource request.

MDN Reference

Request
(
request: Requestrequest.Request.url: string

Returns the URL of request as a string.

MDN Reference

url
.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)

Replaces text in a string, using a regular expression or search string.

@paramsearchValue A string or regular expression to search for.
@paramreplaceValue A string containing the text to replace. When the {@linkcode searchValue} is a RegExp, all matches are replaced if the g flag is set (or only those matches at the beginning, if the y flag is also present). Otherwise, only the first match of {@linkcode searchValue} is replaced.
replace
('https://api.yourapp.com/', 'http://localhost:9999/'),
request: Requestrequest ); } return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest); };

Credentials

同一オリジン(same-origin)リクエストの場合、SvelteKit の fetch 実装は、credentials オプションを "omit" にしない限り、 cookieauthorization ヘッダーを転送します。

クロスオリジン(cross-origin)リクエストの場合、リクエスト URL がアプリのサブドメインに属するときは cookie はリクエストに含まれます。例えば、あなたのアプリが my-domain.com にあり、あなたの API が api.my-domain.com にある場合、cookie はリクエストに含まれることになります。

もしあなたのアプリと API が兄弟関係にあるサブドメイン (例えば www.my-domain.comapi.my-domain.com) の場合は、my-domain.com のような共通の親ドメインに属する cookie は含まれません、なぜなら SvelteKit にはその cookie がどのドメインに属するか判断する方法がないからです。こういったケースでは、handleFetch を使って手動で cookie を含める必要があります:

src/hooks.server
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function 
function handleFetch({ event, request, fetch }: {
    event: any;
    request: any;
    fetch: any;
}): Promise<any>
@type{import('@sveltejs/kit').HandleFetch}
handleFetch
({ event: anyevent, request: anyrequest, fetch: anyfetch }) {
if (request: anyrequest.url.startsWith('https://api.my-domain.com/')) { request: anyrequest.headers.set('cookie', event: anyevent.request.headers.get('cookie')); } return fetch: anyfetch(request: anyrequest); }
import type { 
type HandleFetch = (input: {
    event: RequestEvent;
    request: Request;
    fetch: typeof fetch;
}) => MaybePromise<Response>

The handleFetch hook allows you to modify (or replace) a fetch request that happens inside a load function that runs on the server (or during pre-rendering)

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) a fetch request that happens inside a load function that runs on the server (or during pre-rendering)

HandleFetch
= async ({ event: RequestEvent<Partial<Record<string, string>>, string | null>event, request: Requestrequest,
fetch: {
    (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
    (input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch
}) => {
if (request: Requestrequest.Request.url: string

Returns the URL of request as a string.

MDN Reference

url
.String.startsWith(searchString: string, position?: number): boolean

Returns 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: Headers

Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the “Host” header.

MDN Reference

headers
.Headers.set(name: string, value: string): voidset('cookie', event: RequestEvent<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.request: Request

The original request object

request
.Request.headers: Headers

Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the “Host” header.

MDN Reference

headers
.Headers.get(name: string): string | nullget('cookie'));
} return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest); };

Shared hooks

以下は src/hooks.server.js src/hooks.client.js のどちらにも追加できます:

handleError

予期せぬエラーがロード中またはレンダリング中にスローされると、この関数が erroreventstatus コード、message を引数にとって呼び出されます。これによって以下の2つのことが可能になります:

  • エラーをログに残すことができます
  • エラーからメッセージやスタックトレースなどの機密情報を省略し、ユーザーに見せても安全なカスタムの表現を生成することができます。戻り値のデフォルトは { message } で、$page.error の値となります。

あなたのコード (またはあなたのコードから呼び出されたライブラリのコード) からスローされたエラーの場合、ステータスは 500 となり、message は “Internal Error” になります。error.message にはユーザーに公開されるべきではない機密情報が含まれている可能性がありますが、message は安全です (一般的なユーザーにとっては無意味ではありますが)。

$page.error オブジェクトに型安全な方法で情報を追加するには、App.Error interface を宣言することで想定する形にすることができます (適切なフォールバックの動作を保証するため、message: string を含む必要があります)。これにより、例えばユーザーがテクニカルサポートスタッフとの対応の際に引用することができるトラッキング ID を付加することができます:

src/app.d
declare global {
	namespace App {
		interface interface App.Error

Defines the common shape of expected and unexpected errors. Expected errors are thrown using the error function. Unexpected errors are handled by the handleError hooks which should return this shape.

Error
{
App.Error.message: stringmessage: string; App.Error.errorId: stringerrorId: string; } } } export {};
src/hooks.server
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: {
    error: unknown;
    event: RequestEvent;
    status: number;
    message: string;
}): MaybePromise<void | App.Error>
@type{import('@sveltejs/kit').HandleServerError}
handleError
({ error: unknownerror, event: RequestEvent<Partial<Record<string, string>>, string | null>event, status: numberstatus, message: stringmessage }) {
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`

Available only in secure contexts.

MDN Reference

randomUUID
();
// example integration with https://sentry.io/ module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownerror, {
extra: {
    event: RequestEvent<Partial<Record<string, string>>, string | null>;
    errorId: `${string}-${string}-${string}-${string}-${string}`;
    status: number;
}
extra
: { event: RequestEvent<Partial<Record<string, string>>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId, status: numberstatus }
}); return { App.Error.message: stringmessage: 'Whoops!', errorId: `${string}-${string}-${string}-${string}-${string}`errorId }; }
import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
import type { 
type HandleServerError = (input: {
    error: unknown;
    event: RequestEvent;
    status: number;
    message: string;
}) => MaybePromise<void | App.Error>

The server-side handleError hook runs when an unexpected error is thrown while responding to a request.

If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event. 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 = (input: {
    error: unknown;
    event: RequestEvent;
    status: number;
    message: string;
}) => MaybePromise<void | App.Error>

The server-side handleError hook runs when an unexpected error is thrown while responding to a request.

If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event. Make sure that this function never throws an error.

HandleServerError
= async ({ error: unknownerror, event: RequestEvent<Partial<Record<string, string>>, string | null>event, status: numberstatus, message: stringmessage }) => {
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`

Available only in secure contexts.

MDN Reference

randomUUID
();
// example integration with https://sentry.io/ module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownerror, {
extra: {
    event: RequestEvent<Partial<Record<string, string>>, string | null>;
    errorId: `${string}-${string}-${string}-${string}-${string}`;
    status: number;
}
extra
: { event: RequestEvent<Partial<Record<string, string>>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId, status: numberstatus }
}); return { App.Error.message: stringmessage: 'Whoops!', errorId: `${string}-${string}-${string}-${string}-${string}`errorId }; };
src/hooks.client
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: {
    error: unknown;
    event: NavigationEvent;
    status: number;
    message: string;
}): MaybePromise<void | App.Error>
@type{import('@sveltejs/kit').HandleClientError}
handleError
({ error: unknownerror, event: NavigationEvent<Partial<Record<string, string>>, string | null>event, status: numberstatus, message: stringmessage }) {
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`

Available only in secure contexts.

MDN Reference

randomUUID
();
// example integration with https://sentry.io/ module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownerror, {
extra: {
    event: NavigationEvent<Partial<Record<string, string>>, string | null>;
    errorId: `${string}-${string}-${string}-${string}-${string}`;
    status: number;
}
extra
: { event: NavigationEvent<Partial<Record<string, string>>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId, status: numberstatus }
}); return { App.Error.message: stringmessage: 'Whoops!', errorId: `${string}-${string}-${string}-${string}-${string}`errorId }; }
import * as module "@sentry/sveltekit"Sentry from '@sentry/sveltekit';
import type { 
type HandleClientError = (input: {
    error: unknown;
    event: NavigationEvent;
    status: number;
    message: string;
}) => MaybePromise<void | App.Error>

The client-side handleError hook runs when an unexpected error is thrown while navigating.

If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event. 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: {
    error: unknown;
    event: NavigationEvent;
    status: number;
    message: string;
}) => MaybePromise<void | App.Error>

The client-side handleError hook runs when an unexpected error is thrown while navigating.

If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event. Make sure that this function never throws an error.

HandleClientError
= async ({ error: unknownerror, event: NavigationEvent<Partial<Record<string, string>>, string | null>event, status: numberstatus, message: stringmessage }) => {
const const errorId: `${string}-${string}-${string}-${string}-${string}`errorId = var crypto: Cryptocrypto.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`

Available only in secure contexts.

MDN Reference

randomUUID
();
// example integration with https://sentry.io/ module "@sentry/sveltekit"Sentry.const captureException: (error: any, opts: any) => voidcaptureException(error: unknownerror, {
extra: {
    event: NavigationEvent<Partial<Record<string, string>>, string | null>;
    errorId: `${string}-${string}-${string}-${string}-${string}`;
    status: number;
}
extra
: { event: NavigationEvent<Partial<Record<string, string>>, string | null>event, errorId: `${string}-${string}-${string}-${string}-${string}`errorId, status: numberstatus }
}); return { App.Error.message: stringmessage: 'Whoops!', errorId: `${string}-${string}-${string}-${string}-${string}`errorId }; };

src/hooks.client.js では、handleError の型は HandleServerError ではなく HandleClientError で、eventRequestEvent ではなく NavigationEvent です。

この関数は 想定される エラー (@sveltejs/kit からインポートされる error 関数でスローされるエラー) の場合は呼び出されません。

開発中、Svelte のコードの構文エラーでエラーが発生した場合、渡される error には、エラーの場所のハイライトが付与された frame プロパティがあります。

handleError 自体が決してエラーをスローしないようにしてください。

Universal hooks

以下は src/hooks.js に追加することができます。universal hooks はサーバーとクライアントの両方で実行されます (shared hooks と混同しないようにしてください、shared hooks は環境依存です)。

reroute

この関数は handle より前に実行され、URL をルート(route)に変換する方法を変更することができます。戻り値の pathname (デフォルトは url.pathname) はルート(route)パラメータを選択するのに使用されます。

例えば、src/routes/[[lang]]/about/+page.svelte というページがあるとして、/en/about/de/ueber-uns/fr/a-propos でアクセスできるようにしたいとします。この場合は reroute を使用して実装することができます:

src/hooks

/** @type {Record<string, string>} */
const 
const translated: {
    '/en/about': string;
    '/de/ueber-uns': string;
    '/fr/a-propos': string;
}
@type{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({ url }: {
    url: any;
}): any
@type{import('@sveltejs/kit').Reroute}
reroute
({ url: anyurl }) {
if (url: anyurl.pathname in
const translated: {
    '/en/about': string;
    '/de/ueber-uns': string;
    '/fr/a-propos': string;
}
@type{Record<string, string>}
translated
) {
return
const translated: {
    '/en/about': string;
    '/de/ueber-uns': string;
    '/fr/a-propos': string;
}
@type{Record<string, string>}
translated
[url: anyurl.pathname];
} }
import type { 
type Reroute = (event: {
    url: URL;
}) => void | string

The reroute hook allows you to modify the URL before it is used to determine which route to render.

@since2.3.0
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;
}) => void | string

The reroute hook allows you to modify the URL before it is used to determine which route to render.

@since2.3.0
Reroute
= ({ url: URLurl }) => {
if (url: URLurl.URL.pathname: stringpathname in const translated: Record<string, string>translated) { return const translated: Record<string, string>translated[url: URLurl.URL.pathname: stringpathname]; } };

lang パラメータは戻り値の pathname から正しく導くことができます。

reroute を使用してもブラウザのアドレスバーの内容や event.url の値は変更されません。

その他の参考資料

Edit this page on GitHub