Skip to main content

Hooks

Les “hooks” sont des fonctions que vous pouvez déclarer et que SvelteKit va appeler en réponse à des évènements spécifiques, vous permettant de contrôler finement le comportement de l’application.

Il y a trois fichiers de hooks, tous optionnels :

  • src/hooks.server.js — les hooks serveur de votre application
  • src/hooks.client.js — les hooks client de votre application
  • src/hooks.js — les hooks de votre application qui peuvent être exécutés à la fois sur le client et sur le serveur

Le code dans ces modules s’exécutera lors du démarrage de l’application, les rendant utile pour l’initialisation de clients de bases de données, parmi d’autres choses.

Vous pouvez configurer l’emplacement de ces fichiers avec config.kit.files.hooks.

Hooks de serveur

Les hooks suivants peuvent être ajoutés au fichier src/hooks.server.js :

handle

Cette fonction est exécutée à chaque fois que le serveur SvelteKit reçoit une requête — que cela se produise lors de l’exécution de l’application ou lors du pré-rendu — et en détermine la réponse. Elle reçoit un objet event représentant la requête et une fonction appelée resolve, qui fait le rendu de la route et génère une Response. Ceci vous permet de modifier les en-têtes ou body de réponse, ou de contourner complètement SvelteKit (pour par exemple implémenter des routes programmatiquement).

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
('réponse personnalisée');
} 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
('réponse personnalisée');
} 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; };

Les requêtes demandant des assets statiques — incluant les pages déjà prérendues — ne sont pas gérées par SvelteKit.

Si non implémentée, cette fonction vaut par défaut ({ event, resolve }) => resolve(event).

Durant le prérendu, Svelte parcourt vos pages à la recherche de liens et rend chaque route qu’il trouve. Le fait de rendre la route provoque l’exécution de la fonction handle (et de toute autre dépendance de route, comme load). Si vous avez besoin d’empêcher du code d’être exécuté lors de cette phase, vérifier en amont que l’application n’est pas en train d’être compilée (via building.

locals

Pour ajouter des données personnalisées à la requête, qui seront ensuite passées aux gestionnaires des fichiers +server.js et aux fonctions load, remplissez l’objet event.locals, comme montré ci-dessous.

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); // Notez que modifier les en-têtes de réponse n'est pas toujours sécurisé. // Les objets de réponse peuvent avoir des en-têtes immutables (par ex. // Response.redirect() renvoyé par un endpoint). // Modifier les en-têtes immutables jette une erreur TypeError. // Dans ce cas, clonez la réponse ou évitez de créer un objet de réponse // ayant des en-têtes immutables. 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); // Notez que modifier les en-têtes de réponse n'est pas toujours sécurisé. // Les objets de réponse peuvent avoir des en-têtes immutables (par ex. // Response.redirect() renvoyé par un endpoint). // Modifier les en-têtes immutables jette une erreur TypeError. // Dans ce cas, clonez la réponse ou évitez de créer un objet de réponse // ayant des en-têtes immutables. const response: Responseresponse.Response.headers: Headersheaders.Headers.set(name: string, value: string): voidset('x-custom-header', 'potato'); return const response: Responseresponse; };

Vous pouvez définir plusieurs fonctions handle et les exécuter avec la fonction utilitaire sequence.

resolve supporte également un deuxième paramètre optionnel qui vous donne plus de contrôle sur la manière dont la réponse va être rendue. Ce paramètre est un objet qui peut avoir les champs suivants :

  • transformPageChunk(opts: { html: string, done: boolean }): MaybePromise<string | undefined> — applique des transformations personnalisées au HTML. Si done vaut true, il s’agit du dernier fragment. Il n’y a pas de garantie que chaque fragment individuel soit du HTML bien formé (il se peut qu’un fragment inclut la balise ouvrante d’un élément mais pas sa balise fermante, par exemple) mais ils seront toujours découpés à des endroits clés tels que %sveltekit.head ou les composants de layout ou de page.
  • filterSerializedResponseHeaders(name: string, value: string): boolean — détermine quels en-têtes devraient être inclus dans les réponses sérialisées lorsqu’une fonction load charge une ressource avec fetch. Par défaut, aucun ne sera inclus.
  • preload(input: { type: 'js' | 'css' | 'font' | 'asset', path: string }): boolean — détermine quels fichiers devraient être ajoutés à la balise <head> pour les précharger. La méthode est appelée avec chaque fichier trouvé pendant la construction des fragments de code au moment de la compilation — donc si vous avez par exemple import './styles.css' dans votre fichier +page.svelte, preload sera appelé avec le chemin résolu menant à ce fichier CSS lorsque la page sera visitée. Notez qu’en mode développement preload n’est pas appelé, puisqu’il dépend de l’analyse se produisant lors de la compilation. Le préchargement peut améliorer la performance en téléchargeant les assets plus tôt, mais cela peut aussi la pénaliser si trop de choses sont téléchargées sans raison. Par défaut, les fichiers js et css seront préchargés. Les fichiers asset ne sont actuellement pas préchargés du tout, mais il est possible que cela soit ajouté à SvelteKit plus tard, en fonction des retours sur le sujet.
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>) | 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) | undefined

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) | undefined

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; };

Notez que resolve(...) ne lèvera jamais d’erreur, mais renverra toujours une Promise<Response> avec le statut approprié. Si une erreur est levée ailleurs lors de l’exécution de handle, elle est traitée comme étant fatale, et SvelteKit répondra avec une représentation JSON de l’erreur ou avec la page d’erreur de secours — qui peut être personnalisée via src/error.html — selon la valeur de l’en-tête Accept. Vous pouvez en apprendre plus à propos de la gestion des erreurs here.

handleFetch

Cette fonction vous permet de modifier (ou remplacer) le résultat d’un appel event.fetch se produisant sur le serveur (ou pendant le pré-rendu) au sein d’un endpoint, ou d’une fonction load, action, handle, handleError or reroute.

Par exemple, imaginons que votre fonction load fasse une requête vers une URL publique comme https://api.yourapp.com lorsqu’un utilisateur ou utilisatrice effectue une navigation côté client vers la page concernée. Lors du rendu serveur de cette page, cela aurait du sens d’appeler directement l’API (en contournant tout éventuel proxy ou gestionnaire de charge qui pourrait se trouver entre l’API et internet).

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 la requête originale, mais change l'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 la requête originale, mais change l'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); };

Les requêtes faites avec event.fetch suivent le modèle d’authentification du navigateur — pour les requêtes de même origine, les en-têtes cookie et authorization sont relayés à moins que l’option credentials soit définie comme "omit". Pour les requêtes d’origine différente (cross-origin), cookie sera inclus si l’URL de la requête appartient à un sous-domaine de l’application — par exemple si votre appliation est sur my-domain.com et que votre API est sur api.my-domain.com, les cookies seront inclus dans la requête.

Il y a tout de même une limitation : si votre application et votre API sont sur des sous-domaines frères — www.my-domain.com et api.my-domain.com par exemple — alors un cookie appartenant à un domaine parent commun comme my-domain.com ne sera pas inclus, car SvelteKit n’a aucun moyen de savoir à quel domaine appartient le cookie. Dans ces situations vous devrez manuellement inclure le cookie en utilisant handleFetch :

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); };

Hooks partagés

Vous pouvez ajouter les hooks suivants aux fichiers src/hooks.server.js et src/hooks.client.js :

handleError

Si une erreur imprévue est levée lors du chargement, du rendu, ou de l’exécution d’un endpoint, cette fonction sera exécutée avec les arguments error, event, status et message. Cela permet deux choses :

  • vous pouvez afficher l’erreur
  • vous pouvez générer une représentation personnalisée de l’erreur que vous pouvez afficher aux utilisateurs et utilisatrices, nettoyée des informations sensibles comme les messages ou les stack traces. La valeur renvoyée, qui vaut par défaut { message }, devient la valeur de $page.error.

Pour les erreurs jetées depuis votre code (ou depuis du code d’une librairie appelée depuis votre code), le statut sera 500 et le message sera “Internal Error”. Bien que error.message peut contenir des informations sensibles qui ne devraient pas être exposées aux utilisateurs et utilisatrices, message ne pose pas de problèmes (bien que sans grand intérêt pour une personne lambda).

Pour ajouter plus d’informations à l’objet $page.error de manière typée, vous pouvez personnalisée la forme attendue en déclarant une interface App.Error (qui doit inclure message: string, pour garantir un comportement par défaut correct). Cela vous permet de — par exemple — ajouter un ID de suivi que les utilisateurs et utilisatrices pourront utiliser comme référence lors de leurs échanges potentiels avec vos équipes de support :

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
();
// exemple d'intégration avec 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: 'Oups !', 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
();
// exemple d'intégration avec 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: 'Oups !', 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
();
// exemple d'intégration avec 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: 'Oups !', 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
();
// exemple d'intégration avec 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: 'Oups !', errorId: `${string}-${string}-${string}-${string}-${string}`errorId }; };

Dans le fichier src/hooks.client.js, le type de handleError est HandleClientError au lieu de HandleServerError, et event est un NavigationEvent plutôt qu’un RequestEvent.

Cette fonction n’est pas appelée pour les erreurs prévues (celles jetées depuis la fonction error importée depuis @sveltejs/kit).

Lors du développement, si une erreur se produit à cause d’une erreur de syntaxe dans votre code Svelte, l’erreur fournie aura une propriété frame mettant en valeur la position de l’erreur.

Assurez-vous que handleError ne jette jamais d’erreur.

init

Cette fonction est exécutée une seule fois, lorsque le serveur est créé ou lorsque l’application démarre dans le navigateur. C’est une fonction pratique pour effectuer des opérations asynchrones comme l’initialisation d’une connexion à une base de données.

Si votre environnement support le fait d’écrire await à la racine de votre fichier, utiliser la fonction init n’est pas vraiment différente d’initialiser votre logique d’initialisation à la racine du module, mais certains environnements — le plus connu étant Safari — ne le supportent pas.

src/hooks.server
import * as import dbdb from '$lib/server/database';

/** @type {import('@sveltejs/kit').ServerInit} */
export async function function init(): Promise<void>
@type{import('@sveltejs/kit').ServerInit}
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

@since2.10.0
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

@since2.10.0
ServerInit
= async () => {
await import dbdb.connect(); };

Dans le navigateur, les tâches asynchrones au sein de init vont retarder l’hydratation, soyez donc conscient•e de ce que vous y faites.

Hooks universels

Vous pouvez ajouter les fonctions suivantes au fichier src/hooks.js. Les hooks universels sont exécutés à la fois sur le serveur et le client (à ne pas confondre avec les hooks partagés, qui sont spécifiques à un environnement).

reroute

Cette fonction est exécutée avant handle et vous permet de changer la manière dont les URLs sont traduites en routes. Le chemin renvoyé (qui vaut par défaut url.pathname) est utilisé pour sélectionner la route et ses paramètres.

Par exemple, vous pourriez avoir une page src/routes/[[lang]]/about/+page.svelte, qui devrait être accessible en tant que /en/about, /de/ueber-uns ou /fr/a-propos. Vous pourriez implémenter ceci avec 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;
    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.

@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;
    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.

@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]; } };

Le paramètre lang sera correctement déduit du chemin renvoyé.

Le fait d’utiliser reroute ne changera pas le contenu de la barre d’adresse, ni la valeur de event.url.

Depuis la version 2.18, le hook reroute peut être asynchrone, vous permettant de (par exemple) récupérer des données depuis votre backend pour décider vers quelle route re-router. Assurez-vous que la récupération de données soit rapide, car cela retardera la navigation sinon. Si vous avez besoin de récupérer des données, utilisez la fonction fetch fourni en argument. Celle-ci hérite des mêmes bénéfices que la fonction fetch fournie aux fonctions load, avec l’inconvénient que params et id ne seront pas rendus disponibles pour handleFetch car la route n’est à ce moment-là pas encore déterminée.

src/hooks

/** @type {import('@sveltejs/kit').Reroute} */
export async function 
function reroute({ url, fetch }: {
    url: any;
    fetch: any;
}): Promise<any>
@type{import('@sveltejs/kit').Reroute}
reroute
({ url: anyurl, fetch: anyfetch }) {
// Demandez à un endpoint spécial de votre application quelle est la destination if (url: anyurl.pathname === '/api/reroute') return; const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URL

The URL interface represents an object providing static methods used for creating object URLs.

MDN Reference

URL class is a global reference for require('url').URL https://nodejs.org/api/url.html#the-whatwg-url-api

@sincev10.0.0
URL
('/api/reroute', url: anyurl);
const api: URLapi.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.set(name: string, value: string): void

Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.

MDN Reference

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.

@since2.3.0
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.

@since2.3.0
Reroute
= async ({ url: URLurl,
fetch: {
    (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
    (input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}
fetch
}) => {
// Demandez à un endpoint spécial de votre application quelle est la destination if (url: URLurl.URL.pathname: stringpathname === '/api/reroute') return; const const api: URLapi = new var URL: new (url: string | URL, base?: string | URL) => URL

The URL interface represents an object providing static methods used for creating object URLs.

MDN Reference

URL class is a global reference for require('url').URL https://nodejs.org/api/url.html#the-whatwg-url-api

@sincev10.0.0
URL
('/api/reroute', url: URLurl);
const api: URLapi.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.set(name: string, value: string): void

Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.

MDN Reference

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.

@paramonfulfilled The callback to execute when the Promise is resolved.
@paramonrejected The callback to execute when the Promise is rejected.
@returnsA Promise for the completion of which ever callback is executed.
then
(r: Responser => r: Responser.Body.json(): Promise<any>json());
return const result: anyresult.pathname; };

La fonction reroute est considérée comme une fonction pure et idempotent. Par conséquence, elle doit toujours renvoyer le même résultat pour une entrée donnée, et ne doit pas avoir d’effets de bord. Avec ces considérations, SvelteKit va cacher le résultat de reroute sur le client afin que reroute ne soit exécutée qu’une seule fois par URL unique.

transport

Une collection de transporteurs, qui vous permettent de fournir des types personnalisés — renvoyés depuis une fonction load, au travers de la frontière serveur/client. Chaque transporteur contient une fonction encode, qui encode les valeurs sur le serveur (ou renvoie false pour ce qui n’est pas une instance du type) et une fonction decode correspondante :

src/hooks
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;
    };
}
@type{import('@sveltejs/kit').Transport}
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 &#x26;&#x26; [value.data],
		decode: ([data]) => new MyCustomType(data)
	}
};
@since2.11.0
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 &#x26;&#x26; [value.data],
		decode: ([data]) => new MyCustomType(data)
	}
};
@since2.11.0
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) } };

Plus de lecture

Modifier cette page sur Github llms.txt

précédent suivant