Skip to main content

Routing

Au coeur de SvelteKit se trouve un routeur basé sur le système de fichiers. Les routes de votre application — c-à-d les chemins d’URL auquels les utilisateurs et utilisatrices peuvent accéder — sont définis par les dossiers de votre projet :

  • src/routes est la route racine
  • src/routes/about crée une route /about
  • src/routes/blog/[slug] crée une route avec un paramètre, slug, qui peut être utilisé pour charger des données de manière dynamique lorsqu’un utilisateur ou utilisatrice requête une page comme /blog/hello-world

Vous pouvez changer src/routes pour utiliser un dossier différent en modifiant la configuration de votre projet.

Chaque dossier de route contient un ou plusieurs fichiers de route, qui sont identifiables à leur préfixe +.

Nous présenterons bientôt ces fichiers dans le détail, mais voici déjà quelques règles simples pour vous aider à vous souvenir comment le routing de SvelteKit fonctionne :

  • Tous les fichiers peuvent être exécutés sur le serveur
  • Tous les fichiers peuvent être exécutés côté client, sauf les fichiers +server
  • Les fichiers +layout et +error s’appliquent au dossier dans lequel ils sont définis, ainsi qu’à tous les sous-dossiers de ce dossier

+page

+page.svelte

Un composant +page.svelte définit une page de votre application. Par défaut, les pages sont rendues à la fois sur le serveur (SSR) pour la requête initiale, et dans le navigateur (CSR) pour les navigations suivantes.

src/routes/+page
<h1>Bonjour et bienvenue sur mon site !</h1>
<a href="/about">À propose de mon site</a>
src/routes/about/+page
<h1>À propos de ce site</h1>
<p>TODO...</p>
<a href="/">Accueil</a>

SvelteKit utilise les éléments <a> pour naviguer entre les routes, plutôt qu’un composant spécifique au framework, comme <Link> par exemple.

Les pages peuvent recevoir des données des fonctions load via la prop data.

src/routes/blog/[slug]/+page
<script>
	/** @type {import('./$types').PageProps} */
	let { data } = $props();
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>
<script lang="ts">
	import type { PageProps } from './$types';

	let { data }: PageProps = $props();
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>
Legacy mode

PageProps a été ajouté dans la version 2.16.0 de SvelteKit. Dans les versions antérieures, vous deviez typer les propriétés data manuellement avec PageData, voir $types.

En Svelte 4, vous deviez utiliser export let data.

+page.js

Souvent, une page a besoin de charger des données avant de pouvoir être rendue. Pour cela, nous pouvons ajouter un module +page.js qui exporte une fonction load :

src/routes/blog/[slug]/+page
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */ export function
function load({ params }: {
    params: any;
}): {
    title: string;
    content: string;
}
@type{import('./$types').PageLoad}
load
({ params: anyparams }) {
if (params: anyparams.slug === 'hello-world') { return { title: stringtitle: 'Bonjour tout le monde !', content: stringcontent: 'Bienvenue sur notre blog. Lorem ipsum dolor sit amet...' }; }
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
}
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
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 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
= ({ params: Record<string, any>

The parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object

params
}) => {
if (params: Record<string, any>

The parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object

params
.slug === 'hello-world') {
return { title: stringtitle: 'Bonjour tout le monde !', content: stringcontent: 'Bienvenue sur notre blog. Lorem ipsum dolor sit amet...' }; }
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
};

Cette fonction est exécutée avec +page.svelte, ce qui signifie qu’elle est exécutée lors du rendu côté serveur, et dans le navigateur lors de la navigation côté client. Voir load pour plus de détails sur l’API.

En plus de load, +page.js peut exporter des valeurs qui configurent le comportement de la page :

  • export const prerender = true ou false ou 'auto'
  • export const ssr = true ou false
  • export const csr = true ou false

Vous pouvez trouver plus d’informations sur ces options dans le chapitre Options de page.

+page.server.js

Si votre fonction load ne peut pas être exécutée ailleurs que sur le serveur — par exemple, si elle a besoin de récupérer des données depuis une base de données ou si vous avez besoin de lire des variables d’environnement privées comme des clés d’API — vous pouvez alors renommer +page.js en +page.server.js et changer le type de PageLoad en PageServerLoad.

src/routes/blog/[slug]/+page.server
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
/** @type {import('./$types').PageServerLoad} */ export async function function load(event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>): MaybePromise<void | Record<string, any>>
@type{import('./$types').PageServerLoad}
load
({ params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.

params
}) {
const
const post: {
    title: string;
    content: string;
}
post
= await
const getPostFromDatabase: (slug: string) => {
    title: string;
    content: string;
}
getPostFromDatabase
(params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.

params
.slug);
if (
const post: {
    title: string;
    content: string;
}
post
) {
return
const post: {
    title: string;
    content: string;
}
post
;
}
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
}
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
import type { type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>PageServerLoad } from './$types'; export const const load: PageServerLoadload: type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>PageServerLoad = async ({ params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.

params
}) => {
const
const post: {
    title: string;
    content: string;
}
post
= await
const getPostFromDatabase: (slug: string) => {
    title: string;
    content: string;
}
getPostFromDatabase
(params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.

params
.slug);
if (
const post: {
    title: string;
    content: string;
}
post
) {
return
const post: {
    title: string;
    content: string;
}
post
;
}
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
};

Lors de la navigation côté client, SvelteKit va charger ces données sur le serveur, ce qui signifie que la valeur renvoyée doit être sérialisable par devalue. Voir le chapitre load pour plus de détails sur l’API.

Comme +page.js, +page.server.js peut exporter des options de pageprerender, ssr et csr.

Un fichier +page.server.js peut également exporter des actions. Si load vous permet de lire des données sur le serveur, actions vous permet d’écrire des données sur le serveur en utilisant l’élément <form>. Pour apprendre comment vous en servir, voir la section sur les actions de formulaire.

+error

Si une erreur se produit pendant l’exécution de load, SvelteKit va rendre une page d’erreur par défaut. Vous pouvez personnaliser cette page d’erreur route par route en ajoutant un fichier +error.svelte :

src/routes/blog/[slug]/+error
<script>
	import { page } from '$app/state';
</script>

<h1>{page.status}: {page.error.message}</h1>
<script lang="ts">
	import { page } from '$app/state';
</script>

<h1>{page.status}: {page.error.message}</h1>
Legacy mode

$app/state a été ajouté dans la version 2.12 de SvelteKit. Si vous utilisez une version plus ancienne ou si vous utilisez Svelte 4, utilisez plutôt $app/stores.

SvelteKit va “remonter à la racine” à la recherche de la frontière d’erreur la plus proche — si le fichier dans l’exemple ci-dessus n’existait pas, il essaierait src/routes/blog/+error.svelte, puis src/routes/+error.svelte avant de rendre la page d’erreur par défaut. Si ceci échoue (ou si l’erreur a été levée depuis la fonction load du +layout racine, qui est conceptuellement "au-dessus” du fichier +error racine), SvelteKit va sauver les meubles et rendre une page d’erreur statique de secours, que vous pouvez personnaliser en créant un fichier src/error.html.

Si l’erreur se produit dans une fonction load d’un +layout(.server).js, la frontière d’erreur la plus proche dans l’arbre est un fichier +error.svelte “au-dessus” de ce layout (et non au même "endroit”).

Si aucune route ne peut être trouvée (404), le fichier src/routes/+error.svelte (ou la page d’erreur par défaut si ce fichier n’existe pas), sera utilisé.

+error.svelte n’est pas utilisé lorsqu’une erreur se produit au sein de ‘handle’ ou d’un gestionnaire de requête +server.js.

Vous pouvez en apprendre plus sur la gestion des erreurs ici.

+layout

Jusqu’à maintenant, nous avons traité les pages comme des composants autonomes — lors d’une navigation, le composant +page.svelte existant est détruit, et un nouveau vient le remplacer.

Mais dans beaucoup d’applications, certains éléments doivent être visibles sur chaque page, comme par exemple les éléments principaux de navigation ou un pied-de-page. Plutôt que les répéter dans chaque fichier +page.svelte, nous pouvons les mettre dans des layouts.

+layout.svelte

Pour créer un layout qui s’applique à toutes les pages, créez un fichier appelé src/routes/+layout.svelte. Le layout par défaut (celui que SvelteKit utilise si vous n’en créez pas un vous-même) ressemble à ça...

<script>
	let { children } = $props();
</script>

{@render children()}

... mais nous pouvons ajouter n’importe quel markup, style, ou comportement. Le chose requise est que le composant doit inclure une balise @render pour afficher le contenu de la page. Par exemple, ajoutons une barre de navigation :

src/routes/+layout
<script>
	let { children } = $props();
</script>

<nav>
	<a href="/">Accueil</a>
	<a href="/about">À propos</a>
	<a href="/settings">Paramètres</a>
</nav>

{@render children()}
<script lang="ts">
	let { children } = $props();
</script>

<nav>
	<a href="/">Accueil</a>
	<a href="/about">À propos</a>
	<a href="/settings">Paramètres</a>
</nav>

{@render children()}

Si nous créons les pages correspondant à /, /about et /settings...

src/routes/+page
<h1>Accueil</h1>
src/routes/about/+page
<h1>À propos</h1>
src/routes/settings/+page
<h1>Paramètres</h1>

... la barre de navigation sera toujours visible, et la navigation entre ces trois pages ne va se traduire uniquement par le remplacement du <h1>.

Les layouts peuvent être imbriqués. Supposez que n’ayons pas une seule page /settings, mais plutôt des pages imbriquées comme /settings/profiles et /settings/notifications avec un sous-menu commun (vous pouvez retrouver un exemple de la vraie vie sur la page github.com/settings).

Nous pouvons créer un layout qui s’applique uniquement aux pages sous la route /settings (tout en héritant du layout racine qui contient la barre de navigation principale) :

src/routes/settings/+layout
<script>
	/** @type {import('./$types').LayoutProps} */
	let { data, children } = $props();
</script>

<h1>Settings</h1>

<div class="submenu">
	{#each data.sections as section}
		<a href="/settings/{section.slug}">{section.title}</a>
	{/each}
</div>

{@render children()}
<script lang="ts">
	import type { LayoutProps } from './$types';

	let { data, children }: LayoutProps = $props();
</script>

<h1>Settings</h1>

<div class="submenu">
	{#each data.sections as section}
		<a href="/settings/{section.slug}">{section.title}</a>
	{/each}
</div>

{@render children()}
Legacy mode

LayoutProps a été ajouté dans la version 2.16.0 de SvelteKit. Dans les versions antérieures, vous deviez typer les propriétés manuellement.

Vous pouvez maintenant constater la manière dont data est remplie en inspectant l’exemple de +layout.js de la prochaine section, juste en-dessous.

Par défaut, chaque layout hérite du layout au-dessus de lui. Parfois ce n’est pas ce que souhaitez — dans ce cas, les layouts avancés peuvent être utiles.

+layout.js

Tout comme +page.svelte vient charger ses données de +page.js, un composant +layout.svelte peut charger ses données depuis la fonction load d’un +layout.js.

src/routes/settings/+layout
/** @type {import('./$types').LayoutLoad} */
export function 
function load(): {
    sections: {
        slug: string;
        title: string;
    }[];
}
@type{import('./$types').LayoutLoad}
load
() {
return {
sections: {
    slug: string;
    title: string;
}[]
sections
: [
{ slug: stringslug: 'profile', title: stringtitle: 'Profil' }, { slug: stringslug: 'notifications', title: stringtitle: 'Notifications' } ] }; }
import type { 
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutLoad
} from './$types';
export const const load: LayoutLoadload:
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutLoad
= () => {
return {
sections: {
    slug: string;
    title: string;
}[]
sections
: [
{ slug: stringslug: 'profile', title: stringtitle: 'Profil' }, { slug: stringslug: 'notifications', title: stringtitle: 'Notifications' } ] }; };

Si un fichier +layout.js exporte des options de pagesprerender, ssr et csr — ces options seront utilisées comme valeurs par défaut pour les pages enfant.

Les données renvoyées par la fonction load d’un layout sont également disponibles pour toutes ses pages enfant :

src/routes/settings/profile/+page
<script>
	/** @type {import('./$types').PageProps} */
	let { data } = $props();

	console.log(data.sections); // [{ slug: 'profile', title: 'Profil' }, ...]
</script>
<script lang="ts">
	import type { PageProps } from './$types';

	let { data }: PageProps = $props();

	console.log(data.sections); // [{ slug: 'profile', title: 'Profil' }, ...]
</script>

Souvent, les données de layout ne changent pas lors de la navigation entre pages. SvelteKit ré-exécute intelligemment les fonctions load uniquement lorsque c’est nécessaire.

+layout.server.js

Pour exécuter sur le serveur la fonction load de votre layout, déplacez-la dans un fichier +layout.server.js, et changer le type LayoutLoad en LayoutServerLoad.

Comme +layout.js, +layout.server.js peut exporter des options de pageprerender, ssr et csr.

+server

Comme pour les pages, vous pouvez définir des routes avec un fichier +server.js (parfois appelé "route d’API” ou “endpoint”), ce qui vous donne un contrôle total sur la réponse. Votre fichier +server.js exporte des fonctions correspondant aux verbes HTTP comme GET, POST, PATCH, PUT, DELETE, OPTIONS, et HEAD qui prennent en argument un RequestEvent et renvoient un objet Response.

Par exemple, nous pourrions créer une route /api/random-number avec un gestionnaire GET :

src/routes/api/random-number/+server
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */ export function
function GET({ url }: {
    url: any;
}): Response
@type{import('./$types').RequestHandler}
GET
({ url: anyurl }) {
const const min: numbermin =
var Number: NumberConstructor
(value?: any) => number

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
(url: anyurl.searchParams.get('min') ?? '0');
const const max: numbermax =
var Number: NumberConstructor
(value?: any) => number

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
(url: anyurl.searchParams.get('max') ?? '1');
const const d: numberd = const max: numbermax - const min: numbermin; if (function isNaN(number: number): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).

@paramnumber A numeric value.
isNaN
(const d: numberd) || const d: numberd < 0) {
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(400, 'min et max doivent être des nombres, et min doit être plus petit que max');
} const const random: numberrandom = const min: numbermin + var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
(
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

String
(const random: numberrandom));
}
import { function error(status: number, body: App.Error): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
import type {
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
} from './$types';
export const const GET: RequestHandlerGET:
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
= ({ url: URL

The requested URL.

url
}) => {
const const min: numbermin =
var Number: NumberConstructor
(value?: any) => number

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
(url: URL

The requested URL.

url
.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | null

Returns the first value associated to the given search parameter.

MDN Reference

get
('min') ?? '0');
const const max: numbermax =
var Number: NumberConstructor
(value?: any) => number

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
(url: URL

The requested URL.

url
.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | null

Returns the first value associated to the given search parameter.

MDN Reference

get
('max') ?? '1');
const const d: numberd = const max: numbermax - const min: numbermin; if (function isNaN(number: number): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).

@paramnumber A numeric value.
isNaN
(const d: numberd) || const d: numberd < 0) {
function error(status: number, body?: {
    message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)

Throws an error with a HTTP status code and an optional message. When called during request handling, this will cause SvelteKit to return an error response without invoking handleError. Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(400, 'min et max doivent être des nombres, et min doit être plus petit que max');
} const const random: numberrandom = const min: numbermin + var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
(
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

String
(const random: numberrandom));
};

Le premier argument à Response peut être un ReadableStream, rendant possible le streaming de grandes quantité de données ou bien la création d’évènements envoyés par le serveur (à moins que vous déployiez sur des plateformes qui transforment les réponses en buffers, comme AWS Lambda).

Vous pouvez utiliser les méthodes error, redirect, et json de @sveltejs/kit pour des raisons pratiques (mais leur usage n’est pas nécessaire).

Si une erreur est jetée (soit avec error(...), soit par un évènement inattendu), la réponse sera une représentation JSON de l’erreur ou la page d’erreur de secours — qui peut être personnalisée via src/error.html — en fonction de l’en-tête Accept. Le composant +error.svelte ne sera pas rendu dans ce cas. Vous pouvez en savoir plus sur la gestion des erreurs ici.

Lorsque vous créez un gestionnaire OPTIONS, notez que Vite va injecter les en-têtes Acces-Control-Allow-Origin et Access-Control-Allow-Methods — ceux-ci ne seront présents en production à moins que vous les y ajoutiez.

Les fichiers +layout n’ont aucun effet sur les fichiers +server.js. Si vous souhaitez exécuter de la logique avant chaque requête, ajoutez-la dans le hook serveur handle.

Recevoir des données

En exportant des gestionnaires POST / PUT/PATCH/DELETE/OPTIONS/HEAD, les fichiers +server.js peuvent être utilisés pour créer une API complète :

src/routes/add/+page
<script>
	let a = 0;
	let b = 0;
	let total = 0;

	async function add() {
		const response = await fetch('/api/add', {
			method: 'POST',
			body: JSON.stringify({ a, b }),
			headers: {
				'content-type': 'application/json'
			}
		});

		total = await response.json();
	}
</script>

<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}

<button onclick={add}>Calculer</button>
<script lang="ts">
	let a = 0;
	let b = 0;
	let total = 0;

	async function add() {
		const response = await fetch('/api/add', {
			method: 'POST',
			body: JSON.stringify({ a, b }),
			headers: {
				'content-type': 'application/json'
			}
		});

		total = await response.json();
	}
</script>

<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}

<button onclick={add}>Calculer</button>
src/routes/api/add/+server
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
} from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */ export async function
function POST({ request }: {
    request: any;
}): Promise<Response>
@type{import('./$types').RequestHandler}
POST
({ request: anyrequest }) {
const { const a: anya, const b: anyb } = await request: anyrequest.json(); return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
}
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
} from '@sveltejs/kit';
import type {
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
} from './$types';
export const const POST: RequestHandlerPOST:
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
= async ({ request: Request

The original request object.

request
}) => {
const { const a: anya, const b: anyb } = await request: Request

The original request object.

request
.Body.json(): Promise<any>json();
return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
};

En général, les actions de formulaire sont une meilleure manière de soumettre des données du navigateur vers le serveur.

Si un gestionnaire GET est exporté, une requête HEAD renverra la donnée content-length du body de réponse du gestionnaire GET.

Gestionnaire de méthode de secours

Exporter le gestionnaire fallback va matcher toute requête correspondant à une méthode non gérée, y compris les méthodes comme MOVE qui n’ont pas d’export dédié prévu par +server.js.

src/routes/api/add/+server
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
, function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
} from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */ export async function
function POST({ request }: {
    request: any;
}): Promise<Response>
@type{import('./$types').RequestHandler}
POST
({ request: anyrequest }) {
const { const a: anya, const b: anyb } = await request: anyrequest.json(); return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
} // Ce gestionnaire va répondre à PUT, PATCH, DELETE, etc. /** @type {import('./$types').RequestHandler} */ export async function
function fallback({ request }: {
    request: any;
}): Promise<Response>
@type{import('./$types').RequestHandler}
fallback
({ request: anyrequest }) {
return function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
(`J'ai attrapé votre requête ${request: anyrequest.method} !`);
}
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
, function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
} from '@sveltejs/kit';
import type {
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
} from './$types';
export const const POST: RequestHandlerPOST:
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
= async ({ request: Request

The original request object.

request
}) => {
const { const a: anya, const b: anyb } = await request: Request

The original request object.

request
.Body.json(): Promise<any>json();
return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
}; // Ce gestionnaire va répondre à PUT, PATCH, DELETE, etc. export const const fallback: RequestHandlerfallback:
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
= async ({ request: Request

The original request object.

request
}) => {
return function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
(`J'ai attrapé votre requête ${request: Request

The original request object.

request
.Request.method: string

Returns request’s HTTP method, which is “GET” by default.

MDN Reference

method
} !`);
};

Pour les requêtes HEAD, le gestionnaire GET est prioritaire sur le gestionnaire fallback.

Négociation de contenu

Les fichiers +server.js peuvent être placés dans le même dossier que les fichiers +page, permettant à la même route d’être soit une page, soit un endpoint d’API. Pour les distinguer, SvelteKit applique les règles suivantes :

  • Les requêtes PUT / PATCH/DELETE/OPTIONS sont toujours gérées par +server.js puisque ces méthodes ne s’appliquent pas aux pages
  • Les requêtes GET / POST/HEAD sont traitées comme des requêtes de page si l’en-tête accept priorise text/html (en d’autres mots, si la requête vient d’une page ouverte par un navigateur), sinon elles seront traitées par +server.js.
  • Les réponses aux requêtes GET inclueront un en-tête Vary: Accept, de sorte que les proxies et les navigateurs puissent cacher les réponses HTML et JSON séparément.

$types

Dans les exemples ci-dessus, nous avons importé les types depuis un fichier $types.d.ts. Il s’agit d’un fichier que SvelteKit crée pour vous dans un dossier caché si vous utilisez TypeScript (ou JavaScript avec les annotations de type JSDoc) afin de vous fournir du typage lorsque vous travaillez sur vos fichiers de routes.

Par exemple, annoter let { data } = $props() avec PageProps (ou LayoutProps, pour un fichier +layout.svelte) indique à TypeScript que le type de data est défini par le type de retour de la fonction load correspondante :

src/routes/blog/[slug]/+page
<script>
	/** @type {import('./$types').PageProps} */
	let { data } = $props();
</script>
<script lang="ts">
	import type { PageProps } from './$types';

	let { data }: PageProps = $props();
</script>

Les types PageProps et LayoutProps, ajoutés dans la version 2.16.0, sont un raccourci de typer la prop data en tant que PageData ou LayoutData, ainsi que pour d’autres props, comme form pour les pages, ou children pour les layouts. Dans des versions antérieures, vous deviez typer ces propriétés manuellement. Par exemple, pour une page :

+page
/** @type {{ data: import('./$types').PageData, form: import('./$types').ActionData }} */
let { let data: anydata, let form: anyform } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

https://svelte.dev/docs/svelte/$props

$props
();
import type { import PageDataPageData, import ActionDataActionData } from './$types';

let { let data: PageDatadata, let form: ActionDataform }: { data: PageDatadata: import PageDataPageData, form: ActionDataform: import ActionDataActionData } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

https://svelte.dev/docs/svelte/$props

$props
();

Ou, pour un layout :

+layout
/** @type {{ data: import('./$types').LayoutData, children: Snippet }} */
let { let data: anydata, let children: anychildren } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

https://svelte.dev/docs/svelte/$props

$props
();
import type { import LayoutDataLayoutData } from './$types';

let { let data: LayoutDatadata, let children: Snippetchildren }: { data: LayoutDatadata: import LayoutDataLayoutData, children: Snippetchildren: type Snippet = /*unresolved*/ anySnippet } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

https://svelte.dev/docs/svelte/$props

$props
();

De plus, annoter la fonction load avec PageLoad, PageServerLoad, LayoutLoad, ou LayoutServerLoad (pour respectivement +page.js, +page.server.js, +layout.js ou +layout.server.js) permet de s’assurer que params et la valeur de retour sont correctement typées.

Si vous utilisez VS Code ou tout IDE supportant le protocole LSP (Language Server Protocol) et les plugins TypeScript, vous pouvez omettre ces types complètement ! L’outillage d’IDE de Svelte va insérer les types adéquats à votre place, afin de profiter du typage des données de page et de layout sans que ayez à l’écrire vous-même. Cela fonctionne également au sein de notre outil en ligne de commande svelte-check.

Vous pouvez en apprendre plus sur le fait d’omettre $types dans notre article de blog dédié.

Autres fichiers

Tout autre fichier dans un dossier de route est ignoré par SvelteKit. Ceci signifie que vous pouvez ranger des composants et autres modules utilitaires dans les dossiers des routes qui les nécessitent.

Si des composants ou modules sont requis par plusieurs routes, c’est une bonne idée de les mettre dans le dossier $lib.

En savoir plus

Modifier cette page sur Github