Cours Svelte et SvelteKit · Module 11: Routage SvelteKit
Routes dynamiques et paramètres
Dans cette leçon4
Segments dynamiques [param]
src/routes/warriors/[id]/+page.svelte<!-- src/routes/warriors/[id]/+page.svelte -->
<script>
let { data } = $props();
</script>
<h1>Guerrier : {data.warrior.name}</h1>
<p>Force : {data.warrior.strength}</p>Ce que renvoie la fonction load arrive dans la page sous forme de prop data. Tu la récupères avec $props(), comme n'importe quelle prop en Svelte 5.
// src/routes/warriors/[id]/+page.js
export function load({ params }) {
const warriors = [
{ id: '1', name: 'Ragnar', strength: 95 },
{ id: '2', name: 'Bjorn', strength: 88 }
];
const warrior = warriors.find(w => w.id === params.id);
return { warrior };
}Paramètres rest [...slug]
src/routes/docs/[...path]/+page.svelteCorrespond à : /docs/a, /docs/a/b, /docs/a/b/c
// +page.js
export function load({ params }) {
// params.path = 'a/b/c'
const segments = params.path.split('/');
return { segments };
}Paramètres optionnels [[param]]
src/routes/warriors/[[page]]/+page.svelteCorrespond à : /warriors, /warriors/2
Regroupement de routes (groupes)
src/routes/
├── (public)/
│ ├── about/+page.svelte # /about
│ └── contact/+page.svelte # /contact
├── (auth)/
│ ├── login/+page.svelte # /login
│ └── register/+page.svelte # /register
└── (app)/
└── dashboard/+page.svelte # /dashboardLes groupes (entre parenthèses) n'affectent pas l'URL !
Code de cette leçon : App.svelte
<script>
// Paramètres dynamiques et chaînes de requête
let warriorId = $state('ragnar');
let sortBy = $state('name');
let filter = $state('all');
// Simulation de données
const warriors = {
ragnar: { name: 'Ragnar Lothbrok', strength: 95, clan: 'Lothbrok' },
bjorn: { name: 'Bjorn Ironside', strength: 90, clan: 'Lothbrok' },
ivar: { name: 'Ivar the Boneless', strength: 85, clan: 'Lothbrok' }
};
let currentWarrior = $derived(warriors[warriorId]);
let queryString = $derived(`?sort=${sortBy}&filter=${filter}`);
</script>
<main class="params-demo">
<h1>Paramètres URL</h1>
<section>
<h2>Paramètre dynamique [id]</h2>
<p class="path">/warriors/<strong>[id]</strong></p>
<div class="options">
{#each Object.keys(warriors) as id}
<button
class:active={warriorId === id}
onclick={() => warriorId = id}
>
{id}
</button>
{/each}
</div>
{#if currentWarrior}
<div class="warrior-info">
<h3>{currentWarrior.name}</h3>
<p>Force : {currentWarrior.strength}</p>
<p>Clan : {currentWarrior.clan}</p>
</div>
{/if}
<pre>
// +page.server.js
export function load({"{"} params {"}"}) {"{"}
const warrior = getWarrior(params.id);
return {"{"} warrior {"}"};
{"}"}
</pre>
</section>
<section>
<h2>Chaînes de requête</h2>
<p class="path">/warriors<strong>{queryString}</strong></p>
<div class="controls">
<label>
Trier par :
<select bind:value={sortBy}>
<option value="name">Nom</option>
<option value="strength">Force</option>
</select>
</label>
<label>
Filtrer :
<select bind:value={filter}>
<option value="all">Tous</option>
<option value="alive">Vivant</option>
<option value="dead">Mort</option>
</select>
</label>
</div>
<pre>
// +page.server.js
export function load({"{"} url {"}"}) {"{"}
const sort = url.searchParams.get('sort');
const filter = url.searchParams.get('filter');
return {"{"} sort, filter {"}"};
{"}"}
</pre>
</section>
</main>
<style>
.params-demo {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: #0a1628;
color: #b8d4f7;
min-height: 100vh;
}
h1 {
color: #4a90d9;
text-align: center;
}
section {
background: rgba(74, 144, 217, 0.1);
border: 1px solid #4a90d9;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #4a90d9;
font-size: 1rem;
margin-top: 0;
}
.path {
font-family: monospace;
background: rgba(0,0,0,0.5);
padding: 0.5rem 1rem;
border-radius: 4px;
}
.path strong {
color: #ffd700;
}
.options {
display: flex;
gap: 0.5rem;
margin: 1rem 0;
}
button {
padding: 0.5rem 1rem;
background: #1e3a5f;
color: #b8d4f7;
border: 1px solid #4a90d9;
border-radius: 4px;
cursor: pointer;
}
button.active {
background: #4a90d9;
color: #0a1628;
}
.warrior-info {
background: rgba(0,0,0,0.3);
padding: 1rem;
border-radius: 4px;
margin: 1rem 0;
}
.warrior-info h3 {
color: #ffd700;
margin: 0 0 0.5rem 0;
}
.controls {
display: flex;
gap: 1rem;
margin: 1rem 0;
}
label {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
select {
padding: 0.5rem;
background: #1e3a5f;
color: #b8d4f7;
border: 1px solid #4a90d9;
border-radius: 4px;
}
pre {
background: rgba(0,0,0,0.5);
padding: 1rem;
border-radius: 4px;
font-size: 0.8rem;
overflow-x: auto;
}
</style>Entrées de la documentation utilisées dans cette leçon
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Comment créer une route dynamique pour /warriors/123 ?