Voici la version longue de la refonte de dsti.school — et la raison pour laquelle une petite école d’ingénieurs sélective établie sur la Côte d’Azur a fini par écrire sa propre chaîne de build de site statique, son propre validateur schema.org et son propre moteur de géolocalisation à la périphérie du réseau. La version courte tient en une phrase : l’essentiel de ce qui ressemble à du marketing relève en réalité de l’ingénierie, et l’essentiel de cette ingénierie ne prend tout son sens qu’une fois que l’on sait à quoi elle sert. Cet article présente donc les deux : les systèmes, dans leur intégralité, et les raisons qui les sous-tendent.
Deux efforts progressent en parallèle tout au long de cette histoire. Le premier correspond à dix-huit mois de développement d’un réseau mondial de partenaires, sur le terrain, institution après institution. Le second tient en trois semaines de reconstruction complète du site web. Ils semblent sans rapport. Ils relèvent pourtant du même projet : un effort continu pour gagner la confiance d’une famille envers une école dont elle n’a souvent jamais entendu parler, dans un pays qui lui vient rarement spontanément à l’esprit. Le site web poursuit cet effort pendant que tout le monde dort ; il se doit donc d’être à la hauteur.
01Pourquoi il existe : un réseau, pas un marché national
Avant la moindre ligne de code : le site web a été reconstruit en raison de l’origine réelle de nos étudiants. Au cours des dix-huit derniers mois, le réseau de partenaires conseillers en études à l’étranger de DSTI est passé de quelques dizaines de relations à 92 partenaires agréés dans 78 pays et territoires. Cette croissance s’est faite en personne — salons, visites de campus, longues conversations — et elle a transformé le rôle que doit jouer le site. Ce n’est plus une brochure destinée à des personnes qui nous connaissent déjà. Il devient de plus en plus souvent la première rencontre sérieuse d’un futur étudiant à Lagos, La Paz, Hanoï ou Bogotá avec l’école, sur un téléphone, avec une connexion instable, dans une langue qui n’est peut-être pas la sienne.
Ce seul constat détermine presque toutes les contraintes techniques qui suivent : le site doit être rapide sur mobile, lisible par les machines autant que par les personnes, disponible en plusieurs langues, chacune traitée comme une langue de premier rang, et impossible à publier s’il est défectueux, car il est rare que quelqu’un soit éveillé pour s’en apercevoir. Aucun de ces choix n’est esthétique. Ils découlent de la personne qui se trouve à l’autre bout.
02Le pari : le savoir-faire pour rivaliser à armes égales
Nous sommes une petite structure. Nous n’avons ni un nom célèbre ni un budget immense, et nous n’allons acquérir ni l’un ni l’autre ce trimestre. Ce qu’une petite équipe peut maîtriser, c’est la qualité de ce qu’elle met réellement en ligne. Le pari de cette refonte était donc volontairement classique : résoudre le problème par une meilleure ingénierie. Rendre le site plus rapide, plus propre, plus fiable et plus lisible par les machines que ceux d’écoles cent fois plus grandes, car cette compétition se gagne par le soin et la discipline, non par le niveau de dépense.
C’est aussi pourquoi la refonte a créé une dynamique cumulative plutôt qu’un simple changement de design. Chaque propriété de qualité recherchée — vitesse, validité, lisibilité machine — a été transformée en quelque chose que le build peut vérifier à chaque version, afin que l’exigence soit maintenue sans dépendre de la mémoire de chacun.
03La vitesse, parce que les millisecondes comptent dans le recrutement
Un futur étudiant confronté à une connexion irrégulière en altitude n’attend pas qu’une page lente se charge : il part. Nous avons donc mesuré nos performances sur mobile, là où cela compte réellement, par rapport aux écoles d’ingénieurs les plus célèbres au monde — non pour prétendre mieux enseigner, mais pour situer un ordre de grandeur technique.
Une capture rapide peut relever de la chance ; un site durablement rapide relève de l’ingénierie. Les trois mesures réellement utilisées par les Core Web Vitals de Google — la vitesse d’apparition du contenu principal, la rapidité de réaction de la page à une interaction et l’ampleur de ses déplacements visuels pendant le chargement — se situent toutes dans la zone « bonne », et le build maintient ce niveau à chaque version. Du HTML prégénéré dans S3 derrière un CDN signifie qu’aucun rendu n’est effectué à chaque requête ; s’y ajoutent des images AVIF, des indications de préchargement ciblées, un chemin critique volontairement léger et une optimisation qui mérite d’être détaillée parce qu’elle paraît anodine alors qu’elle ne l’est pas.
La suite de V308 : supprimer le travail évitable avant de modifier l’architecture
La première version suivant la refonte présentait encore un avertissement intermittent de Lighthouse dans notre propre runtime : un gestionnaire de défilement pouvait mettre à jour la barre de progression de lecture puis demander au navigateur une nouvelle géométrie des sections au cours du même cycle. V308 a réorganisé ce chemin autour d’un unique requestAnimationFrame : la hauteur de l’en-tête sticky et les positions des sections sont mises en cache, la géométrie n’est lue qu’une fois, puis les classes de progression ou d’état actif sont écrites. La même version a déplacé les feuilles de style référencées avant les blocs JSON-LD volumineux dans les pages maintenues, les pages générées et les chaînes de build des supports, tout en préservant l’ordre des feuilles de style. C’était délibérément l’option prudente : aucune séparation du CSS critique, aucune astuce de chargement asynchrone des feuilles de style et aucune nouvelle cascade à démontrer.
Le premier test mobile en laboratoire après déploiement a reflété ce changement sans prétendre qu’une seule exécution constitue une donnée de terrain : First Contentful Paint est resté à 0,9 s ; Largest Contentful Paint est passé de 2,9 s à 2,7 s ; Total Blocking Time a chuté de 190 ms à 30 ms ; Speed Index est passé de 1,1 s à 0,9 s ; et Cumulative Layout Shift est resté à 0. Le chemin critique maximal mesuré a été réduit de 159 ms à 98 ms. Lighthouse signale encore, à juste titre, une ressource bloquant le rendu — la feuille de style élaguée de 19,5 KiB de la page — car nous avons privilégié un premier rendu prévisible plutôt que la suppression d’un avertissement à tout prix.
Une feuille de style par page — et pourquoi c’est difficile
La méthode habituelle consiste à construire un site avec une grande feuille de style partagée, ce qui oblige chaque page à télécharger, analyser et appliquer des milliers de règles qu’elle n’utilisera jamais. Nous faisons l’inverse : chaque page livre une feuille de style réduite aux règles dont elle a réellement besoin. Moins de données à transmettre, moins de travail à effectuer par le navigateur avant l’affichage. Le problème est qu’il est impossible d’élaguer uniquement à partir de ce qui figure dans le HTML de la page.
La version naïve — « supprimer toute règle dont le sélecteur n’apparaît jamais dans cette page » — casse discrètement le site, car les classes les plus importantes ne figurent pas du tout dans le HTML enregistré. JavaScript les ajoute à l’exécution : un menu devient open lorsqu’on le touche, un en-tête devient sticky et scrolled pendant le défilement, une boîte de dialogue devient active, la bannière de cookies bascule sur consent, un élément devient selected ou loading. Supprimer ces règles « inutilisées » ferait perdre son style à chaque interaction. L’optimiseur conserve donc une liste d’autorisation volontairement prudente de ces marqueurs d’état dynamique et ne les supprime jamais. Trois autres éléments compliquent encore l’exercice : les sélecteurs ne se lisent pas de gauche à droite (:is(), :where() et :has() imbriquent d’autres sélecteurs, ce qui exige une correspondance récursive) ; les règles précédées de @ se divisent en deux catégories (@media/@container encapsulent des règles qu’il faut parcourir, tandis que @font-face/@keyframes sont référencées par leur nom et conservées comme des blocs opaques) ; enfin, certains CSS modernes réellement utilisés — les requêtes de conteneur avec container-type et les unités cqi — sont suffisamment récents pour que le validateur HTML/CSS les signale encore comme utilisant une propriété « inexistante ». Le pipeline les conserve donc comme faux positifs connus et examinés. La suppression de CSS étant risquée, chaque page élaguée est ensuite comparée à l’original par un vérificateur distinct avant toute publication.
04Portée : trois langues à part entière
Le site est né bilingue — anglais et français. L’espagnol (es-MX) est l’ajout le plus récent, et il est utile d’en expliquer la logique puisqu’il s’agit d’une décision d’entreprise, non d’un simple exercice de traduction. L’espagnol est la seule langue qui donne accès à tout un continent : une seule version linguistique ouvre d’un coup l’Amérique latine, à l’exception du Brésil, tandis que chacune des nombreuses langues d’Asie n’en ouvrirait qu’une partie. L’espagnol a donc toute sa place non parce qu’il serait abstraitement la « deuxième langue des affaires », mais en raison de la portée exceptionnelle qu’offre une seule version linguistique.
hreflang réciproques afin que les moteurs de recherche servent la bonne version ; les URLs ne sont jamais traduites automatiquement. Le chapitre suivant revient sur les jumeaux lisibles par machine.Surtout, les langues ne sont pas organisées comme un site principal auquel on aurait greffé des traductions. Chacune est une destination à part entière produite à partir d’une source unique, avec une réciprocité hreflang correcte, un x-default et une liste stricte des éléments à ne pas traduire : noms de programmes, marques, noms des certificateurs et des campus, ainsi que noms des modes d’études — tout ce qui doit rester identique dans chaque langue pour rester facile à trouver et correct.
La gouvernance de la traduction est devenue une mémoire du build
La traduction française du long récit Team DSTI a mis en évidence une distinction importante : un bon référentiel de traduction a besoin à la fois de règles normatives et des éléments qui ont conduit à les établir. À partir de V308, la passation comportait donc une autorité de traduction maintenue, ainsi que des fichiers de provenance distincts pour le français et l’espagnol mexicain. L’autorité précise ce qui doit être préservé — identifiants, URLs, noms officiels des programmes et des modes d’études, attribution de la première personne, balisage et sens lisible par machine. Les fichiers de provenance consignent la manière dont s’exprime naturellement un contenu destiné au public dans chaque langue : français international neutre avec vous ; espagnol mexicain professionnel avec tú ; conventions numériques distinctes ; terminologie récurrente ; contrôles des faux amis et des variantes propres à l’Espagne.
Ces fichiers ne sont pas de simples notes. Ils font obligatoirement partie du paquet sélectionné pour le modèle suivant, dans son ordre de lecture, ses sommes de contrôle, ses manifestes et son rapport de structure. Un futur traducteur — humain ou modèle — reçoit ainsi non seulement la règle, mais aussi sa provenance et le vocabulaire de QA nécessaire pour tester le résultat. La localisation devient une autre surface d’ingénierie reproductible, au lieu de rester une mémoire détenue par la dernière personne ayant traduit une page.
05Lisible par les personnes et par les machines
Pour la première fois dans l’histoire du web, deux catégories de lecteurs comptent : les personnes et les systèmes d’IA qui répondent de plus en plus à leurs questions. Une école qui souhaite être découverte doit désormais être lisible par les deux ; chaque page contient donc davantage que ce que l’on voit.
llms.txt fournissent aux systèmes d’IA une copie claire et sans ambiguïté. Nous ne devinons pas comment être cités : nous l’exposons explicitement.Le HTML visible est destiné aux personnes et aux robots d’exploration ; schema.org JSON-LD indique précisément aux machines ce qu’est un programme, un tarif ou une date ; un jumeau Markdown fidèle de chaque page et un index llms.txt fournissent aux systèmes d’IA une copie claire et sans ambiguïté. Lorsqu’un futur étudiant demande à un assistant « où étudier le data engineering en France, en anglais ? », les systèmes qui répondent lisent des données structurées et un texte propre, au lieu de tenter de déchiffrer une jolie page. La plupart des institutions n’ont pas publié de version d’elles-mêmes lisible par machine. Nous l’avons fait.
Le contrôle schema.org nous appartient et ne triche pas
Deux précisions méritent d’être apportées. Premièrement, ce validateur schema.org est développé en interne. Le vocabulaire est public et il existe un vérificateur interactif sur le web, mais aucun outil exécutable sans intervention dans un build, comme c’est le cas pour le validateur HTML. Nous avons donc écrit un vérificateur dédié qui récupère le vocabulaire officiel schema.org et reproduit, page par page et sans intervention humaine, ce qu’afficherait le Schema Markup Validator en ligne. Deuxièmement, et surtout, nous n’avons jamais recherché un résultat flatteur de type « zéro erreur, zéro avertissement » en supprimant du balisage. schema.org est volontairement un vocabulaire ouvert : une propriété qu’il ne déclare pas formellement constitue un avertissement, non une erreur. La solution facile consiste à supprimer les champs concernés, ce qui fait disparaître du sens. À l’inverse, les erreurs bloquent immédiatement la version, tandis que les avertissements sont examinés et conservés lorsque le balisage est réellement juste et utile. Nous validons la structure sans l’amputer.
llms.txt valide. La page d’accueil de DSTI réussit les trois : un résultat net de 3/3. Google précise encore ne pas utiliser llms.txt pour Search, et la catégorie est ouvertement « en cours de développement » ; il ne s’agit donc pas d’un trophée de classement, mais du signe le plus clair à ce jour que les plateformes évoluent dans la direction de contenus pensés pour les lecteurs machine avant même que cela ne devienne obligatoire. Nous n’avions pas anticipé cet audit. Nous le réussissions simplement déjà.06Conçu pour ne pas casser
Un site statique n’est pas fragile ; correctement conçu, c’est même l’inverse. L’ensemble du site est constitué de HTML prérendu dans un stockage objet, verrouillé pour n’être servi qu’à travers le CDN, avec un pare-feu applicatif web, une protection DDoS gérée en périphérie et le DNS en amont. Aucun serveur d’application ne peut tomber à 2 heures du matin, puisqu’il n’existe aucun serveur d’application.
La seule migration réellement délicate concernait le comportement des URLs. L’ancienne configuration reposait sur la logique try_files d’un serveur web pour associer des URLs propres, sans extension, à des fichiers ; la nouvelle périphérie devait reproduire ce comportement avec une petite fonction CDN et gérer la particularité selon laquelle une origine verrouillée renvoie, pour un objet absent, un statut différent de celui auquel on s’attend. Mettre cette logique de réécriture exactement au point — afin que chaque ancien lien fonctionne et qu’aucune erreur 404 ne survienne par accident — a constitué l’essentiel du travail véritablement minutieux de ces trois semaines, avec la création d’une table de redirections entre les sitemaps de l’ancien site et la nouvelle structure.
07Une validité démontrable : neuf contrôles et le refus de publier
Voici la partie qui surprend le plus. Le système refuse de publier une version qui échoue à ses propres contrôles. Il ne s’agit pas d’une consigne du type « soyez prudent au moment du déploiement », mais d’une machine qui empêche toute page défectueuse ou non validée d’être mise en ligne. Au cœur du dispositif, la publication est une machine à états finis.
Rien de partiel n’est jamais publié : l’échec d’une étape de contrôle renvoie le système vers un candidat conservé, et une version peut être rétablie à partir d’une version antérieure identifiée. Les étapes bloquantes sont, dans l’ordre : build (esbuild analyse et minifie chaque fichier externe .js et .css, tandis que le minifieur HTML fonctionne avec la minification du JavaScript inline expressément désactivée, afin qu’aucun script ne soit réécrit) → VNU HTML et CSS (la sortie doit être vide) → validité du JavaScript inline (chaque <script> exécutable, gestionnaire on* et URL javascript: doit être analysable) → préservation exacte octet par octet du JavaScript inline lors de la minification → optimisation prudente du CSS par page (uniquement les réécritures autorisées, avec équivalence démontrée pour chaque page) → validité JSON-LD / schema.org → preuve de reconstruction identique octet par octet → cohérence de version entre les sources (cinq documents doivent s’accorder sur la version active) → publication, avec un marqueur interdisant le déploiement et un étiquetage de version permettant le retour arrière.
# publish() — simplified; every step is a hard gate def publish(candidate): stage(candidate) # into a verified temp tree for gate in [ build, # esbuild parses/minifies every .js and .css; inline JS untouched vnu_html, vnu_css, # W3C/VNU must print nothing — HTML and CSS alike inline_js_valid, # every inline script, on-handler, javascript: URL must parse inline_js_preserve, # inline JS byte-identical, before vs after minification css_allowlist, # per-page CSS pruned; only allow-listed rewrites, proven equivalent schemaorg, # JSON-LD validates against the live vocabulary byte_identical, # published == validated source, to the byte version_authority]: # five documents agree on the active version if not gate(candidate).ok: mark("DO_NOT_DEPLOY"); keep(candidate) # retained for retry; nothing ships return Blocked aws_publish(candidate); tag_version(candidate) # transactional; rollback enabled return Published
Une étape de contrôle exécutée à chaque version doit être rapide. Nous avons donc fortement accéléré la validation HTML et CSS et, surtout, démontré que le chemin rapide produit exactement les mêmes verdicts que le chemin de référence, y compris sur des cas de test volontairement défectueux et des chemins Unicode difficiles. Aller vite sans cette preuve serait tricher ; aller vite avec elle relève simplement d’une bonne ingénierie.
08Le système complet, de bout en bout
Avant d’expliquer le « comment », voici l’ensemble du dispositif sur une seule page : chaque langage et chaque outil de la chaîne qui transforme une ligne de tableur en page servie en périphérie de réseau. Le système est volontairement polyglotte et embarque ses dépendances : le cœur Python ne dépend d’aucune bibliothèque tierce, et les outils plus lourds voyagent dans le projet, avec des versions figées, pour Windows comme pour macOS. Toute machine peut ainsi reproduire un build sans installation globale.
Un orchestrateur Python sans dépendance tierce pilote la chaîne d’outils : un outil d’inventaire de contenu en .NET 8, un vérificateur schema.org interne en Python, le Nu Html Checker fondé sur Java, qui valide le HTML comme le CSS, un minifieur Node accompagné, dans la même étape de build, d’un validateur du JavaScript inline et d’un optimiseur prudent du CSS par page, ainsi qu’un moteur de géolocalisation XML/XSD. Le résultat est un site statique dont les fichiers sont versionnés par empreinte — chaque octet étant pris en compte par des sommes de contrôle et un manifeste par fichier — servi depuis un stockage objet à travers le CDN. Les deux éléments historiques encore en migration sont une installation WordPress qui fournit des images au moment du build, et non à l’exécution, ainsi qu’un unique formulaire de candidature avec persistance d’état.
Un moteur de contenu pour tous, pas seulement pour les ingénieurs
Toute cette discipline vise à permettre aux non-ingénieurs de contribuer en toute sécurité. La surface d’édition est un tableur ; un outil d’inventaire de contenu le lit ; l’orchestrateur Python pilote chaque étape ; et les contrôles précédents empêchent qu’un collègue modifiant un tarif ou une date ne publie par accident quelque chose d’invalide. La boucle est fermée et s’auto-vérifie.
09Dynamique là où cela compte
Un site statique ne doit pas nécessairement être inerte. Lorsqu’une adaptation aide réellement un visiteur, la page s’ajuste — mais au moyen d’un petit moteur de règles validé, plutôt que de scripts improvisés. Le routage selon la région, par exemple pour diriger un visiteur d’Asie du Sud vers le bon représentant régional, est exprimé sous la forme d’un jeu de règles XML validé par son propre XSD avant toute exécution. Le même réflexe se retrouve partout dans le build : les paramètres de déploiement sont eux-mêmes validés par rapport à un schéma avant qu’une commande puisse agir. Une cible de déploiement mal formée est ainsi détectée avant le déploiement, et non en plein déploiement. Vérifier, puis poursuivre — en périphérie autant que dans le pipeline.
10Conçu avec l’IA — et volontairement portable
Une grande partie de ce travail a été réalisée avec l’aide de l’IA, mais pas selon une logique jetable de copier-coller depuis un chatbot. Le principe est simple : la mémoire du projet réside dans le projet, et non dans une conversation ou un modèle particulier. Chaque décision importante est consignée dans des fichiers de continuité versionnés qui accompagnent le dépôt : l’un pour le contenu — version de référence, règles de traduction, invariants UI/UX, URLs, médias, décisions de non-régression — et l’autre pour l’outillage — validations, procédures AWS, incidents connus. Un nouveau collaborateur, humain ou modèle, commence par ces fichiers et par le paquet auto-vérifié, non par l’historique de conversation de quelqu’un.
Ce principe n’est pas théorique : la passation a été testée avec différents modèles, un second modèle ayant reconstruit indépendamment la version active et vérifié chaque somme de contrôle avant de proposer une modification. À partir de V308, la passation compacte est devenue une liste blanche strictement sélectionnée plutôt qu’un simple dépôt de dossiers : sources et sorties maintenues, ContentInventory actif, autorité de traduction et éléments de preuve propres à chaque langue, sources des outils, structure du paquet générée, manifeste par fichier et base de référence des sommes de contrôle vérifiée indépendamment. Lier le site d’une école à la mémoire d’un seul fournisseur d’IA créerait simplement une nouvelle forme de dépendance et un nouveau point unique de défaillance ; nous l’avons donc exclu par conception. La reprise du projet ne doit pas non plus coûter une semaine de configuration à un collègue : une seule commande vérifie la présence des outils nécessaires au build, installe les composants embarqués et refuse de déclarer le projet « prêt » tant que ses paramètres ne sont pas validés par rapport à leur schéma.
11Pourquoi le monde, plutôt que le marché national
On peut légitimement se demander pourquoi une école française investit autant dans le monde et relativement peu dans le marché qui l’entoure. La réponse honnête tient à la nature de ce que nous avons construit. DSTI est, depuis le premier jour, une institution conçue pour le marché international : un corps enseignant volontairement mixte de plus de 50 universitaires et professionnels ; une Direction des Études qui constitue en réalité une fonction opérationnelle et de contrôle qualité que la France reconnaît à peine comme une discipline, et valorise encore moins ; des modes d’études extrêmement flexibles ; des bourses au mérite ; des programmes et des évaluations exigeants ; des certifications professionnelles ; et un enseignement entièrement en anglais. Rien de cela n’est conçu pour un marché strictement national.
Pour des raisons structurelles — et non de qualité — les marchés français de premier cycle et de cycle supérieur sont largement insensibles à ces caractéristiques. Nous faisons donc la chose la plus française qui soit : nous exportons. La France est l’une des grandes économies exportatrices du monde ; nous aussi. Nous portons dans le monde le meilleur de ce que la France et DSTI ont à offrir, et nous faisons venir des étudiants de qualité pour qu’ils puissent en tirer pleinement parti.
12En toute franchise : investir pendant une année difficile
Parlons franchement, car nous le devons. Le marché de l’enseignement supérieur est difficile en ce moment, pour tout le monde. Nous résistons mieux que la plupart, mais il serait malhonnête d’embellir la situation : les effectifs étudiants sont restés stables au lieu de progresser depuis 2024. Dans ce contexte, rester stable est déjà un résultat que bien des institutions n’ont pas obtenu — mais ce n’est pas de la croissance, et toute cette refonte repose sur le pari que la croissance reviendra.
La solution facile, dans une année difficile, consiste à réduire les dépenses et à attendre. Nous avons fait l’inverse : investir dans les programmes, les personnes, le corps enseignant et la visibilité internationale — le réseau de partenaires, le site web et les supports de communication. Cela a été possible grâce au soutien patient de notre Président et de nos actionnaires, tous des particuliers, ingénieurs et scientifiques — un soutien que nous ne tenons pas pour acquis.
13Ce à quoi tout cela sert réellement
Le réseau présent dans 78 pays, les pages rapides, le balisage propre, les versions démontrables, les trois langues : aucun de ces éléments ne constitue une fin en soi. Ce qui compte est ce à quoi ils servent : donner à un jeune, quelque part où nous ne sommes pas encore allés, qui a du talent mais peu de moyens, une véritable chance d’accéder à une formation sérieuse, à une profession solide et à une carrière durable. Nous sommes une petite école encore jeune, sans nom célèbre ni budget immense. Nous avons choisi de faire le meilleur travail possible, au plus haut niveau de qualité que nous puissions atteindre — et nous disposons de plus en plus de l’ingénierie nécessaire pour le démontrer.
Le résumé honnête
Une petite école a résolu par l’ingénierie un problème qu’elle ne pouvait résoudre par la dépense : un build de site statique sans dépendance tierce, entièrement validé, portable entre modèles d’IA, disponible en trois langues, rapide sur téléphone, lisible par les machines et impossible à publier s’il est défectueux — le tout pour gagner, famille après famille, la confiance nécessaire pour enseigner. Voilà tout l’article, et toute sa raison d’être.
Les figures sont produites à partir du build réel ; certains détails techniques sont simplifiés pour un public général intéressé par l’ingénierie. Les chiffres de performance correspondent à des mesures en laboratoire issues des exécutions indiquées, et ne remplacent pas des données de terrain.