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 racinesrc/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.
<h1>Bonjour et bienvenue sur mon site !</h1>
<a href="/about">À propose de mon site</a>
<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
.
<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ésdata
manuellement avecPageData
, 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
:
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.
error } from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */
export function function load({ params }: {
params: any;
}): {
title: string;
content: string;
}
load({ params: any
params }) {
if (params: any
params.slug === 'hello-world') {
return {
title: string
title: 'Bonjour tout le monde !',
content: string
content: '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.
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.
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: PageLoad
load: 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: string
title: 'Bonjour tout le monde !',
content: string
content: '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.
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
oufalse
ou'auto'
export const ssr = true
oufalse
export const csr = true
oufalse
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
.
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.
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>>
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.
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.
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: PageServerLoad
load: 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.
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 page — prerender
,
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
:
<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 :
<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
...
<h1>Accueil</h1>
<h1>À propos</h1>
<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) :
<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
.
/** @type {import('./$types').LayoutLoad} */
export function function load(): {
sections: {
slug: string;
title: string;
}[];
}
load() {
return {
sections: {
slug: string;
title: string;
}[]
sections: [
{ slug: string
slug: 'profile', title: string
title: 'Profil' },
{ slug: string
slug: 'notifications', title: string
title: '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: LayoutLoad
load: 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: string
slug: 'profile', title: string
title: 'Profil' },
{ slug: string
slug: 'notifications', title: string
title: 'Notifications' }
]
};
};
Si un fichier +layout.js
exporte des options de pages — prerender
, 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 :
<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 page —
prerender
, 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
:
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.
error } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export function function GET({ url }: {
url: any;
}): Response
GET({ url: any
url }) {
const const min: number
min = 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: any
url.searchParams.get('min') ?? '0');
const const max: number
max = 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: any
url.searchParams.get('max') ?? '1');
const const d: number
d = const max: number
max - const min: number
min;
if (function isNaN(number: number): boolean
Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
isNaN(const d: number
d) || const d: number
d < 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.
error(400, 'min et max doivent être des nombres, et min doit être plus petit que max');
}
const const random: number
random = const min: number
min + 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: number
d;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response
This Fetch API interface represents the response to a request.
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: number
random));
}
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.
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: RequestHandler
GET: 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: number
min = 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: URLSearchParams
searchParams.URLSearchParams.get(name: string): string | null
Returns the first value associated to the given search parameter.
get('min') ?? '0');
const const max: number
max = 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: URLSearchParams
searchParams.URLSearchParams.get(name: string): string | null
Returns the first value associated to the given search parameter.
get('max') ?? '1');
const const d: number
d = const max: number
max - const min: number
min;
if (function isNaN(number: number): boolean
Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
isNaN(const d: number
d) || const d: number
d < 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.
error(400, 'min et max doivent être des nombres, et min doit être plus petit que max');
}
const const random: number
random = const min: number
min + 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: number
d;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response
This Fetch API interface represents the response to a request.
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: number
random));
};
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êtesAcces-Control-Allow-Origin
etAccess-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 serveurhandle
.
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 :
<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>
import { function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function function POST({ request }: {
request: any;
}): Promise<Response>
POST({ request: any
request }) {
const { const a: any
a, const b: any
b } = await request: any
request.json();
return function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
json(const a: any
a + const b: any
b);
}
import { function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
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: RequestHandler
POST: 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: any
a, const b: any
b } = 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.
json(const a: any
a + const b: any
b);
};
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êteHEAD
renverra la donnéecontent-length
du body de réponse du gestionnaireGET
.
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
.
import { function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
json, function text(body: string, init?: ResponseInit | undefined): Response
Create a Response
object from the supplied body.
text } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function function POST({ request }: {
request: any;
}): Promise<Response>
POST({ request: any
request }) {
const { const a: any
a, const b: any
b } = await request: any
request.json();
return function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
json(const a: any
a + const b: any
b);
}
// Ce gestionnaire va répondre à PUT, PATCH, DELETE, etc.
/** @type {import('./$types').RequestHandler} */
export async function function fallback({ request }: {
request: any;
}): Promise<Response>
fallback({ request: any
request }) {
return function text(body: string, init?: ResponseInit | undefined): Response
Create a Response
object from the supplied body.
text(`J'ai attrapé votre requête ${request: any
request.method} !`);
}
import { function json(data: any, init?: ResponseInit | undefined): Response
Create a JSON Response
object from the supplied data.
json, function text(body: string, init?: ResponseInit | undefined): Response
Create a Response
object from the supplied body.
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: RequestHandler
POST: 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: any
a, const b: any
b } = 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.
json(const a: any
a + const b: any
b);
};
// Ce gestionnaire va répondre à PUT, PATCH, DELETE, etc.
export const const fallback: RequestHandler
fallback: 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.
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.
method} !`);
};
Pour les requêtes
HEAD
, le gestionnaireGET
est prioritaire sur le gestionnairefallback
.
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êteaccept
priorisetext/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êteVary: 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 :
<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
etLayoutProps
, ajoutés dans la version 2.16.0, sont un raccourci de typer la propdata
en tant quePageData
ouLayoutData
, ainsi que pour d’autres props, commeform
pour les pages, ouchildren
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: any
data,let form: any
form } =
function $props(): any namespace $props
$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
import type {
import PageData
PageData,import ActionData
ActionData } from './$types'; let {let data: PageData
data,let form: ActionData
form }: {data: PageData
data:import PageData
PageData,form: ActionData
form:import ActionData
ActionData } =
function $props(): any namespace $props
$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
Ou, pour un layout :
+layout/** @type {{ data: import('./$types').LayoutData, children: Snippet }} */ let {
let data: any
data,let children: any
children } =
function $props(): any namespace $props
$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
import type {
import LayoutData
LayoutData } from './$types'; let {let data: LayoutData
data,let children: Snippet
children }: {data: LayoutData
data:import LayoutData
LayoutData,children: Snippet
children:type Snippet = /*unresolved*/ any
Snippet } =
function $props(): any namespace $props
$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $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