Avant qu'un composant [`+page.svelte`](routing#page-page.svelte) (et ses composants
[`+layout.svelte`](routing#layout-layout.svelte) parents) puissent être rendus, il est souvent
nécessaire de récupérer des données pour les alimenter. Nous pouvons faire cela en définissant des
fonctions `load`.
## Données de page [!VO]Page data
Un fichier `+page.svelte` peut avoir un fichier frère `+page.js` qui exporte une fonction `load`,
dont la valeur de retour est rendue disponible dans la page via la prop `data` :
```js
/// file: src/routes/blog/[slug]/+page.js
/** @type {import('./$types').PageLoad} */
export function load({ params }) {
return {
post: {
title: `Titre pour ${params.slug}`,
content: `Contenu pour ${params.slug}`
}
};
}
```
```svelte
{data.post.title}
{@html data.post.content}
```
> [!LEGACY]
> Avant la version 2.16.0, les props d'une page et d'un layout devaient être typées individuellement
> :
> ```js
> /// file: +page.svelte
> /** @type {{ data: import('./$types').PageData }} */
> let { data } = $props();
> ```
>
> En Svelte 4, vous devez plutôt utiliser `export let data`.
Grâce au module `$types` que SvelteKit génère, nous profitons pleinement du typage.
Une fonction `load` dans un fichier `+page.js` est exécutée à la fois sur le serveur et dans le
navigateur (à moins qu'elle soit associée à une déclaration `export const ssr = false`, auquel cas
elle [ne sera exécutée que dans le navigateur](page-options#ssr)). Si votre fonction `load` doit
_toujours_ être exécutée sur le serveur (car elle utilise des variables d'environnement privées, par
exemple, ou parce qu'elle a besoin d'avoir accès à une base de données), alors il faut plutôt la
définir dans un fichier `+page.server.js`.
Une version plus réaliste de la fonction `load` pour un article de blog, qui ne s'exécute que sur le
serveur et récupère des données dans une base de données, pourrait ressembler à ceci :
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content: string }>
}
// @filename: index.js
// ---cut---
import * as db from '$lib/server/database';
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
return {
post: await db.getPost(params.slug)
};
}
```
Notez que le type a changé de `PageLoad` à `PageServerLoad`, car les fonctions `load` de serveur
peuvent accéder à des arguments supplémentaires. Pour comprendre lorsque vous devez utiliser
`+page.js` ou `+page.server.js`, voir la section [Universel vs serveur](load#Universal-vs-server).
## Données de layout [!VO]Layout data
Vos fichiers `+layout.svelte` peuvent aussi charger des données, via `+layout.js` ou
`+layout.server.js`.
```js
/// file: src/routes/blog/[slug]/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPostSummaries(): Promise>
}
// @filename: index.js
// ---cut---
import * as db from '$lib/server/database';
/** @type {import('./$types').LayoutServerLoad} */
export async function load() {
return {
posts: await db.getPostSummaries()
};
}
```
```svelte
{@render children()}
```
> [!LEGACY]
> `LayoutProps` a été ajouté dans la version 2.16.0. Dans les versions antérieures, les propriétés
> devaient être typées individuellement :
> ```js
> /// file: +layout.svelte
> /** @type {{ data: import('./$types').LayoutData, children: Snippet }} */
> let { data, children } = $props();
> ```
Les données renvoyées par des fonctions `load` de layout sont accessibles par les composants
`+layout.svelte` et le composant `+page.svelte` enfants, ainsi que par le composant de layout auquel
elles sont associées.
```svelte
/// file: src/routes/blog/[slug]/+page.svelte
{/if}+++
```
> [!NOTE] Si plusieurs fonctions `load` renvoient des données avec la même clé, la dernière "gagne"
> — le résultat d'une fonction `load` de layout renvoyant `{ a: 1, b: 2}` et d'une fonction `load`
> de page renvoyant `{ b: 3, c: 4 }` serait `{ a: 1, b: 3, c: 4 }`.
## page.data
Le composant `+page.svelte`, ainsi que chaque composant `+layout.svelte` au-dessus de lui, a accès à
ses propres données en plus de toutes les données venant de ses parents.
Dans certains cas, nous pourrions avoir besoin de l'inverse — un layout parent pourrait avoir besoin
d'avoir accès aux données de page ou aux données d'un layout enfant. Par exemple, le layout racine
pourrait vouloir avoir accès à la propriété `title` renvoyée par une fonction `load` d'un `+page.js`
ou `+page.server.js`. Ceci est rendu possible par `page.data` :
```svelte
{page.data.title}
```
L'information de typage de `page.data` est fournie par `App.PageData`.
> [!LEGACY]
> `$app/state` a été ajouté par SvelteKit 2.12. Si vous utilisez une version antérieure ou si vous
> utilisez Svelte 4, utilisez plutôt `$app/stores`. Ce module fournit un store de `page` ayant la
> même interface, et vous pouvez vous y abonner avec, par exemple, `$page.data.title`.
## Universel vs serveur [!VO]Universal vs server
Comme nous l'avons vu, il y a deux types de fonctions `load` :
* les fichiers `+page.js` et `+layout.js` exportent des fonctions `load` _universelles_ qui sont
exécutées à la fois sur le serveur et dans le navigateur
* les fichiers `+page.server.js` et `+layout.server.js` exportent des fonctions `load` de _serveur_
qui ne exécutées que côté serveur
Conceptuellement, elles font la même chose, mais il y a quelques différences importantes dont il
faut avoir conscience.
### À quel moment chacune est-elle exécutée ? [!VO]When does which load function run?
Les fonctions `load` de serveur sont _toujours_ exécutées sur le serveur.
Par défaut, les fonctions `load` universelles sont exécutées sur le serveur lors du rendu côté
serveur (SSR) au moment ou un utilisateur ou une utilisatrice visite pour la première fois votre
page. Elles seront de nouveau exécutées lors de l'hydratation, en réutilisant toute réponse venant
de [requêtes `fetch`](#Making-fetch-requests). Toutes les invocations suivantes de fonctions `load`
universelles vont se produire dans le navigateur. Vous pouvez personnaliser ce comportement via les
[options de page](page-options). Si vous désactivez le [rendu côté serveur](page-options#ssr), votre
application deviendra une SPA et les fonctions `load` universelles seront _toujours_ exécutées dans
le navigateur.
Si une route contient à la fois des fonctions `load` universelles et de serveur, la fonction `load`
de serveur est exécutée en premier.
Une fonction `load` est invoquée au moment de l'exécution de votre processus, à moins que nous ne
[pré-rendiez](page-options#prerender) la page — dans ce cas, elle sera invoquée au moment de la
compilation.
### Entrées [!VO]Input
Les fonctions `load` universelles et de serveur ont toutes deux accès aux propriétés décrivant la
requête (`params`, `route`, et `url`) ainsi qu'à diverses fonctions (`fetch`, `setHeaders`,
`parent`, `depends` et `untrack`). Ces fonctions sont décrites dans les sections suivantes.
Les fonctions `load` de serveur sont appelées avec un `ServerLoadEvent`, qui hérite de
`clientAddress`, `cookies`, `locals`, `platform` et `request` venant de `RequestEvent`.
Les fonctions `load` universelles sont appelées avec un `LoadEvent`, qui a une propriété `data`. Si
vous avez une fonction `load` à la fois dans `+page.js` et dans `+page.server.js` (ou `+layout.js`
et `+layout.server.js`), la valeur de retour de la fonction `load` de serveur est la propriété
`data` dans les arguments de la fonction `load` universelle.
### Sorties [!VO]Output
Une fonction `load` universelle peut renvoyer un objet contenant tout type de valeurs, y compris des
choses comme des classes personnalisées et des constructeurs de composants.
Une fonction `load` de serveur doit renvoyer des données pouvant être sérialisées avec
[devalue](https://github.com/rich-harris/devalue) — tout ce qui peut être représenté en tant que
JSON plus des choses comme `BigInt`, `Date`, `Map`, `Set` et `RegExp`, ou des références
répétées/cycliques — afin qu'elles puissent être transportées sur le réseau. Vos données peuvent
inclure des [promesses](#Streaming-with-promises), auquel cas elles seront streamées vers les
navigateurs.
### Quand utiliser quoi [!VO]When to use which
Les fonctions `load` de serveur sont pratiques lorsque vous avez besoin d'accéder directement à des
données se trouvant dans une base de données ou un système de fichiers, ou si vous avez besoin
d'utiliser des variables d'environnement privées.
Les fonctions `load` universelles sont utiles lorsque vous avez besoin de récupérer avec `fetch` des
données d'une API externe et que vous n'avez pas besoin d'être authentifié•e pour cela, puisque
SvelteKit peut récupérer directement les données depuis l'API sans avoir à passer par votre serveur.
Elles sont aussi utiles lorsque vous devez renvoyer quelque chose qui ne peut pas être sérialisé,
comme un constructeur de composant Svelte.
Dans de rares cas, vous pourriez avoir besoin des deux ensemble — par exemple, vous pourriez avoir
besoin de renvoyer une instance d'une classe personnalisée qui doit être initialisée avec des
données venant de votre serveur. Lorsque vous utilisez les deux, la valeur de retour de la fonction
`load` de serveur n'est _pas_ directement passée à la page, mais à la fonction `load` universelle
(en tant que propriété `data`) :
```js
/// file: src/routes/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export async function load() {
return {
serverMessage: 'bonjour depuis la fonction load de serveur'
};
}
```
```js
/// file: src/routes/+page.js
// @errors: 18047
/** @type {import('./$types').PageLoad} */
export async function load({ data }) {
return {
serverMessage: data.serverMessage,
universalMessage: 'bonjour depuis la fonction load universelle'
};
}
```
## Utiliser les données d'URL [!VO]Using URL data
Souvent, la fonction `load` dépend de l'URL d'une manière ou d'une autre. Pour gérer ça, la fonction
`load` vous fournit `url` `route` et `params`.
### url
Une instance d'[`URL`](https://developer.mozilla.org/fr/docs/Web/API/URL), contenant des propriétés
comme `origin`, `hostname`, `pathname` et `searchParams` (qui contient les paramètres de recherche
sous la forme d'un objet
[`URLSearchParams`](https://developer.mozilla.org/fr/docs/Web/API/URLSearchParams)). `url.hash`
n'est pas accessible pendant l'exécution de `load`, car il n'est pas disponible sur le serveur.
> [!NOTE] Dans certains environnement, `url` est déduit des en-têtes de requêtes lors du rendu côté
> serveur. Si vous utilisez l'adaptateur [adapter-node](adapter-node), par exemple, vous pourriez
> avoir besoin de configurer votre adaptateur pour que l'URL soit correcte.
### route
Contient le nom du dossier de route actuel, relativement à `src/routes` :
```js
/// file: src/routes/a/[b]/[...c]/+page.js
/** @type {import('./$types').PageLoad} */
export function load({ route }) {
console.log(route.id); // '/a/[b]/[...c]'
}
```
### params
`params` est construit à partir de `url.pathname` et `route.id`.
Étant donné une `route.id` telle que `/a/[b]/[...c]` et un `url.pathname` de `/a/x/y/z`, l'objet
`params` va ressembler à ceci :
```json
{
"b": "x",
"c": "y/z"
}
```
## Faire des requêtes avec fetch [!VO]Making fetch requests
Pour récupérer des données depuis une API externe ou un gestionnaire `+server.js`, vous pouvez
utiliser la fonction `fetch` fournie, qui se comporte de la même façon que l'[API web `fetch`
native](https://developer.mozilla.org/fr/docs/Web/API/fetch) avec quelques fonctionnalités
additionnelles :
- Elle peut être utilisée pour faire de requêtes authentifiées sur le serveur, puisqu'elle hérite
des en-têtes `cookie` et `authorization` de la requête de page.
- Elle peut faire des requêtes relatives au serveur (normallement, `fetch` requiert une URL avec une
origine lorsqu'utilisée dans un contexte serveur).
- Les requêtes internes (par ex. pour les routes `+server.js`) vont appeler directement la fonction
de gestion lorsqu'exécutée sur le serveur, sans le surcoût d'un appel HTTP.
- Lors du rendu côté serveur, la réponse sera capturée et inlinée dans le HTML rendu en s'appuyant
sur les méthodes `text`, `json` et `arrayBuffer` de l'objet `Response`. Notez que les en-têtes ne
seront _pas_ sérialisées, à moins d'être explicitement incluses via
[`filterSerializedResponseHeaders`](hooks#Server-hooks-handle).
- Lors de l'hydratation, la réponse sera lue depuis le HTML, garantissant la consistance et
empêchant une requête additionnelle — si vous voyez un avertissement dans votre console de
navigateur lorsque vous utilisez le `fetch` natif du navigateur plutôt que le `fetch` de `load`,
en voici la raison.
```js
/// file: src/routes/items/[id]/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, params }) {
const res = await fetch(`/api/items/${params.id}`);
const item = await res.json();
return { item };
}
```
## Cookies
Une fonction `load` de serveur peut récupérer et définir des [`cookies`](@sveltejs-kit#Cookies).
```js
/// file: src/routes/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getUser(sessionid: string | undefined): Promise<{ name: string, avatar: string }>
}
// @filename: index.js
// ---cut---
import * as db from '$lib/server/database';
/** @type {import('./$types').LayoutServerLoad} */
export async function load({ cookies }) {
const sessionid = cookies.get('sessionid');
return {
user: await db.getUser(sessionid)
};
}
```
Les cookies ne seront passées à la fonction `fetch` de `load` que si l'hôte cible est le même que
celui de l'application SvelteKit, ou un sous-domaine spécifique de ce dernier.
Par exemple, si SvelteKit sert le domaine my.domain.com :
- domain.com NE VA PAS recevoir de cookies
- my.domain.com VA recevoir des cookies
- api.domain.com NE VA PAS recevoir des cookies
- sub.my.domain.com VA recevoir des cookies
Les autres cookies ne seront pas fournis lorsque `credentials: 'include'` est défini, car SvelteKit
ne connaît pas les domaines auxquels chaque cookie appartient (le navigateur ne fournit pas cette
information), et il ne serait donc pas sécurisé de les fournir. Utiliser le [hook
`handleFetch`](hooks#Server-hooks-handleFetch) pour contourner le problème.
## En-têtes [!VO]Headers
Les fonctions `load` universelles et de serveur ont toutes les deux accès à une fonction
`setHeaders` qui, lorsqu'exécutée sur le serveur, peut définir les en-têtes de la réponse.
(Lorsqu'exécutée dans le navigateur, `setHeaders` n'a pas d'effet.) C'est utile si vous souhaitez
que la page puisse être mise en cache, par exemple :
```js
// @errors: 2322 1360
/// file: src/routes/products/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, setHeaders }) {
const url = `https://cms.example.com/products.json`;
const response = await fetch(url);
// Les en-têtes ne sont définies que lors du SSR, pour mettre en cache le HTML de la page pour la
// même durée que la donnée sous-jacente.
setHeaders({
age: response.headers.get('age'),
'cache-control': response.headers.get('cache-control')
});
return response.json();
}
```
Définir la même en-tête plusieurs fois (même dans des fonctions `load` séparées) est une erreur.
Vous pouvez seulement définir une en-tête particulière une seule fois en utilisant la fonction
`setHeaders`. Vous ne pouvez pas définir l'en-tête `set-cookie` avec `setHeaders` — utilisez plutôt
`cookies.set(name, value, options)`.
## Utiliser les données du parent [!VO]Using parent data
Parfois, il est utile pour une fonction `load` d'avoir accès aux données d'une fonction `load`
parente, ce qui est possible via `await parent()` :
```js
/// file: src/routes/+layout.js
/** @type {import('./$types').LayoutLoad} */
export function load() {
return { a: 1 };
}
```
```js
/// file: src/routes/abc/+layout.js
/** @type {import('./$types').LayoutLoad} */
export async function load({ parent }) {
const { a } = await parent();
return { b: a + 1 };
}
```
```js
/// file: src/routes/abc/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ parent }) {
const { a, b } = await parent();
return { c: a + b };
}
```
```svelte
{data.a} + {data.b} = {data.c}
```
> [!NOTE] Notez que la fonction `load` de `+page.js` reçoit la donnée fusionnée des deux fonctions
> `load` de layout, pas uniquement celles du parent immédiat.
Dans `+page.server.js` et `+layout.server.js`, `parent` renvoie les données des fichiers
`+layout.server.js`.
Dans `+page.js` ou `+layout.js`, `parent` renvoie les données des fichiers `+layout.js`. Toutefois,
un `+layout.js` manquant est considéré comme une fonction `({ data }) => data`, ce qui implique
qu'il va également fournir les données des fichiers `+layout.server.js` parents qui ne sont pas
"cachés" par un fichier `+layout.js`.
Faites attention à ne pas introduire de "cascades de chargement" lorsque vous utilisez `await
parent()`. Ici par exemple, `getData()` ne dépend pas du résultat de l'appel de `parent()`, nous
devrions donc plutôt l'exécuter en premier pour éviter de retarder le rendu.
```js
/// file: +page.js
// @filename: ambient.d.ts
declare function getData(params: Record): Promise<{ meta: any }>
// @filename: index.js
// ---cut---
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
---const parentData = await parent();---
const data = await getData(params);
+++const parentData = await parent();+++
return {
...data,
meta: { ...parentData.meta, ...data.meta }
};
}
```
## Erreurs [!VO]Errors
Si une erreur est jetée lors d'une fonction `load`, la page [`+error.svelte`](routing#error) la plus
proche sera rendue. Pour les erreurs [_prévues_](errors#Expected-errors), utilisez l'utilitaire
`error` importé depuis `@sveltejs/kit` pour préciser le statut HTTP et un message optionnel :
```js
/// file: src/routes/admin/+layout.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user?: {
name: string;
isAdmin: boolean;
}
}
}
// @filename: index.js
// ---cut---
import { error } from '@sveltejs/kit';
/** @type {import('./$types').LayoutServerLoad} */
export function load({ locals }) {
if (!locals.user) {
error(401, 'non identifié');
}
if (!locals.user.isAdmin) {
error(403, 'pas un administrateur');
}
}
```
Appeler `error(...)` va lever une exception, ce qui vous permet de facilement arrêter l'exécution
depuis des fonctions utilitaires.
Si une erreur [_imprévue_](errors#Unexpected-errors) est levée, SvelteKit va exécuter le hook
[`handleError`](hooks#Shared-hooks-handleError) et la traiter comme une erreur 500 Internal Error.
> [!NOTE] [Dans SvelteKit
> 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you), vous deviez `throw`
> l'erreur vous-même.
## Redirections [!VO]Redirects
Pour rediriger les utilisateurs et utilisatrices, utilisez l'utilitaire `redirect` importé depuis
`@sveltejs/kit` et associé à un status `3xx` pour préciser l'endroit vers lequel ils ou elles
devraient être redirigé•e•s. Comme avec `error(...)`, exécuter `redirect(...)` va jeter une
exception, permettant d'arrêter l'exécution depuis des fonctions utilitaires.
```js
/// file: src/routes/user/+layout.server.js
// @filename: ambient.d.ts
declare namespace App {
interface Locals {
user?: {
name: string;
}
}
}
// @filename: index.js
// ---cut---
import { redirect } from '@sveltejs/kit';
/** @type {import('./$types').LayoutServerLoad} */
export function load({ locals }) {
if (!locals.user) {
redirect(307, '/login');
}
}
```
> [!NOTE] N'utilisez pas `redirect()` au sein d'un block `try {...}`, puisque la redirection va
> immédiatement déclencher l'exécution du `catch`.
Dans le navigateur, vous pouvez naviguer programmatiquement en dehors d'une fonction `load` en
utilisant [`goto`]($app-navigation#goto) importé depuis [`$app/navigation`]($app-navigation).
> [!NOTE] [Dans SvelteKit
> 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) vous deviez `throw`
> le `redirect` vous-même.
## Streamer grâce aux promesses [!VO]Streaming with promises
Lorsque vous utilisez une fonction `load` de serveur, les promesses vont être streamées vers le
navigateur à mesure qu'elles se résolvent. Cela peut être utile si vous avez des données lourdes et
non essentielles, puisque vous pouvez commencer le rendu de la page avant que toutes les données
soient disponibles :
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare global {
const loadPost: (slug: string) => Promise<{ title: string, content: string }>;
const loadComments: (slug: string) => Promise<{ content: string }>;
}
export {};
// @filename: index.js
// ---cut---
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
return {
// assurez-vous que le `await` se produise à la fin, sinon
// nous ne pouvons pas commencer le chargement des commentaires
// tant que l'article n'est pas chargé
comments: loadComments(params.slug),
post: await loadPost(params.slug)
};
}
```
C'est utile notamment pour créer des états de chargement, par exemple :
```svelte
{data.post.title}
{@html data.post.content}
{#await data.comments}
Chargement des commentaires...
{:then comments}
{#each comments as comment}
{comment.content}
{/each}
{:catch error}
erreur lors du chargement des commentaires : {error.message}
{/await}
```
Lorsque vous streamez des données, faites attention à gérer les rejets de promesses correctement.
Plus précisément, le serveur pourrait planter avec une erreur "unhandled promise rejection" ("rejet
de promesse non géré") si une promesse différée échoue avant le début du rendu (et donc est
"attrapé"), et que celle-ci n'est pas gérée d'une manière ou d'une autre. Lorsque vous utilisez
directement le `fetch` de SvelteKit dans une fonction `load`, SvelteKit va gérer cette situation
pour vous. Pour les autres promesses, il suffit d'attacher à la promesse un `catch` ne faisant rien
de spécial pour la marquer comme gérée.
```js
/// file: src/routes/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export function load({ fetch }) {
const ok_manual = Promise.reject();
ok_manual.catch(() => {});
return {
ok_manual,
ok_fetch: fetch('/fetch/that/could/fail'),
dangerous_unhandled: Promise.reject()
};
}
```
> [!NOTE] Sur de plateformes qui ne supportent pas le streaming, comme AWS Lambda ou Firebase, les
> réponses seront transformées en buffer. Ceci signifie que la page ne sera rendue qu'une fois que
> toutes les promesses auront été résolues. Si vous utilisez un proxy (par ex. NGINX), assurez-vous
> qu'il transforme pas les réponses du serveur qu'il relaye en buffers.
> [!NOTE] Streamer des données ne va fonctionner que si JavaScript est disponible. Vous devriez
> éviter de renvoyer des promesses depuis une fonction `load` universelle si la page est rendue côté
> serveur, puisque ces promesses-là ne sont _pas_ streamées — dans ce cas, la promesse est recréée
> lorsque la fonction est ré-exécutée dans le navigateur.
> [!NOTE] Les en-têtes et le statut d'une réponse ne peuvent pas être modifiés une fois que la
> réponse a commencé à être streamée, vous ne pouvez donc pas utiliser `setHeaders` ou des
> redirections au sein d'une promesses streamée.
> [!NOTE] [Avec SvelteKit 1.x](migrating-to-sveltekit-2#Top-level-promises-are-no-longer-awaited)
> les promesses créées à la racine étaient automatiquement attendues, et uniquement les promesses
> imbriquées étaient streamées.
## Chargement parallèle [!VO]Parallel loading
Lorsque du rendu d'une page (ou d'une navigation vers une page), SvelteKit exécute toutes les
fonctions `load` de manière concurrente, ce qui permet d'éviter une cascade de requêtes. Lors d'une
navigation côté client, les résultats de multiples appels à des fonctions `load` sont regroupés dans
une seule réponse. Une fois que toutes les fonctions `load` ont renvoyé leur réponse, la page est
rendue.
## Ré-exécuter des fonctions load [!VO]Rerunning load functions
SvelteKit enregistre les dépendances de chaque fonction `load` pour éviter de la ré-exécuter
inutilement lors des navigations.
Par exemple, étant donné une paire de fonctions `load` comme celles-ci...
```js
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content: string }>
}
// @filename: index.js
// ---cut---
import * as db from '$lib/server/database';
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
return {
post: await db.getPost(params.slug)
};
}
```
```js
/// file: src/routes/blog/[slug]/+layout.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPostSummaries(): Promise>
}
// @filename: index.js
// ---cut---
import * as db from '$lib/server/database';
/** @type {import('./$types').LayoutServerLoad} */
export async function load() {
return {
posts: await db.getPostSummaries()
};
}
```
... celle dans `+page.server.js` sera rejouée si nous naviguons depuis
`/blog/trying-the-raw-meat-diet` vers `/blog/i-regret-my-choices` car `params.slug` a changé. Celle
dans `+layout.server.js` ne sera pas rejouée, car ses données sont toujours considérées comme
valides. En d'autres mots, nous n'appellerons pas `db.getPostSummaries()` une deuxième fois.
Une fonction `load` qui exécute `await parent()` sera également rejouée si une fonction `load`
parente est rejouée.
Le suivi des dépendances ne s'applique pas _après_ que la fonction `load` a renvoyé ses données —
par exemple, lire `params.x` dans une [promesse](#Streaming-with-promises) imbriquée ne va pas
déclencher la ré-exécution de la fonction lorsque `params.x` change. (Ne vous inquiétez pas, vous
aurez un avertissement en mode développement si vous faites cela.) Pour éviter cela, lisez le
paramètre dans le corps principal de votre fonction `load`.
Les paramètres de recherche sont suivis indépendamment du reste de l'URL. Par exemple, lire
`event.url.searchParams.get("x")` dans une fonction `load` va déclencher la ré-exécution de la
fonction `load` lors d'une navigation depuis `?x=1` vers `?x=2`, mais pas lors d'une navigation
depuis `?x=1&y=1` vers `?x=1&y=2`.
### Arrêter le suivi des dépendances [!VO]Untracking dependencies
Dans de rares situations, vous pourriez vouloir exclure quelque chose du mécanisme de suivi des
dépendances. Vous pouvez faire cela grâce à la fonction `untrack` fournie par `load` :
```js
/// file: src/routes/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ untrack, url }) {
// arrête le suivi de url.pathname afin qu'un changement de path de
// déclenche pas une ré-exécution
if (untrack(() => url.pathname === '/')) {
return { message: 'Bienvenue !' };
}
}
```
### Invalidation manuelle [!VO]Manual invalidation
Vous pouvez également ré-exécuter des fonctions `load` s'appliquant à la page actuelle en utilisant
[`invalidate(url)`]($app-navigation#invalidate), ce qui ré-exécute toutes les fonctions `load` qui
dépendent d'`url`, ou [`invalidateAll()`]($app-navigation#invalidateAll), qui ré-exécute toutes les
fonctions `load`. Les fonctions `load` de serveur ne vont jamais être automatiquement dépendantes
d'une `url` utilisées par un `fetch` pour éviter de fuiter des informations sensibles au client.
Une fonction `load` dépend de l'`url` si elle exécute `fetch(url)` ou `depends(url)`. Notez qu'`url`
peut être un identifiant qui commence par `[a-z]` :
```js
/// file: src/routes/random-number/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ fetch, depends }) {
// load est ré-exécutée lorsque `invalidate('https://api.example.com/random-number') est
// appelée...
const response = await fetch('https://api.example.com/random-number');
// ... ou lorsque `invalidate('app:random') est appelée
depends('app:random');
return {
number: await response.json()
};
}
```
```svelte