Ce que vous saurez faire
- Comprendre l’approche Svelte (compilateur vs runtime)
- SvelteKit avec routing + SSR
- Runes (Svelte 5) et stores
- Déployer en production
Étape 1 — Pourquoi Svelte
Svelte compile les composants en JS vanilla optimisé. Pas de Virtual DOM, pas de hooks, bundle runtime minimal. Le framework disparaît au build.
Étape 2 — Créer un projet SvelteKit
npm create svelte@latest mon-app
# Skeleton + TypeScript + ESLint + Prettier + Vitest
cd mon-app
npm install
npm run dev
Étape 3 — Premier composant
<script lang="ts">
let nom = $state("Aminata");
let clics = $state(0);
let salutation = $derived(`Bonjour ${nom.trim()}`);
function incrementer() { clics++; }
</script>
<input bind:value={nom} />
<p>{salutation}</p>
<button onclick={incrementer}>Clics: {clics}</button>
<style>
button { background: #ff3e00; color: white; padding: .5rem 1rem; }
</style>
Étape 4 — Runes (Svelte 5)
<script lang="ts">
let clients = $state<{id:number; nom:string}[]>([]);
let recherche = $state("");
let filtres = $derived(clients.filter(c => c.nom.includes(recherche)));
$effect(() => {
fetch("/api/clients").then(r => r.json()).then(d => clients = d);
});
</script>
<input bind:value={recherche} placeholder="Filtrer..." />
{#each filtres as c (c.id)}
<div>{c.nom}</div>
{/each}
Étape 5 — Props et events
<!-- Carte.svelte -->
<script lang="ts">
let { titre, onselect }: { titre: string; onselect: (t: string) => void } = $props();
</script>
<article onclick={() => onselect(titre)}>
<h3>{titre}</h3>
</article>
Étape 6 — Routing SvelteKit
src/routes/
+layout.svelte layout global
+page.svelte /
clients/
+page.svelte /clients
+page.server.ts loader serveur
[id]/+page.svelte /clients/42
Étape 7 — Loader serveur
// src/routes/clients/+page.server.ts
import type { PageServerLoad } from "./$types";
import { db } from "$lib/db";
export const load: PageServerLoad = async () => {
const clients = await db.query("SELECT id, nom, ville FROM clients");
return { clients: clients.rows };
};
<!-- +page.svelte -->
<script lang="ts">
let { data } = $props();
</script>
<h1>Clients</h1>
<ul>
{#each data.clients as c}<li>{c.nom}</li>{/each}
</ul>
Étape 8 — Form actions
// +page.server.ts
import { fail, redirect } from "@sveltejs/kit";
export const actions = {
creer: async ({ request }) => {
const data = await request.formData();
const nom = data.get("nom")?.toString();
if (!nom) return fail(400, { manque: true });
const r = await db.query("INSERT INTO clients(nom) VALUES($1) RETURNING id", [nom]);
throw redirect(303, `/clients/${r.rows[0].id}`);
},
};
<form method="POST" action="?/creer">
<input name="nom" required />
<button>Créer</button>
</form>
Étape 9 — Stores custom
// $lib/panier.svelte.ts
class Panier {
items = $state<{id:string;qty:number;prix:number}[]>([]);
total = $derived(this.items.reduce((s, i) => s + i.qty * i.prix, 0));
ajouter(id: string, prix: number) {
const e = this.items.find(i => i.id === id);
if (e) e.qty++;
else this.items.push({id, prix, qty: 1});
}
}
export const panier = new Panier();
Étape 10 — Animations
<script>
import { fly, fade } from "svelte/transition";
import { flip } from "svelte/animate";
let liste = $state(["A","B","C"]);
</script>
{#each liste as item (item)}
<div in:fly={{y:20,duration:300}} out:fade animate:flip>{item}</div>
{/each}
Étape 11 — Build et déploiement
npm run build
npm run preview
# Adapters: vercel, cloudflare, node, static...
npm install -D @sveltejs/adapter-vercel
# svelte.config.js: import adapter from '@sveltejs/adapter-vercel';
# Déploiement
npx vercel --prod
Étape 12 — Tests Vitest
import { render, screen } from "@testing-library/svelte";
import { test, expect } from "vitest";
import Carte from "./Carte.svelte";
test("rend le titre", () => {
render(Carte, { titre: "Formation" });
expect(screen.getByText("Formation")).toBeInTheDocument();
});
Checklist
✓ Svelte 5 runes ($state, $derived, $effect, $props)
✓ Séparation +page.svelte (UI) / +page.server.ts (data)
✓ Form actions pour submits sans fetch côté client
✓ Stores classes pour état partagé complexe
✓ Transitions intégrées (fly, fade, flip)
✓ Tests Vitest + Testing Library
✓ Adapter selon cible (Vercel, CF, Node)