钩子
“钩子”是在应用程序范围内声明的函数,SvelteKit 会在响应特定事件时调用这些函数,从而让你能够对框架的行为进行细粒度的控制。
有三个钩子文件,所有文件都是可选的
src/hooks.server.js
— 你的应用程序的服务器钩子src/hooks.client.js
— 你的应用程序的客户端钩子src/hooks.js
— 你的应用程序在客户端和服务器上都运行的钩子
这些模块中的代码将在应用程序启动时运行,因此它们对于初始化数据库客户端等操作非常有用。
你可以使用
config.kit.files.hooks
配置这些文件的位置。
服务器钩子
以下钩子可以添加到 src/hooks.server.js
中
handle
每次 SvelteKit 服务器收到请求时,此函数都会运行——无论是在应用程序运行期间还是在预渲染期间——并确定响应。它接收一个表示请求的 event
对象和一个名为 resolve
的函数,该函数渲染路由并生成一个 Response
。这允许你修改响应头或主体,或完全绕过 SvelteKit(例如,用于以编程方式实现路由)。
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle({ event, resolve }: {
event: any;
resolve: any;
}): Promise<any>
handle({ event: any
event, resolve: any
resolve }) {
if (event: any
event.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.
Response('custom response');
}
const const response: any
response = await resolve: any
resolve(event: any
event);
return const response: any
response;
}
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: Handle
handle: 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: string
pathname.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.
Response('custom response');
}
const const response: Response
response = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event);
return const response: Response
response;
};
对静态资源的请求——包括已预渲染的页面——不会由 SvelteKit 处理。
如果未实现,则默认为 ({ event, resolve }) => resolve(event)
。
locals
要将自定义数据添加到请求中(该数据传递给 +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.Locals
Contains custom data that was added to the request within the server handle hook
.
locals.App.Locals.user: User
user = 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.
get('sessionid'));
const const response: Response
response = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event);
const response: Response
response.Response.headers: Headers
headers.Headers.set(name: string, value: string): void
set('x-custom-header', 'potato');
return const response: Response
response;
}
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: Handle
handle: 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: User
user = 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.
get('sessionid'));
const const response: Response
response = await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event);
const response: Response
response.Response.headers: Headers
headers.Headers.set(name: string, value: string): void
set('x-custom-header', 'potato');
return const response: Response
response;
};
你可以定义多个 handle
函数,并使用sequence
辅助函数执行它们。
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: any
event, resolve: any
resolve }) {
const const response: any
response = await resolve: any
resolve(event: any
event, {
transformPageChunk: ({ html }: {
html: any;
}) => any
transformPageChunk: ({ html: any
html }) => html: any
html.replace('old', 'new'),
filterSerializedResponseHeaders: (name: any) => any
filterSerializedResponseHeaders: (name: any
name) => name: any
name.startsWith('x-'),
preload: ({ type, path }: {
type: any;
path: any;
}) => any
preload: ({ type: any
type, path: any
path }) => type: any
type === 'js' || path: any
path.includes('/important/')
});
return const response: any
response;
}
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: Handle
handle: 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: Response
response = 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.
transformPageChunk: ({ html: string
html }) => html: string
html.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
Determines 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: string
name) => name: string
name.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 <head>
tag to preload it.
By default, js
and css
files will be preloaded.
preload: ({ type: "font" | "css" | "js" | "asset"
type, path: string
path }) => type: "font" | "css" | "js" | "asset"
type === 'js' || path: string
path.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.
includes('/important/')
});
return const response: Response
response;
};
请注意,resolve(...)
永远不会抛出错误,它始终会返回一个包含相应状态码的 Promise<Response>
。如果在 handle
期间其他地方抛出错误,则将其视为致命错误,SvelteKit 将响应错误的 JSON 表示形式或回退错误页面——可以通过 src/error.html
自定义——具体取决于 Accept
标头。你可以在这里了解更多关于错误处理的信息。
handleFetch
此函数允许你修改(或替换)在服务器上运行的 load
或 action
函数(或在预渲染期间)内部发生的 fetch
请求。
例如,你的 load
函数可能会在用户执行客户端导航到相应页面时向 https://api.yourapp.com
等公共 URL 发送请求,但在 SSR 期间,直接访问 API(绕过它和公共互联网之间的任何代理和负载均衡器)可能更有意义。
/** @type {import('@sveltejs/kit').HandleFetch} */
export async function function handleFetch({ request, fetch }: {
request: any;
fetch: any;
}): Promise<any>
handleFetch({ request: any
request, fetch: any
fetch }) {
if (request: any
request.url.startsWith('https://api.yourapp.com/')) {
// clone the original request, but change the URL
request: any
request = new var Request: new (input: RequestInfo | URL, init?: RequestInit) => Request
This Fetch API interface represents a resource request.
Request(
request: any
request.url.replace('https://api.yourapp.com/', 'https://127.0.0.1:9999/'),
request: any
request
);
}
return fetch: any
fetch(request: any
request);
}
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: HandleFetch
handleFetch: 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: Request
request, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
if (request: Request
request.Request.url: string
Returns the URL of request as a string.
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: Request
request = new var Request: new (input: RequestInfo | URL, init?: RequestInit) => Request
This Fetch API interface represents a resource request.
Request(
request: Request
request.Request.url: string
Returns 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/', 'https://127.0.0.1:9999/'),
request: Request
request
);
}
return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)
fetch(request: Request
request);
};
凭据
对于同源请求,SvelteKit 的 fetch
实现将转发 cookie
和 authorization
标头,除非 credentials
选项设置为 "omit"
。
对于跨源请求,如果请求 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: any
event, request: any
request, fetch: any
fetch }) {
if (request: any
request.url.startsWith('https://api.my-domain.com/')) {
request: any
request.headers.set('cookie', event: any
event.request.headers.get('cookie'));
}
return fetch: any
fetch(request: any
request);
}
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: HandleFetch
handleFetch: 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: Request
request, fetch: {
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch }) => {
if (request: Request
request.Request.url: string
Returns the URL of request as a string.
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: Request
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.
headers.Headers.set(name: string, value: string): void
set('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.
headers.Headers.get(name: string): string | null
get('cookie'));
}
return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)
fetch(request: Request
request);
};
共享钩子
以下内容可以添加到 src/hooks.server.js
和 src/hooks.client.js
中
handleError
如果在加载或渲染期间抛出意外错误,则此函数将使用 error
、event
、status
代码和 message
进行调用。这允许做两件事
- 你可以记录错误
- 你可以生成错误的自定义表示形式,该表示形式对用户来说是安全的,并省略敏感详细信息(如消息和堆栈跟踪)。返回值(默认为
{ message }
)成为$page.error
的值。
对于从你的代码(或你的代码调用的库代码)抛出的错误,状态将为 500,消息将为“内部错误”。虽然 error.message
可能包含不应向用户公开的敏感信息,但 message
是安全的(尽管对普通用户来说毫无意义)。
要以类型安全的方式向 $page.error
对象添加更多信息,你可以通过声明 App.Error
接口(必须包含 message: string
,以保证合理的回退行为)来自定义预期的形状。这允许你——例如——为用户附加一个跟踪 ID,以便在与你的技术支持人员联系时引用该 ID
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: string
message: string;
App.Error.errorId: string
errorId: string;
}
}
}
export {};
import * as module "@sentry/sveltekit"
Sentry from '@sentry/sveltekit';
module "@sentry/sveltekit"
Sentry.const init: (opts: any) => void
init({/*...*/})
/** @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: unknown
error, event: RequestEvent<Partial<Record<string, string>>, string | null>
event, status: number
status, message: string
message }) {
const const errorId: `${string}-${string}-${string}-${string}-${string}`
errorId = var crypto: Crypto
crypto.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) => void
captureException(error: unknown
error, {
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: number
status }
});
return {
App.Error.message: string
message: '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) => void
init({/*...*/})
export const const handleError: HandleServerError
handleError: 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: unknown
error, event: RequestEvent<Partial<Record<string, string>>, string | null>
event, status: number
status, message: string
message }) => {
const const errorId: `${string}-${string}-${string}-${string}-${string}`
errorId = var crypto: Crypto
crypto.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) => void
captureException(error: unknown
error, {
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: number
status }
});
return {
App.Error.message: string
message: '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) => void
init({/*...*/})
/** @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: unknown
error, event: NavigationEvent<Partial<Record<string, string>>, string | null>
event, status: number
status, message: string
message }) {
const const errorId: `${string}-${string}-${string}-${string}-${string}`
errorId = var crypto: Crypto
crypto.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) => void
captureException(error: unknown
error, {
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: number
status }
});
return {
App.Error.message: string
message: '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) => void
init({/*...*/})
export const const handleError: HandleClientError
handleError: 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: unknown
error, event: NavigationEvent<Partial<Record<string, string>>, string | null>
event, status: number
status, message: string
message }) => {
const const errorId: `${string}-${string}-${string}-${string}-${string}`
errorId = var crypto: Crypto
crypto.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) => void
captureException(error: unknown
error, {
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: number
status }
});
return {
App.Error.message: string
message: 'Whoops!',
errorId: `${string}-${string}-${string}-${string}-${string}`
errorId
};
};
在
src/hooks.client.js
中,handleError
的类型为HandleClientError
而不是HandleServerError
,并且event
为NavigationEvent
而不是RequestEvent
。
对于预期错误(使用从 @sveltejs/kit
导入的error
函数抛出的错误),不会调用此函数。
在开发过程中,如果由于 Svelte 代码中的语法错误而发生错误,则附加的传递错误具有 frame
属性,突出显示错误的位置。
确保
handleError
永远不会抛出错误
通用钩子
以下内容可以添加到 src/hooks.js
中。通用钩子在服务器和客户端上都运行(不要与特定于环境的共享钩子混淆)。
reroute
此函数在 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: any
url }) {
if (url: any
url.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: any
url.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.
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: Reroute
reroute: 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.
Reroute = ({ url: URL
url }) => {
if (url: URL
url.URL.pathname: string
pathname in const translated: Record<string, string>
translated) {
return const translated: Record<string, string>
translated[url: URL
url.URL.pathname: string
pathname];
}
};
lang
参数将从返回的路径名中正确派生。
使用 reroute
不会更改浏览器地址栏的内容或 event.url
的值。