Hooks
钩子是你在应用程序范围内声明的函数,SvelteKit 会在响应特定事件时调用这些函数,从而让你能够精细控制框架的行为。
有三个钩子文件,都是可选的:
src/hooks.server.js— 您的应用程序的服务器钩子src/hooks.client.js— 您的应用程序客户端钩子src/hooks.js— 您的应用程序在客户端和服务器上运行的钩子
代码在这些模块中将在应用程序启动时运行,使它们对于初始化数据库客户端等非常有用。
[!注意] 您可以使用
config.kit.files.hooks配置这些文件的存储位置。
服务器钩子
以下钩子可以添加到 src/hooks.server.js 中:
处理
这个函数在 SvelteKit 服务器每次接收到请求时都会运行——无论是在应用运行期间,还是在预渲染期间——并确定响应。它接收一个表示请求的事件对象和一个名为`` resolve的函数,该函数渲染路由并生成`Response。这允许您修改响应头或正文,或者完全绕过 SvelteKit(例如,用于程序化实现路由)。` ``
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle({ event, resolve }: {
event: any;
resolve: any;
}): Promise<any>
handle({ event: anyevent, resolve: anyresolve }) {
if (event: anyevent.url.pathname.startsWith('/custom')) {
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => ResponseThis Fetch API interface represents the response to a request.
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: URLThe requested URL.
url.URL.pathname: stringpathname.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) => ResponseThis Fetch API interface represents the response to a request.
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) 。
在预渲染期间,SvelteKit 会爬取您的页面以查找链接,并为找到的每个路由进行渲染。渲染路由会调用handle函数(以及所有其他路由依赖项,如load)。如果您需要在此阶段排除某些代码的运行,请确保应用不是在构建。
本地
要向请求中添加自定义数据,这些数据将传递到在 +server.js 和服务器 load 函数中的处理器,请填充 event.locals 对象,如下所示。
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}): MaybePromise<...>
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.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<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.cookies: CookiesGet or set cookies related to the current request
cookies.Cookies.get: (name: string, opts?: CookieParseOptions) => 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) => MaybePromise<Response>resolve(event: RequestEvent<Partial<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: 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.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<Partial<Record<string, string>>, string | null>event.RequestEvent<Partial<Record<string, string>>, string | null>.cookies: CookiesGet or set cookies related to the current request
cookies.Cookies.get: (name: string, opts?: CookieParseOptions) => 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) => MaybePromise<Response>resolve(event: RequestEvent<Partial<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: Headersheaders.Headers.set(name: string, value: string): voidset('x-custom-header', 'potato');
return const response: Responseresponse;
};您可以为多个 handle 函数定义,并使用 序列 helper 函数 执行它们。
resolve 同样支持第二个可选参数,该参数可以让你更灵活地控制响应的渲染方式。该参数是一个对象,可以包含以下字段:
transformPageChunk(opts: { html: string, done: boolean }): MaybePromise<string | undefined>— 对 HTML 应用自定义转换。如果done为 true,则是最后一个块。块不保证是良好形成的 HTML(例如,它们可能包含一个元素的打开标签但没有其关闭标签)但它们将始终在合理的边界处分割,如%sveltekit.head%或布局/页面组件。filterSerializedResponseHeaders(name: string, value: string): boolean— 确定在load函数使用fetch加载资源时,应包含哪些头信息在序列化响应中。默认情况下,不包含任何头信息。preload(input: { type: 'js' | 'css' | 'font' | 'asset', path: string }): boolean— 确定哪些文件应该添加到<head>标签中以预加载它。该方法在构建时构建代码块时,对每个找到的文件调用 — 因此,如果您例如在+page.svelte中有import './styles.css',则在访问该页面时,preload将调用该 CSS 文件的解析路径。请注意,在开发模式下,preload不会 调用,因为它依赖于构建时发生的分析。预加载可以通过提前下载资源来提高性能,但如果不必要地下载过多,也可能造成伤害。默认情况下,将预加载js和css文件。目前,asset文件根本不会预加载,但我们在评估反馈后可能会添加此功能。
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle({ event, resolve }: {
event: any;
resolve: any;
}): Promise<any>
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>) | 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 what should be added to the <head> tag to preload it.
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;
};请注意,resolve(...)永远不会抛出错误,它总是返回一个带有适当状态码的Promise<Response>。如果在handle过程中其他地方抛出错误,它将被视为致命错误,SvelteKit 将以错误或备用错误页面的 JSON 表示形式响应——该页面可以通过src/error.html进行自定义——具体取决于Accept头。您可以在这里了解更多关于错误处理的信息。
处理获取
此功能允许您修改(或替换)在端点内运行的 event.fetch 调用的结果,该调用在服务器上(或在预渲染期间)执行,包括 load、action、handle、handleError 或 reroute。
例如,您的 load 函数可能在用户执行客户端导航到相应页面时向公共 URL(如 https://api.yourapp.com)发起请求,但在 SSR 过程中,直接调用 API(绕过位于其与公共互联网之间的任何代理和负载均衡器)可能更有意义。
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function function handleFetch({ request, fetch }: {
request: any;
fetch: any;
}): Promise<any>
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) => RequestThis Fetch API interface represents a resource request.
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) 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 | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
if (request: Requestrequest.Request.url: stringReturns the URL of request as a string.
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) => RequestThis Fetch API interface represents a resource request.
Request(
request: Requestrequest.Request.url: stringReturns the URL of request as a string.
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 | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
};请求使用event.fetch的请求遵循浏览器的凭据模型——对于同源请求,除非将credentials选项设置为"omit",否则将转发cookie和authorization头部。对于跨源请求,如果请求 URL 属于应用的子域,则将包含cookie——例如,如果您的应用位于my-domain.com,而您的 API 位于api.my-domain.com,则 cookie 将包含在请求中。
有一个注意事项:如果您的应用程序和 API 位于兄弟子域名上——例如 www.my-domain.com 和 api.my-domain.com ——那么属于公共父域(如 my-domain.com)的 cookie 将不会包含在内,因为 SvelteKit 无法知道 cookie 属于哪个域名。在这种情况下,您需要手动使用 handleFetch 包含 cookie。
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function function handleFetch({ event, request, fetch }: {
event: any;
request: any;
fetch: any;
}): Promise<any>
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) 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<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: stringReturns the URL of request as a string.
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: HeadersReturns 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.
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: RequestThe original request object.
request.Request.headers: HeadersReturns 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.
headers.Headers.get(name: string): string | nullget('cookie'));
}
return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch(request: Requestrequest);
};共享钩子
以下可以添加到 src/hooks.server.js和src/hooks.client.js:
处理错误
如果在加载、渲染或从端点抛出意外错误时,此函数将使用错误、事件、状态代码和消息被调用。这允许做两件事:
- 您可以记录错误
- 您可以为用户生成一个安全的错误自定义表示,省略敏感细节,如消息和堆栈跟踪。返回的值默认为
{消息},成为$page.error的值。
对于从您的代码(或被您的代码调用的库代码)抛出的错误,状态将为 500,信息为“内部错误”。虽然error.message可能包含不应向用户暴露的敏感信息,但message是安全的(尽管对普通用户来说可能没有意义)。
要安全地向 $page.error 对象添加更多信息,您可以通过声明一个 App.Error 接口(必须包含 message: string,以确保合理的回退行为)来自定义期望的形状。这允许您——例如——为用户提供一个跟踪 ID,以便在与技术支持人员沟通时引用:
declare global {
namespace App {
interface interface App.ErrorDefines 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 {};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>
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.
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
};
}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.
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';
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>
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.
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
};
}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.
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的类型为HandleClientError而不是HandleServerError,并且event是NavigationEvent而不是RequestEvent。
此函数不会为预期错误(使用从@sveltejs/kit导入的error函数抛出的错误)调用。
在开发过程中,如果由于您的 Svelte 代码中的语法错误导致发生错误,传入的错误将附加一个frame属性,突出显示错误的位置。
[!注意] 确保以下代码
handleError从不 抛出错误
初始化
此函数在服务器创建或浏览器中的应用启动时运行一次,是执行异步工作(如初始化数据库连接)的有用位置。
[注意] 如果您的环境支持顶级 await,那么
init函数实际上与在模块顶层编写初始化逻辑并没有太大区别,但某些环境——最值得注意的是,Safari——并不支持。
import * as import dbdb from '$lib/server/database';
/** @type {import('@sveltejs/kit').ServerInit} */
export async function function init(): Promise<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();
};[!注意] 在浏览器中,
init中的异步工作将延迟初始化,因此请注意您放入那里的内容。
通用钩子
以下可以添加到 src/hooks.js。通用钩子在服务器和客户端上运行(不要与特定环境的共享钩子混淆)。
重定向
此函数在 handle 之前运行,并允许您更改如何将 URL 转换为路由。返回的路径名(默认为 url.pathname)用于选择路由及其参数。
例如,您可能有一个 src/routes/[[lang]]/about/+page.svelte 页面,它应该可以通过 /en/about 或 /de/ueber-uns 或 /fr/a-propos 访问。您可以使用 reroute 来实现这一点:
/** @type {Record<string, string>} */
const const translated: {
'/en/about': string;
'/de/ueber-uns': string;
'/fr/a-propos': 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
reroute({ url: anyurl }) {
if (url: anyurl.pathname in const translated: {
'/en/about': string;
'/de/ueber-uns': string;
'/fr/a-propos': string;
}
translated) {
return const translated: {
'/en/about': string;
'/de/ueber-uns': string;
'/fr/a-propos': string;
}
translated[url: anyurl.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: stringpathname in const translated: Record<string, string>translated) {
return const translated: Record<string, string>translated[url: URLurl.URL.pathname: stringpathname];
}
};The lang parameter will be correctly derived from the returned pathname.
使用reroute不会改变浏览器地址栏的内容,或event.url的值。不会
自 2.18 版本起,reroute钩子可以异步执行,允许它(例如)从您的后端获取数据以决定重定向到何处。请谨慎使用,并确保其快速执行,否则它将延迟导航。如果您需要获取数据,请使用作为参数提供的fetch。它与提供给load函数的fetch具有相同的优势,但有一个前提是params和id对于handleFetch不可用,因为路由尚未确定。
/** @type {import('@sveltejs/kit').Reroute} */
export async function function reroute({ url, fetch }: {
url: any;
fetch: any;
}): Promise<any>
reroute({ url: anyurl, fetch: anyfetch }) {
// Ask a special endpoint within your app about the destination
if (url: anyurl.pathname === '/api/reroute') return;
const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URLThe URL interface represents an object providing static methods used for creating object URLs.
URL class is a global reference for import { URL } from 'node:url'
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: anyurl);
const api: URLapi.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.set(name: string, value: string): voidSets the value associated to a given search parameter to the given value. If there were several values, delete the others.
set('pathname', url: anyurl.pathname);
const const result: anyresult = await fetch: anyfetch(const api: URLapi).then(r: anyr => r: anyr.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 | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
// Ask a special endpoint within your app about the destination
if (url: URLurl.URL.pathname: stringpathname === '/api/reroute') return;
const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URLThe URL interface represents an object providing static methods used for creating object URLs.
URL class is a global reference for import { URL } from 'node:url'
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: URLurl);
const api: URLapi.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.set(name: string, value: string): voidSets the value associated to a given search parameter to the given value. If there were several values, delete the others.
set('pathname', url: URLurl.URL.pathname: stringpathname);
const const result: anyresult = await fetch: (input: string | URL | globalThis.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;
};[注意]
reroute被视为一个纯净的幂等函数。因此,它必须始终对相同的输入返回相同的输出,并且不能有副作用。在这些假设下,SvelteKit 在客户端缓存了reroute的结果,因此它只对每个唯一的 URL 调用一次。
运输
这是一个包含 运输器 的集合,允许您传递自定义类型——从 加载 和表单操作返回的类型——跨越服务器/客户端边界。每个运输器包含一个 编码 函数,该函数在服务器上编码值(或对于不是该类型实例的任何内容返回一个假值)以及相应的 解码 函数:
import { import VectorVector } from '$lib/math';
/** @type {import('@sveltejs/kit').Transport} */
export const const transport: {
Vector: {
encode: (value: any) => false | any[];
decode: ([x, y]: [any, any]) => any;
};
}
transport = {
type Vector: {
encode: (value: any) => false | any[];
decode: ([x, y]: [any, any]) => any;
}
Vector: {
encode: (value: any) => false | any[]encode: (value: anyvalue) => value: anyvalue instanceof import VectorVector && [value: anyvalue.x, value: anyvalue.y],
decode: ([x, y]: [any, 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 { 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';
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 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)
}
};进一步阅读
Edit this page on GitHub llms.txt