Back to sh0
sh0

Construire un tableau de bord de production avec Svelte 5 en 48 heures

Comment nous avons construit le tableau de bord de production de sh0 -- thèmes sombre/clair, i18n en 5 langues, logs WebSocket en temps réel, et 7 pages principales -- avec Svelte 5 runes et TailwindCSS 4 en 48 heures.

Juste A. Gnimavo (Thales) & Claude | March 26, 2026 4 min sh0
EN/ FR/ ES
sveltesvelte-5dashboardtailwindcsstypescriptuifrontend

Chaque PaaS a un tableau de bord. La plupart ressemblent à des interfaces construites en 2018 et jamais mises à jour. Nous voulions que le nôtre donne l'impression d'un produit qu'on prendrait plaisir à utiliser -- mode sombre, cinq langues, logs en temps réel, responsive jusqu'au mobile -- et nous voulions qu'il soit compilé dans le binaire Rust pour que sh0 soit livré comme un seul exécutable avec zéro dépendance externe.

Le 12 mars 2026, nous sommes passés d'un dossier dashboard/ vide à une SPA SvelteKit entièrement fonctionnelle avec 7 pages, 8 composants UI partagés, un système i18n couvrant cinq langues, et un client API typé gérant l'authentification, les états d'erreur et la reconnexion WebSocket. Puis nous avons embarqué le tout dans notre binaire Rust avec include_dir. Quarante-huit heures plus tard, chaque page avait de vraies données.

Pourquoi Svelte 5 et pas React

La décision a pris environ trente secondes. Les Runes ($state, $derived, $effect, $props) ont éliminé la cérémonie de stores que React exige. Pas de danse useState / useEffect / useCallback / useMemo. Pas de bugs de tableau de dépendances. Déclarez votre état et utilisez-le.

SvelteKit 2 avec adapter-static nous a donné le routage basé sur les fichiers et une étape de build qui produit du HTML, CSS et JavaScript brut -- exactement ce dont nous avions besoin pour embarquer dans un binaire Rust.

L'échafaudage de la Phase 12

L'échafaudage a livré huit éléments en une seule session : TailwindCSS 4 avec thème personnalisé, le système i18n en 5 langues, le store d'auth et le flux de connexion, le client API, le client WebSocket avec reconnexion automatique, huit composants UI partagés, la mise en page sidebar responsive, et sept pages placeholder.

La Phase 13 : les pages principales prennent vie

Le tableau de bord d'accueil montre quatre cartes de statistiques et une liste de déploiements récents. La liste d'applications est un grille de cartes avec recherche, filtrage et un modal « Créer une application ». La page de détail d'application est la plus complexe : une seule route avec six onglets (Vue d'ensemble, Déploiements, Logs, Domaines, Environnement, Paramètres).

Le LogViewer mérite une mention spéciale. Il ouvre une connexion WebSocket, affiche les lignes entrantes dans un conteneur monospace avec défilement automatique, et maintient un buffer de 1 000 lignes pour empêcher la croissance mémoire.

La Phase 14 : pages étendues

La poussée finale a remplacé les quatre pages placeholder restantes par des implémentations de production : Bases de données, Sauvegardes, Monitoring et Paramètres (avec configuration TOTP et gestion des clés API).

Embarquer le tableau de bord dans un binaire Rust

La crate include_dir a permis d'embarquer le répertoire dashboard/build entier dans le binaire compilé au moment du build. Le handler static_files.rs sert les fichiers depuis le répertoire embarqué, avec un repli SPA vers index.html.

Le résultat : sh0 est un binaire unique. Téléchargez-le, lancez-le, ouvrez un navigateur. Le tableau de bord est déjà là. Pas de npm install. Pas de serveur frontend séparé.

Ce que nous avons appris

Les runes Svelte 5 sont un vrai bond en avant. Le modèle $state / $derived / $effect correspond directement à la façon dont on pense l'interface. TailwindCSS 4 avec propriétés CSS personnalisées est la bonne approche de thème. L'i18n dès le premier jour ne coûte presque rien. Embarquer une SPA dans un binaire Rust se fait étonnamment bien.

En 48 heures, nous sommes passés d'un répertoire vide à un tableau de bord avec 11 pages fonctionnelles, 19 composants personnalisés, 5 langues, thèmes sombre/clair, streaming de logs en temps réel, et variables d'environnement chiffrées -- le tout compilé dans un seul binaire Rust.


Prochain dans la série : Des listes plates aux Stacks : repenser toute notre UX.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude deblo

Le jour où Déblo a refusé une bonne réponse — deux fois

Une trace de production a montré Déblo K12 rejetant deux fois de suite la bonne réponse d’un élève de Terminale. Huit heures d’analyse, quatre commits, une rotation A/B de modèles et un benchmark sur 6 modèles plus tard, le tuteur de maths était corrigé. Ce qui a cassé, ce que nous avons changé, et ce que l’échec surprenant de GPT-5.4-mini au test socratique nous a appris sur le choix des modèles pour l’IA éducative.

32 min May 3, 2026
debloclaude-opus-4.7claude-codemethodology +14
Thales & Claude deblo

Web Claude a trouvé le bug. Puis il a failli l’aggraver.

Comment un prompt vocal de 270 lignes pour le tuteur Ultravox de Deblo produisait la même phrase d’accueil scriptu00e9e à chaque appel. Web Claude a diagnostiqué le problème parfaitement, puis a prescrit une correction qui aurait doublé la taille du prompt avec des hooks backend inexistants. Le filtre qui a gardé le diagnostic et rejeté la prescription.

17 min Apr 28, 2026
debloclaude-opus-4.7methodologyprompt-engineering +7
Thales & Claude deblo

Pourquoi j’ai dû corriger Web Claude deux fois sur la stratégie de la page d’accueil de Deblo

Comment une conversation de 48 heures avec Web Claude a failli entraîner Deblo dans le piège généraliste « ChatGPT pour l’Afrique », et pourquoi la connaissance du marché par le fondateur a dû prendre le dessus sur les suggestions stratégiques de l’IA à deux reprises.

26 min Apr 26, 2026
debloclaude-opus-4.7methodologystrategy +6