Introduction au Routage Complexe
Le système de routage de SvelteKit est conçu autour de la structure du système de fichiers, offrant une flexibilité puissante au-delà des simples chemins statiques. Cette section explore les mécanismes permettant de manipuler des structures de URL dynamiques, de gérer les erreurs de manière granulaire et d'organiser l'héritage des mises en page.
Paramètres de Reste (Rest Parameters)
Lorsque le nombre de segments de chemin n'est pas connu à l'avance, vous pouvez utiliser la syntaxe de paramètre restant. Cela est particulièrement utile pour construire des navigateurs de fcihiers ou des visualiseurs de contenu hiérarchique.
/projet/[version]/doc/[...chemin_fichier]
Dans ce scénario, une requête vers /mon-projet/v1/guide/introduction.md sera résolue avec les paramètres suivants accessibles dans la logique de chargement :
// @noErrors
{
version: 'v1',
chemin_fichier: 'guide/introduction.md'
}
Note importante : Un dossier tel que src/routes/api/[...rest]/health/+page.svelte correspondra également à /api/health, car le paramètre restant peut être vide. Il est recommandé de valider la présence des données attendues lors de l'exécution.
Gestion des Erreurs 404 Personnalisées
Les paramètres restants permettent également de définir des pages d'erreur contextualisées. Considérons la structure suivante :
src/routes/
├ équipes/
│ ├ alpha/
│ ├ beta/
│ └ +error.svelte
└ +error.svelte
Si l'utilisateur accède à /équipes/gamma, le fichier +error.svelte racine sera activé, ignorant le contexte équipes. Pour afficher une erreur spécifique au périmètre des équipes, créez une route capture-tout imbriquée :
src/routes/
├ équipes/
│ ├ [...segment_inconnu]/
│ │ └ +page.server.js
│ ├ alpha/
│ └ +error.svelte
└ +error.svelte
Dans le module de chargement associé à cette nouvelle route :
/// file: src/routes/equipes/[...segment_inconnu]/+page.server.js
import { fail } from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */
export async function load() {
throw fail(404, { message: 'Cette équipe n\'existe pas.' });
}
Paramètres Optionnels
Par défaut, un paramètre comme [langue]/accueil exige une valeur. Si vous souhaitez rendre l'accès sans langue (par exemple /accueil) valide et identique à /fr/accueil, doublez les crochets :
/[[langue]]/accueil
Attention : Un paramètre optionnel ne peut pas suivre un paramètre restant ([...rest]/[[optionnel]]). En effet, le paramètre restant est "gourmand" et consommera tout le chemin disponible, rendant le paramètre suivant inaccessible.
Filtres de Paramètres (Matchers)
Une route simple comme produits/[categorie] acceptera n'improte quel texte, y compris des valeurs invalides. Pour contraindre les entrées, utilisez un matcheur défini dans le dossier src/params.
Créons un validateur pour ne accepter que certaines catégories spécifiques :
/// file: src/params/categorie_valide.js
/**
* @param {string} param
* @return {param is ('electronique' | 'meuble')}
*/
export function match(param) {
return ['electronique', 'meuble'].includes(param);
}
Rendez ensuite votre route sensible à ce filtre :
/produits/[categorie=categorie_valide]
Si la portion de l'URL ne respecte pas la règle, SvelteKit continuera sa recherche de route correspondante. Les matcheurs s'exécutent à la fois côté serveur et client.
Priorité et Tri des Routes
Plusieurs configurations peuvent théoriquement correspondre à une même URL. Le moteur de routage détermine celle à utiliser selon ces règles de priorité (de la plus haute à la plus basse) :
- Les routes statiques précises surpassent les routes dynamiques.
- Les paramètres munis de matcheurs (
[name=filtre]) priment sur les paramètres génériques ([name]). - Les paramètres restants et optionnels sont considérés comme les moins prioritaires, sauf s'ils se trouvent en fin de chemin.
- En cas d'égalité, l'ordre alphabétique du nom de dossier tranche.
Cela garantit qu'une URL comme /jeux/abc atteindra un dossier /jeux/abc/ plutôt que /jeux/[id]/.
Encodage des Caractères Réservés
Le système de fichiers impose des limitations aux noms de dossiers. Les symboles tels que /, #, % ou ( ) ont des significations spéciales et ne peuvent être utilisés directement dans les noms de dossiers de routes.
Pour contourner cela, utilisez la notation hexadécimale sous la forme [x+CODE]. Par exemple, pour créer une route contenant un point d'interrogation :
- Caractère
?devient[x+3f]. - Caractère
:devient[x+3a].
Ainsi, pour une route /emojis/sourire:-), le chemin physique serait src/routes/emojis/sourire-[x+3a]-[x+29]/+page.svelte. Vous pouvez vérifier le code hexadécimal en JavaScript via 'char'.charCodeAt(0).toString(16). Les séquences Unicode [u+NNNN] sont également supportées pour les emojis ou caractères spéciaux.
Organisation Avancée des Mise en Page
La hiérarchie des mises en page reflète généralement celle du système de fichiers, mais ce n'est pas toujours idéal. SvelteKit propose des outils pour découpler ces deux structures.
Regroupement par Groupes (Groups)
Pour organiser visuellement vos fichiers sans affecter les URLs, utilisez des répertoires entourés de parenthèses, comme (application) ou (marketing). Ces dossiers servent uniquement à héberger des mises en page spécifiques.
src/routes/
├ (application)/
│ ├ tableau-de-bord/
│ │ └ +layout.svelte
│ └ profil/
└ (marketing)/
├ propos/
└ +layout.svelte
Une URL comme /tableau-de-bord utilisera la mise en page de (application), tandis que /propos utilisera celle de (marketing).
Contorunement de Mise en Page (@)
Il est parfois nécessaire qu'une page ignore une partie de l'arbre des mises en page parentales. Vous pouvez utiliser le symbole @ suivi du nom du segment pour cibler une mise en page précise.
Considérons une page d'intégration (/profil/integration) qui doit ignorer la mise en page du tableau de bord :
+page[@].svelteignore toutes les mises en page parentes et utilise la racine.+page[(application)].svelteremonte jusqu'à la mise en page définie dans le groupe application.
Même une mise en page peut utiliser cette syntaxe (+layout@(application).svelte) pour déterminer quelle mise en page parente elle doit englober, offrant une flexibilité totale dans la composition visuelle de l'application.
Alternative aux Groupes
Toutes les architectures n'exigent pas des groupes de dossiers. Parfois, réutiliser un composant de layout existant ou injecter dynamiquement une fonction de chargement commune est une approche plus simple qu'une complexification de l'arborescence des fichiers.