ITSkillsCenter
Développement Web

Svelte : framework front radicalement différent

4 min de lecture
Svelte : framework front radicalement différent

Ce que vous saurez faire

  1. Comprendre l’approche Svelte (compilateur vs runtime)
  2. SvelteKit avec routing + SSR
  3. Runes (Svelte 5) et stores
  4. 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)
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité