Cours Svelte et SvelteKit · Module 11: Routage SvelteKit
Layouts
Dans cette leçon4
+layout.svelte
<!-- src/routes/+layout.svelte -->
<script>
import Header from '#lib/components/Header.svelte';
import Footer from '#lib/components/Footer.svelte';
let { children } = $props();
</script>
<Header />
<main>
{@render children()} <!-- La page s'affiche ici -->
</main>
<Footer />
<style>
main {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
</style>Le layout reçoit le contenu de la page sous forme de snippet children et l'affiche avec la balise {@render children()}. En Svelte 4, c'était le rôle de l'élément <slot />, devenu obsolète en Svelte 5.
L'alias #lib est le successeur de $lib dans SvelteKit 3 : il pointe vers le dossier src/lib (une entrée imports dans package.json), et tu importes les modules JS avec leur extension, par exemple #lib/utils.js.
Layouts imbriqués
src/routes/
├── +layout.svelte # Layout principal
├── +page.svelte # Page d'accueil
└── dashboard/
├── +layout.svelte # Layout du dashboard (imbriqué)
├── +page.svelte # /dashboard
└── settings/
└── +page.svelte # /dashboard/settings<!-- src/routes/dashboard/+layout.svelte -->
<script>
import Sidebar from './Sidebar.svelte';
let { children } = $props();
</script>
<div class="dashboard-layout">
<Sidebar />
<div class="content">
{@render children()}
</div>
</div>Données de layout
// src/routes/+layout.js
export function load() {
return {
user: { name: 'Ragnar' }
};
}<!-- src/routes/+layout.svelte -->
<script>
let { data, children } = $props();
</script>
<nav>
Connecté en tant que : {data.user.name}
</nav>
{@render children()}Réinitialiser le layout
<!-- src/routes/fullscreen/+page@.svelte -->
<!-- @ réinitialise vers le layout racine -->
<h1>Page plein écran sans layout</h1>Code de cette leçon : App.svelte
<script>
// Layout et layouts imbriqués
let showSidebar = $state(true);
</script>
<div class="app-layout">
<!-- +layout.svelte (principal) -->
<header class="header">
<h1>Application Viking</h1>
<nav>
<a href="/">Accueil</a>
<a href="/warriors">Guerriers</a>
<a href="/ships">Navires</a>
</nav>
</header>
<div class="main-content">
{#if showSidebar}
<!-- barre latérale depuis (warriors)/+layout.svelte -->
<aside class="sidebar">
<h3>Filtre des guerriers</h3>
<ul>
<li><a href="/warriors?status=all">Tous</a></li>
<li><a href="/warriors?status=alive">Vivant</a></li>
<li><a href="/warriors?status=dead">Walhalla</a></li>
</ul>
</aside>
{/if}
<!-- +page.svelte -->
<main class="page">
<button onclick={() => showSidebar = !showSidebar}>
{showSidebar ? 'Masquer' : 'Afficher'} la barre latérale
</button>
<h2>Contenu de la page</h2>
<p>C’est ici que le layout affiche la page : <code>{'{@render children()}'}</code></p>
<div class="structure">
<pre>
src/routes/
├── +layout.svelte ← En-tête (partagé)
├── +page.svelte ← Accueil
└── warriors/
├── +layout.svelte ← Barre latérale (pour warriors)
└── +page.svelte ← Liste des guerriers
</pre>
</div>
</main>
</div>
<!-- Pied de page depuis le layout principal -->
<footer class="footer">
<p>© 2024 Application Viking - Propulsé par SvelteKit</p>
</footer>
</div>
<style>
.app-layout {
font-family: 'Georgia', serif;
min-height: 100vh;
display: flex;
flex-direction: column;
background: #0a1628;
color: #b8d4f7;
}
.header {
background: #1e3a5f;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.header h1 {
margin: 0;
color: #ffd700;
font-size: 1.5rem;
}
.header nav {
display: flex;
gap: 1rem;
}
.header a {
color: #b8d4f7;
text-decoration: none;
}
.main-content {
flex: 1;
display: flex;
}
.sidebar {
width: 200px;
background: rgba(74, 144, 217, 0.1);
padding: 1rem;
border-right: 1px solid #4a90d9;
}
.sidebar h3 {
color: #4a90d9;
font-size: 1rem;
margin-top: 0;
}
.sidebar ul {
list-style: none;
padding: 0;
}
.sidebar li {
margin: 0.5rem 0;
}
.sidebar a {
color: #b8d4f7;
text-decoration: none;
}
.page {
flex: 1;
padding: 2rem;
}
button {
padding: 0.5rem 1rem;
background: #1e3a5f;
color: #b8d4f7;
border: 1px solid #4a90d9;
border-radius: 4px;
cursor: pointer;
margin-bottom: 1rem;
}
h2 {
color: #4a90d9;
}
code {
background: rgba(0,0,0,0.5);
padding: 0.2rem 0.5rem;
border-radius: 4px;
}
.structure pre {
background: rgba(0,0,0,0.5);
padding: 1rem;
border-radius: 4px;
font-size: 0.85rem;
}
.footer {
background: #1e3a5f;
padding: 1rem;
text-align: center;
font-size: 0.9rem;
}
</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 affiches-tu le contenu de la page dans +layout.svelte (Svelte 5) ?