Skip to main content

Options de page

Par défaut, SvelteKit va rendre (ou pré-rendre) tout composant d’abord sur le serveur puis l’envoyer au client en tant que HTML. Le composant sera ensuite rendu de nouveau dans le navigateur pour le rendre interactif dans un processus appelée hydratation. Pour cette raison, vous devez vous assurer que les composants puissent être exécutés à la fois sur le serveur et dans le navigateur. Puis Sveltekit initialisera un routeur côté client qui va prendre le relais pour toutes les navigations à venir.

Vous pouvez contrôler chacune de ces étapes page par page en exportant des options depuis les fichiers +page.js ou +page.server.js, ou pour des groupes de page en exportant ces options depuis un fichier +layout.js ou +layout.server.js partagé par les pages concernées. Pour définir une option pour toute l’application, exportez-la depuis le layout racine. Les layouts enfants et les pages surchargent les valeurs des options définies dans des layouts parents, ce qui veut dire que, — par exemple — vous pouvez activer le pré-rendu pour toute votre application puis le désactiver pour les pages qui ont besoin d’être rendues dynamiquement.

Vous pouvez mélanger ces options à différents endroits de votre application. Par exemple, vous pourriez pré-rendre votre page marketing pour optimiser sa vitesse d’affichage, rendre sur le serveur vos pages dynamiques pour en optimiser le référencement et l’accessibilité, et faire de votre section d’administration une SPA en la rendant uniquement côté client. Tout cela rend SvelteKit très versatile.

prerender

Il est probable qu’au moins quelques unes des routes de votre application puisse être représentées comme un simple fichier HTML généré au moment de la compilation. Ces routes peuvent être pré-rendues.

+page.js/+page.server.js/+server
export const const prerender: trueprerender = true;

Vous pouvez également définir export const prerender = true dans votre fichier +layout.js ou ou +layout.server.js racine, et pré-rendre toute votres application à l’exception des pages qui se définissent explicitement comme ne devant pas être pré-rendues :

+page.js/+page.server.js/+server
export const const prerender: falseprerender = false;

Les routes avec prerender = true seront exclues des manifestes utilisés pour le rendu côté serveur (SSR) dynamique, diminuant le poids de votre serveur (ou de vos fonctions serverless/edge). Dans certains cas, vous pourriez vouloir pré-rendre une route mais également l’inclure dans le manifeste (par exemple, avec une route comme /blog/[slug], dont vous souhaitez pré-rendre le contenu le plus populaire/récent mais rendre sur le serveur le reste) — pour ces situations, il existe une troisième option, 'auto' :

+page.js/+page.server.js/+server
export const const prerender: "auto"prerender = 'auto';

Si toute votre application est compatible avec le pré-rendu, vous pouvez utiliser l’adaptateur adapter-static, qui va générer des fichiers pouvant être utilisés avec n’importe quel serveur web statique.

Le processus de pré-rendu commence à la racine de votre application et génère des fichiers pour toutes les pages ou routes +server.js pouvant être pré-rendues qu’il trouve. Chaque page est scannée à la recherche d’éléments <a> pointant vers d’autres pages candidates au pré-rendu — pour cette raison, vous n’avez pas besoin de préciser quelles pages doivent être accessibles au processus de pré-rendu. Si vous devez préciser les pages devant être accessibles au processus de pré-rendu, vous pouvez le faire avec config.kit.prerender.entries, ou en exportant une fonction entries de votre route dynamique.

Pendant le pré-rendu, la valeur de building importée depuis $app/environment sera true.

Pré-rendu des routes de serveur

À la différence des autres options de page, prerender s’applique aussi aux fichiers +server.js. Ces fichiers ne sont pas affectés par les layouts, mais hériteront des valeurs par défaut de l’option des pages qui leur demandent des données, s’il en existe. Par exemple, si un fichier +page.js contient cette fonction load...

+page
export const const prerender: trueprerender = true;

/** @type {import('./$types').PageLoad} */
export async function 
function load({ fetch }: {
    fetch: any;
}): Promise<any>
@type{import('./$types').PageLoad}
load
({ fetch: anyfetch }) {
const const res: anyres = await fetch: anyfetch('/my-server-route.json'); return await const res: anyres.json(); }
import type { 
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageLoad
} from './$types';
export const const prerender: trueprerender = true; export const const load: PageLoadload:
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageLoad
= async ({
fetch: {
    (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
    (input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
}

fetch is equivalent to the native fetch web API, with a few additional features:

  • It can be used to make credentialed requests on the server, as it inherits the cookie and authorization headers for the page request.
  • It can make relative requests on the server (ordinarily, fetch requires a URL with an origin when used in a server context).
  • Internal requests (e.g. for +server.js routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
  • During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the text and json methods of the Response object. Note that headers will not be serialized, unless explicitly included via filterSerializedResponseHeaders
  • During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.

You can learn more about making credentialed requests with cookies here

fetch
}) => {
const const res: Responseres = await fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response> (+1 overload)fetch('/my-server-route.json'); return await const res: Responseres.Body.json(): Promise<any>json(); };

... alors le fichier src/routes/my-server-route.json/+server.js sera traité comme candidat au pré-rendu s’il ne contient pas son propre export const prerender = false.

Quand ne pas pré-rendre

La règle d’or est la suivante : pour qu’une page puisse être pré-rendue, deux personnes arrivant directement sur cette page doivent obtenir le même contenu du serveur.

Toutes les pages ne sont pas compatibles avec le pré-rendu. Tout contenu qui est pré-rendu sera vu par toutes les utilisateurs et utilisatrices. Vous pouvez bien sûr récupérer des données personnalisées via onMount dans une page pré-rendue, mais cela peut se traduire en une moins bonne expérience utilisateur, puisque cela implique d’afficher initialement un contenu vide ou des indicateurs de chargement.

Notez que vous pouvez toujours pré-rendre des pages qui chargent leurs données en fonction des paramètres de page, comme sur une route src/routes/blog/[slug]/+page.svelte.

Lire url.searchParams pendant le pré-rendu est interdit. Si vous devez vous en servir, assurez-vous que vous le faites uniquement dans le navigateur (par exemple avec onMount).

Les pages comportant des actions ne peuvent pas être prérendues, car un serveur doit être capable de gérer les requêtes POST venant de l’action.

Conflits de route

Puisque le pré-rendu écrit dans le système de fichiers, il n’est pas possible d’avoir deux endpoints qui génèreraient un dossier et un fichier avec le même nom. Par exemple, src/routes/foo/+server.js et src/routes/foo/bar/+server.js vont essayer de créer foo et foo/bar, ce qui est impossible.

Pour cette raison parmi d’autres, il est recommandé de toujours inclure une extension de fichier — src/routes/foo.json/+server.js et src/routes/foo/bar.json/+server.js vont créer des fichiers foo.json et foo/bar.json qui peut coexister en harmonie côte-à-côte.

Pour les pages, nous contournons ce problème en écrivant foo/index.html au lieu de foo.

Résolution de problèmes

Si vous rencontrez une erreur comme ‘The following routes were marked as prerenderable, but were not prerendered’ (“Les routes suivantes ont été marquées comme devant être pré-rendues, mais n’ont pas été pré-rendues”), c’est parce que la route en question (ou éventuellement un layout parent, si c’est une page) a l’option export const prerender = true mais la page n’a pas été atteinte par le processus de pré-rendu, et n’a donc pas été pré-rendue.

Puisque ces routes ne peuvent pas être dynamiquement rendues sur le serveur, ceci va causer des erreurs pour les personnes qui essaieraient d’accéder à la route en question. Il y a quelques moyens de régler ce problème :

  • Assurez-vous que SvelteKit peut trouver la route en suivant des liens depuis les entrées précisées dans config.kit.prerender.entries ou dans l’option de page entries. Ajoutez des liens aux routes dynamiques (c-à-d les pages avec des [parameters]) à cette option si celles-ci ne sont pas trouvables en passant par les autres point d’entrée, sans quoi elles ne seront pas pré-rendues car SvelteKit ne peut pas savoir quelles valeurs les paramètres peuvent avoir. Les pages non marquées comme pouvant être pré-rendues seront ignorées et leurs liens vers d’autres pages ne seront pas utilisés lors du processus de pré-rendu, même si certaines d’entre elles pourraient être pré-rendues.
  • Assurez-vous que SvelteKit peut trouver la route en découvrant un lien la ciblant depuis l’une des autres pages pré-rendues ayant du rendu côté serveur activé.
  • Changez export const prerender = true en export const prerender = 'auto'. Les routes avec 'auto' peuvent être dynamiquement rendues sur le serveur.

entries

SvelteKit va découvrir les pages à pré-rendre automatiquement, en commençant par les points d’entrée et en les parcourant. Par défaut, toutes vos routes non dynamiques sont considérées comme des points d’entrée — par exemple, si vous avez ces routes...

/    # non dynamique
/blog# non dynamique
/blog/[slug]  # dynamique, à cause de `[slug]`

... SvelteKit va prérendre / and /blog, et au cours du processus découvrir des liens comme <a href="/blog/hello-world>, lui donnant de nouvelles pages à pré-rendre.

La plupart du temps, c’est suffisant. Dans certaines situations, les liens vers des pages comme /blog/hello-world peuvent ne pas exister (ou peuvent ne pas exister sur des pages pré-rendues), auquel cas il est nécessaire de déclarer à SvelteKit leur existence.

Vous pouvez faire cela avec config.kit.prerender.entries, ou en exportant une fonction entries depuis un fichier +page.js, +page.server.js ou +server.js appartenant à une route dynamique :

src/routes/blog/[slug]/+page.server
/** @type {import('./$types').EntryGenerator} */
export function 
function entries(): {
    slug: string;
}[]
@type{import('./$types').EntryGenerator}
entries
() {
return [ { slug: stringslug: 'hello-world' }, { slug: stringslug: 'another-blog-post' } ]; } export const const prerender: trueprerender = true;
import type { 
type EntryGenerator = () => Promise<Array<Record<string, any>>> | Array<Record<string, any>>
type EntryGenerator = () => Promise<Array<Record<string, any>>> | Array<Record<string, any>>
EntryGenerator
} from './$types';
export const const entries: EntryGeneratorentries:
type EntryGenerator = () => Promise<Array<Record<string, any>>> | Array<Record<string, any>>
type EntryGenerator = () => Promise<Array<Record<string, any>>> | Array<Record<string, any>>
EntryGenerator
= () => {
return [ { slug: stringslug: 'hello-world' }, { slug: stringslug: 'another-blog-post' } ]; }; export const const prerender: trueprerender = true;

entries peut être une fonction async, vous permettant (par exemple) de récupérer une liste d’articles depuis un CMS ou une base de données, dans l’exemple ci-dessus.

ssr

Normalement, SvelteKit rend votre page d’abord sur le serveur, puis envoie le HTML construit vers le client où celui-ci va être hydraté. Si vous définissez ssr à false, la page construite par le serveur sera alors une “coquille” vide. C’est utile si votre page ne peut pas être rendue sur le serveur (parce que vous utilisez des variables globales comme document par exemple), mais dans la plupart des situations, ce n’est pas recommandé (voir les annexes).

+page
export const const ssr: falsessr = false;
// Si à la `ssr` et `csr` sont `false`, rien ne sera affiché !

Si vous ajoutez export const ssr = false à votre fichier +layout.js racine, votre application toute entière sera uniquement rendue sur le client — ce qui signifie que votre application devient une SPA.

Si toutes vos options de page sont des valeurs booléenes ou des chaînes de caractères litérales, SvelteKit va les évaluer de manière statique. Sinon, il va importer votre fichier +page.js ou +layout.js sur le serveur (à la fois lors de compilation et à l’exécution si votre application n’est pas complètement statique) afin d’en évaluer les options. Dans le deuxième cas, du code exclusif au navigateur ne doit pas être exécuté lorsque le module se charge. En pratique, ceci signifie que vous devriez plutôt importer votre code exclusif au navigateur dans votre fichier +page.svelte ou +layout.svelte.

csr

D’ordinaire, SvelteKit hydrate votre HTML rendu sur le serveur (SSR) en une page interactive rendue sur le client (CSR). Certaines pages ne nécessitent pas du tout JavaScript — la plupart des articles de blog et des pages “à propos” tombent dans cette catégorie. Dans ces cas-là vous pouvez désactiver le CSR.

+page
export const const csr: falsecsr = false;
// Si à la `ssr` et `csr` sont `false`, rien ne sera affiché !

Désactiver le CSR permet de ne pas envoyer de JavaScript au client. Cela signifie :

  • La page web doit pouvoir fonctionner avec uniquement du HTML et du CSS.
  • Les balises <script> au sein des composants Svelte vont être supprimées.
  • Les éléments <form> ne peuvent pas être améliorés progressivement.
  • Les liens sont gérés par le navigateur et génèrent un rechargement complet de la page lors des navigations.
  • Le remplacement instantané de modules (Hot Module Replacement, ou HMR) est désactivé.

Vous pouvez activer le csr pendant le développement (par exemple pour tirer profit du HMR) de cette manière :

+page
import { const dev: boolean

Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.

dev
} from '$app/environment';
export const const csr: booleancsr = const dev: boolean

Whether the dev server is running. This is not guaranteed to correspond to NODE_ENV or MODE.

dev
;

trailingSlash

Par défaut, SvelteKit va supprimer les slashs à la fin des URLs — si vous allez sur /about, SvelteKit va répondre avec une redirection vers /about. Vous pouvez changer ce comportement avec l’option trailingSlash, qui peut avoir comme valeur 'never' (valeur par défaut), 'always', ou 'ignore'.

Comme avec les autres options de page, vous pouvez exporter cette valeur depuis un fichier +layout.js ou +layout.server.js, et celle-ci s’appliquera alors à toutes les pages enfant. Vous pouvez aussi exporter la configuration depuis des fichiers +server.ts.

src/routes/+layout
export const const trailingSlash: "always"trailingSlash = 'always';

Cette option affecte aussi le pré-rendu. Si trailingSlash vaut 'always', une route comme /about va générer un fichier about/index.html, sinon le fichier généré sera about.html, comme recommandé par les conventions de serveur web statiques.

Il n’est pas recommandé d’ignorer les slashs de fin d’URLs — la sémantique des chemins relatifs diffère entre les 2 situations (./y depuis /x est /y, mais depuis /x/ c’est /x/y), et /x et /x/ sont traités comme des URLs différentes, ce qui pénalise le référencement.

config

Avec le concept d’adaptateurs, SvelteKit est capable de tourner sur une grande variété de plateformes. Chacune d’entre elles peut avoir une configuration spécifique permettant de modifier le déploiement — par exemple sur Vercel vous pourriez choisir de déployer certaines parties de votre application sur l’edge et d’autres sur des environnements serverless.

config est un objet de paires clé-valeur à la racine. À part ça, sa forme dépend de l’adaptateur que vous utilisez. Chaque adaptateur devrait fournir une interface Config à importer pour fournir le typage adapté. Consultez la documentation de votre adaptateur pour plus d’informations.

src/routes/+page
/** @type {import('some-adapter').Config} */
export const const config: Config
@type{import('some-adapter').Config}
config
= {
Config.runtime: stringruntime: 'edge' };
import type { Config } from 'some-adapter';


export const const config: Configconfig: Config = {
	Config.runtime: stringruntime: 'edge'
};

Les objets config sont fusionnés au premier niveau (mais pas plus profond). Ceci signifie que vous n’avez pas besoin de répéter toutes les valeurs dans un fichier +page.js si vous souhaitez uniquement surcharger quelques unes des valeurs définies dans un fichier +layout.js. Par exemple, cette configuration de layout...

src/routes/+layout
export const 
const config: {
    runtime: string;
    regions: string;
    foo: {
        bar: boolean;
    };
}
config
= {
runtime: stringruntime: 'edge', regions: stringregions: 'all',
foo: {
    bar: boolean;
}
foo
: {
bar: booleanbar: true } }

... est surchargée par cette configuration de page...

src/routes/+page
export const 
const config: {
    regions: string[];
    foo: {
        baz: boolean;
    };
}
config
= {
regions: string[]regions: ['us1', 'us2'],
foo: {
    baz: boolean;
}
foo
: {
baz: booleanbaz: true } }

... ce qui résulte dans la valeur de configuration { runtime: 'edge', regions: ['us1', 'us2'], foo: { baz: true } } pour cette page.

Plus de lecture

Modifier cette page sur Github llms.txt