Refondre mon site Drupal de 2016 avec Astro 7 : carnet de bord
Pendant plus de dix ans, mon site personnel a tourné sous Drupal — évidemment : je construis des plateformes Drupal pour gagner ma vie. Mais le site était devenu le cordonnier le plus mal chaussé du web : un CV d’une seule page sur un Drupal 9 vieillissant, avec 58 feuilles de style bloquantes, aucune donnée structurée, pas de sitemap, et un contenu figé quelque part autour de 2019.
Je l’ai refondu avec Astro 7 — et cet article documente l’architecture SEO-first, parce que c’est exactement la recette que je recommande désormais pour tout site de contenu qui n’a pas besoin d’un front piloté par un CMS.
Pourquoi du statique, et pourquoi Astro
Mon ancien site Drupal servait exactement une page aux visiteurs anonymes. Faire tourner une pile CMS complète — PHP, base de données, mises à jour de sécurité, couches de cache — pour servir ce qui est en réalité un document statique, c’est de la dette d’ingénierie sans retour sur investissement.
La proposition de valeur d’Astro colle parfaitement à ce cas :
- Zéro JavaScript par défaut. Chaque octet de JS doit se justifier. Mes pages de contenu n’en embarquent aucun.
- Les content collections avec frontmatter typé — le blog, ce sont des fichiers markdown dans git, validés au build.
- Un outillage images et fonts de premier ordre — j’y reviens plus bas.
- La sortie, c’est du HTML pur sur un CDN. Rien à pirater, rien à patcher un mardi soir.
Note pour mes collègues drupalistes : ce n’est pas un discours « Drupal est mort ». Les plateformes éditoriales avec des dizaines de contributeurs ont besoin d’un vrai back-office — c’est exactement à ça que sert Drupal. Pas votre site personnel.
Ce qui compte vraiment pour le SEO
Des fonts sans décalage de mise en page
L’API Fonts intégrée d’Astro télécharge les polices au build, les auto-héberge avec des sous-ensembles
unicode-range, et — la fonctionnalité qui tue — génère automatiquement des polices de repli ajustées
métriquement. L’Arial de secours est métriquement compatible avec la vraie police : le swap ne provoque quasiment
aucun décalage cumulatif (CLS). Il fallait toute une chaîne manuelle pour ça ; c’est devenu un bloc de config.
Un graphe JSON-LD par page
Plutôt que d’éparpiller des fragments de schema déconnectés, chaque page émet un unique @graph qui relie les
entités par @id : WebSite → Person (mon entité, avec des liens sameAs vers drupal.org, GitHub et LinkedIn) →
le nœud de la page (WebPage, ProfilePage, BlogPosting…) → BreadcrumbList. Les moteurs de recherche — et de
plus en plus les LLM — reçoivent un graphe d’identité cohérent au lieu de confettis.
Pour une marque personnelle, l’entité Person est tout l’enjeu : c’est elle qui permet à Google (et aux assistants
IA) de relier votre site, vos contributions open source et vos profils en une seule réponse à « qui est cette
personne ».
hreflang uniquement là où les traductions existent
Le site est bilingue (anglais d’abord, français sous /fr/). L’erreur multilingue classique consiste à générer des
paires hreflang pour chaque URL par substitution de préfixe — y compris pour des pages jamais traduites. Mes liens
hreflang sont générés depuis une table de correspondance explicite : une page ne revendique une version alternative
que si elle existe vraiment. Une traduction partielle, c’est acceptable ; mentir aux robots, non.
Des images Open Graph générées au build
Chaque page et chaque article reçoit une image OG 1200×630 aux couleurs de la marque, rendue au build avec satori (template façon HTML → SVG) et resvg (SVG → PNG). Pas de runtime, pas de service tiers — juste des PNG statiques sur le CDN, en marine et azur.
La plomberie ennuyeuse, faite proprement
robots.txtgénéré depuis la config, pointant vers l’index de sitemap.- Sitemap avec de vraies valeurs
lastmod. - Redirections 301 pour chaque URL de l’ancien site Drupal (
/node/1, tu ne me manqueras pas). - Canoniques, balises OG/Twitter et meta descriptions sur chaque page — imposées par un unique composant
<Seo>: impossible de créer une page sans elles.
Déploiement : Cloudflare
Le site est déployé en assets statiques sur Cloudflare Workers, avec une seule route rendue côté serveur : le formulaire de contact (Turnstile contre les bots, Resend pour l’envoi — une cinquantaine de lignes). Depuis le rachat de l’équipe Astro par Cloudflare en janvier 2026, c’est la voie de déploiement la plus investie de l’écosystème, et l’offre gratuite couvre entièrement un site personnel.
Le résultat
Lighthouse ne monte pas plus haut, et le poids des pages est passé d’une soupe de CSS/JS en mégaoctets à quelques dizaines de kilo-octets. Mais la vraie métrique est ailleurs : l’ancien site avait une seule page indexable ; celui-ci a une architecture de contenu faite pour grandir — services, études de cas, et ce blog.
Les prochains articles creuseront chaque brique : la conception du graphe JSON-LD, les patterns de migration Drupal → statique, et le débogage des Core Web Vitals sur les plateformes Drupal. À suivre.