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 applicationsrc/hooks.client.js
— les hooks client de votre applicationsrc/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).
/** @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('réponse personnalisée');
}
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('réponse personnalisée');
}
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;
};
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.
/** @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);
// 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: 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);
// 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: Response
response.Response.headers: Headers
headers.Headers.set(name: string, value: string): void
set('x-custom-header', 'potato');
return const response: Response
response;
};
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. Sidone
vauttrue
, 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 fonctionload
charge une ressource avecfetch
. 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 exempleimport './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éveloppementpreload
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 fichiersjs
etcss
seront préchargés. Les fichiersasset
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.
/** @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>) | 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) | 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.
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) | 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: 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;
};
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).
/** @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 la requête originale, mais change l'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/', 'http://localhost: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 la requête originale, mais change l'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/', 'http://localhost:9999/'),
request: Request
request
);
}
return fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)
fetch(request: Request
request);
};
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
:
/** @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);
};
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 :
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();
// exemple d'intégration avec 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: '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) => 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();
// exemple d'intégration avec 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: 'Oups !',
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();
// exemple d'intégration avec 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: '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) => 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();
// exemple d'intégration avec 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: 'Oups !',
errorId: `${string}-${string}-${string}-${string}-${string}`
errorId
};
};
Dans le fichier
src/hooks.client.js
, le type dehandleError
estHandleClientError
au lieu deHandleServerError
, etevent
est unNavigationEvent
plutôt qu’unRequestEvent
.
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 fonctioninit
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.
import * as import db
db from '$lib/server/database';
/** @type {import('@sveltejs/kit').ServerInit} */
export async function function init(): Promise<void>
init() {
await import db
db.connect();
}
import * as import db
db 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: ServerInit
init: type ServerInit = () => MaybePromise<void>
The init
will be invoked before the server responds to its first request
ServerInit = async () => {
await import db
db.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
:
/** @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;
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: Reroute
reroute: 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: 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];
}
};
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.
/** @type {import('@sveltejs/kit').Reroute} */
export async function function reroute({ url, fetch }: {
url: any;
fetch: any;
}): Promise<any>
reroute({ url: any
url, fetch: any
fetch }) {
// Demandez à un endpoint spécial de votre application quelle est la destination
if (url: any
url.pathname === '/api/reroute') return;
const const api: URL
api = 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.
URL
class is a global reference for require('url').URL
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: any
url);
const api: URL
api.URL.searchParams: URLSearchParams
searchParams.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.
set('pathname', url: any
url.pathname);
const const result: any
result = await fetch: any
fetch(const api: URL
api).then(r: any
r => r: any
r.json());
return const result: any
result.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: Reroute
reroute: 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: URL
url, 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: URL
url.URL.pathname: string
pathname === '/api/reroute') return;
const const api: URL
api = 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.
URL
class is a global reference for require('url').URL
https://nodejs.org/api/url.html#the-whatwg-url-api
URL('/api/reroute', url: URL
url);
const api: URL
api.URL.searchParams: URLSearchParams
searchParams.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.
set('pathname', url: URL
url.URL.pathname: string
pathname);
const const result: any
result = await fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)
fetch(const api: URL
api).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: Response
r => r: Response
r.Body.json(): Promise<any>
json());
return const result: any
result.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 dereroute
sur le client afin quereroute
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 :
import { import Vector
Vector } 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: any
value) => value: any
value instanceof import Vector
Vector && [value: any
value.x, value: any
value.y],
decode: ([x, y]: [any, any]) => any
decode: ([x: any
x, y: any
y]) => new import Vector
Vector(x: any
x, y: any
y)
}
};
import { import Vector
Vector } 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: Transport
transport: 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) => any
encode: (value: any
value) => value: any
value instanceof import Vector
Vector && [value: any
value.x, value: any
value.y],
Transporter<any, any>.decode: (data: any) => any
decode: ([x: any
x, y: any
y]) => new import Vector
Vector(x: any
x, y: any
y)
}
};
Plus de lecture
Modifier cette page sur Github llms.txt