Guide Astro SEO

Astro est l’un des cadres les plus solides pour le SEO : les pages sont pré-rendues en HTML statique par défaut et n’envoient du JavaScript que là où vous le demandez, avec de très bons Core Web Vitals. Mais les valeurs par défaut ne sont pas des garanties, et Astro n’écrit pas vos balises meta, votre sitemap ni vos canoniques à votre place. Voici comment j’exploite mon propre site Astro et comment mettre l’architecture en place correctement.

Première publication : 26 juin 2026 · Dernière mise à jour : 9 août 2026 · Advanced
Langues

Astro est l’un des meilleurs choix de cadre pour le SEO, car il pré-rend par défaut le HTML statique : votre contenu se trouve dans le HTML brut dès le premier crawl, sans file de rendu à attendre pour cette route. Les îlots n’hydratent que les composants auxquels vous ajoutez une directive client, si bien que la plupart du site est envoyée sans son propre JavaScript d’hydratation (Astro peut toutefois ajouter des scripts de page et du JavaScript de routeur ailleurs) — rien de cela ne garantit à lui seul l’explorabilité, l’indexation ou les positions, donc vérifiez les routes déployées. Les sites Astro obtiennent aussi de très bons résultats de Core Web Vitals. Le point d’attention : Astro produit un HTML propre, mais n’écrit pas vos balises meta, vos canoniques, votre sitemap ni vos données structurées — ce sont des étapes de construction explicites; la découverte du sitemap vise les routes générées statiquement, donc les URL uniquement disponibles à l’exécution demandent un traitement explicite. Les Server Islands (qui nécessitent un adaptateur) et les View Transitions sont compatibles avec le SEO lorsque vous comprenez ce que les robots récupèrent réellement. J’utilise Astro sur patrickstox.com : c’est donc la pile que j’emploie au quotidien.

TL;DR — Astro est particulièrement bien conçu pour le SEO : les pages et les endpoints sont pré-rendus en HTML statique par défaut, sans vague de file de rendu à attendre pour ce contenu — mais il s’agit d’une valeur par défaut, pas d’une garantie universelle, et le HTML statique ou serveur ne prouve pas à lui seul l’explorabilité, l’indexation, les positions ni les Core Web Vitals de vos URL de production. L’architecture en îlots n’hydrate que les composants auxquels vous ajoutez une directive client:* : tout le reste envoie du HTML sans son propre JavaScript d’hydratation, même si des scripts de page, d’autres îlots et des améliorations de routeur peuvent ajouter du JavaScript ailleurs dans la page. Astro ne génère pas automatiquement les balises meta, les canoniques, les sitemaps ni les données structurées : branchez-les explicitement, idéalement avec une validation par Content Collections + Zod. Les Server Islands (qui nécessitent un adaptateur) servent l’enveloppe statique avec son contenu de repli dans le document initial, puis récupèrent le contenu différé séparément — vérifiez ce qu’un robot donné récupère réellement au lieu de supposer. Les View Transitions utilisent history.pushState et sont compatibles avec le SEO; Google explore normalement les pages MPA sous-jacentes. J’utilise patrickstox.com avec Astro : les fonctions ci-dessous sont celles que j’emploie réellement, vérifiées sur le site déployé et non seulement en développement local.

Evidence for this claim Astro prerenders pages as static HTML by default and only sends client JavaScript for explicitly hydrated components. Scope: Astro default static output and islands architecture. Confidence: high · Verified: Astro: Why Astro

Pourquoi Astro évite complètement le problème du rendu JavaScript

Toute la difficulté du SEO JavaScript vient de la seconde vague. Google récupère d’abord votre HTML brut, puis met la page en file pour un rendu ultérieur dans Chromium sans interface — et cette file constitue le risque. Les documents de Google l’expliquent ainsi : “Googlebot queues all pages with a 200 HTTP status code for rendering unless a robots meta tag tells Google not to index the page. The page may stay on this queue for a few seconds, but it can take longer than that.” (traduction) : « Googlebot met en file pour le rendu toute page dont le statut HTTP est 200, sauf si une balise meta robots lui indique de ne pas l’indexer. La page peut rester dans cette file quelques secondes, mais l’attente peut être plus longue. » Pour une SPA rendue côté client, votre contenu n’existe pas avant cette phase de rendu.

Le mode de sortie par défaut d’Astro est statique : les pages et les endpoints sont pré-rendus dans un fichier HTML complet au moment du build. Pour une route qui utilise cette valeur par défaut, le HTML brut est la page rendue. Evidence for this claim Astro uses static output and prerenders routes at build time by default. Scope: Astro default output mode; routes can opt out of prerendering. Confidence: high · Verified: Astro: On-demand rendering Il n’y a aucune seconde vague à attendre pour cette route, puisqu’il ne reste rien à exécuter. Googlebot voit tout le contenu dès la première récupération. Comme l’écrit Joost de Valk (fondateur de Yoast) : “From an SEO perspective, static HTML on a CDN is a better starting point than most CMSes will ever give you.” (traduction) : « Du point de vue du SEO, un HTML statique sur un CDN constitue un meilleur point de départ que ce que la plupart des CMS pourront jamais offrir. »

C’est le comportement par défaut, pas une propriété universelle de chaque route. Avec output: 'server', la valeur par défaut devient un rendu à la demande (nous y revenons plus bas); même dans un projet statique par défaut, un adaptateur permet à une route donnée de désactiver le pré-rendu avec export const prerender = false. Rien de tout cela n’est garanti par la seule architecture : le HTML statique ou serveur, les îlots et les adaptateurs ne garantissent pas l’explorabilité, l’indexation, les positions ni les Core Web Vitals — tout dépend de la route déployée et du robot précis. Vérifiez-les au lieu de supposer que le cadre s’en charge.

Cela aide aussi les robots qui ne peuvent pas effectuer de rendu. Google le dit clairement : “not all bots can run JavaScript” (traduction) : « tous les robots ne peuvent pas exécuter JavaScript » — et c’est la réalité de 2026 pour la plupart des robots d’IA et de nombreux outils tiers. La sortie HTML d’abord d’Astro est lisible par chacun d’eux lorsqu’elle est effectivement pré-rendue, pas seulement par Googlebot. (C’est le même point que je soulève dans le SEO d’un CMS headless : le mode de rendu fait partie du produit.)

Architecture en îlots : du JS uniquement là où vous le demandez

Astro rend vos composants en HTML et, selon ses propres termes, envoie “just HTML & CSS, stripping out all client-side JavaScript automatically.” (traduction) : « uniquement du HTML et du CSS, en retirant automatiquement tout le JavaScript côté client ». L’interactivité est opt-in. Vous marquez un composant avec une directive client:*client:load, client:idle ou client:visible — et seul cet îlot est hydraté avec JavaScript. Tout le reste demeure du HTML statique. Evidence for this claim Astro client directives selectively hydrate interactive islands while other components remain static HTML. Scope: Astro islands and client directives. Confidence: high · Verified: Astro: Islands

Pour le SEO, c’est presque idéal. Le contenu que Googlebot doit indexer est du HTML simple, et vos widgets interactifs ne l’alourdissent pas. client:visible est particulièrement utile : un composant sous la ligne de flottaison ne commence même pas son hydratation avant d’être visible au défilement, et ne bloque donc jamais votre LCP. Le concept vient de Jason Miller (créateur de Preact), qui le décrit comme “rendering HTML pages on the server, and inject[ing] placeholders or slots around highly dynamic regions.” (traduction) : « rendre des pages HTML sur le serveur et injecter des espaces réservés ou des emplacements autour de régions très dynamiques ».

Deux nuances méritent une formulation précise, car les comparatifs les confondent souvent :

  • client:only est différent. Contrairement à client:load/client:idle/client:visible, un composant client:only ignore entièrement le rendu serveur : il ne produit aucun HTML côté serveur. Tout contenu indexable placé uniquement dans un composant client:only ne se trouve donc pas dans le document récupéré par Googlebot; il n’existe qu’après l’hydratation du navigateur. N’y placez pas votre contenu principal.
  • Il s’agit d’hydratation sélective, pas de reprise d’exécution. Astro relance le code client de chaque îlot depuis zéro dans le navigateur; il ne reprend pas un état d’exécution sérialisé sur le serveur comme le ferait un modèle de reprise (celui de Qwik, par exemple). Les deux mécanismes sont souvent confondus dans les articles, mais ils ne sont pas identiques.
Evidence for this claim A client:only component skips server rendering, so indexable content placed only inside it cannot be assumed to exist in the initial page HTML. Scope: client and server islands Confidence: high · Verified: Template directives reference

Un composant non hydraté ne résume pas tout le JavaScript d’une page. « Zéro JS » décrit un composant sans directive client:* : Astro peut encore envoyer des balises <script> au niveau de la page, le routeur des View Transitions et d’autres îlots ailleurs sur la même page. Décrivez ce qui est envoyé par composant ou par route, pas comme une affirmation générale sur toute la page.

Ce qu’Astro ne génère PAS automatiquement

Astro produit un HTML sémantique propre — et rien d’autre en matière de SEO. Il n’y a par défaut ni métadonnées, ni canonique, ni sitemap, ni données structurées. Le mythe selon lequel « Astro est automatiquement optimisé pour le SEO » est exactement cela, un mythe. Vous devez prendre en charge :

  • Les balises meta (titre, description, Open Graph, Twitter).
  • Les URL canoniques.
  • Le sitemap (via l’intégration officielle).
  • Les données structurées / JSON-LD.
  • robots.txt.

Astro est la meilleure base que j’aie utilisée, mais c’est une base, pas une maison terminée.

Le sitemap : @astrojs/sitemap

Installez-le avec npx astro add sitemap. Il explore les routes générées statiquement et émet au moment du build un sitemap-index.xml ainsi que des fichiers sitemap-0.xml découpés. Deux points piègent souvent les utilisateurs : Evidence for this claim Astro's official sitemap integration generates sitemap files from statically generated routes. Scope: Astro @astrojs/sitemap integration. Confidence: high · Verified: Astro: Sitemap integration

  • Vous devez définir site: dans astro.config.mjs. Sans cette valeur, l’intégration génère silencieusement un résultat vide. C’est la cause la plus fréquente du « où est mon sitemap ? ».
  • Vous devez ajouter vous-même la ligne du sitemap dans robots.txt. Astro ne le fait pas.

Pour garder le contrôle, filter() exclut des routes (pages d’aperçu ou brouillons — c’est exactement ce que j’utilise sur ce site), serialize() permet de définir lastmod, changefreq et priority, et l’option i18n émet des entrées hreflang dans le sitemap. C’est ce que spécifient les documents actuels de @astrojs/sitemap; vérifiez votre version installée si elle est ancienne, car le comportement de l’intégration a déjà changé entre versions majeures.

La limite qui piège le plus : la découverte de l’intégration vise les routes générées statiquement. Si certaines URL n’existent qu’à l’exécution — routes rendues côté serveur (output: 'server') ou générées à la demande plutôt qu’au moment du build — ne supposez pas qu’elles figurent dans le sitemap. Ajoutez-les explicitement avec customPages, puis ouvrez réellement sitemap-index.xml après un build pour confirmer leur présence. Ne prenez pas pour acquis que « l’intégration s’en charge » lorsqu’il ne s’agit pas d’une route statique de build.

Balises meta et canoniques : le modèle BaseLayout

Astro n’a pas de composant <Head> spécial : vous contrôlez directement <head> dans les fichiers .astro. Le modèle courant (et celui que j’utilise) est un unique BaseLayout.astro qui reçoit title, description et canonicalURL comme props et écrit l’en-tête. Définissez explicitement le canonique sur chaque page et gardez-le cohérent avec og:url. Une bibliothèque n’est pas nécessaire, mais le paquet communautaire astro-seo (npm) est un wrapper pratique à un composant pour le titre, la description, OG, Twitter et le canonique si vous le souhaitez.

Content Collections comme filet de sécurité SEO

C’est une fonction SEO sous-estimée d’Astro. Les Content Collections constituent une couche de contenu typée pour votre Markdown/MDX/JSON, avec validation de schéma par Zod. Vous pouvez ainsi rendre les champs title et description obligatoires; si une page en oublie un, le build échoue. Il est alors impossible d’envoyer par accident une page sans titre. Les fonctions de requête (getCollection(), getEntry()) produisent les pages statiques au moment du build, donc la sortie déployée est du HTML simple. Et puisque MDX conserve le Markdown brut comme source de vérité, ces fichiers forment aussi un contenu source propre pour les robots d’IA et les motifs de type llms.txt. Ce site même repose sur des Content Collections avec un frontmatter validé par Zod.

astro:assets : des images bien faites (avec un piège)

Le composant <Image /> convertit automatiquement en WebP, déduit les dimensions pour “avoid Cumulative Layout Shift (CLS).” (traduction) : « éviter le décalage cumulatif de mise en page (CLS) », définit loading="lazy" par défaut et exige alt — l’absence de alt est une erreur de compilation. <Picture /> étend ce comportement avec des éléments <source> AVIF/WebP et une solution de repli.

Le piège : le loading="lazy" automatique est mauvais pour votre image LCP (généralement l’image hero). Le chargement différé de l’image la plus importante retarde son affichage. Pour les images au-dessus de la ligne de flottaison, remplacez-le par loading="eager" et fetchpriority="high". Les images distantes ont besoin d’un width et d’un height explicites.

Server Islands : ce que voient réellement les robots

Les Server Islands (Astro 4.12+) sont la fonction que la plupart des guides concurrents décrivent mal. Avec server:defer, un composant est rendu sur le serveur indépendamment de la page principale. L’enveloppe statique est servie immédiatement; selon les documents Astro : “Your page will be rendered immediately with any specified fallback content as a placeholder. Then, the component’s own contents are fetched on the client and displayed when available.” (traduction) : « Votre page est rendue immédiatement avec le contenu de repli spécifié comme espace réservé. Le contenu propre au composant est ensuite récupéré côté client et affiché lorsqu’il est disponible. »

Deux points doivent être exacts. Premièrement, les Server Islands nécessitent un adaptateur : c’est une fonction à la demande, pas un résultat produit par un build entièrement statique. Deuxièmement, la séquence est la suivante : le document initial envoie le contenu de repli que vous avez configuré, puis le contenu réel de l’îlot est récupéré par une requête indépendante sur son propre endpoint, après le chargement de la page. C’est une limite ferme de ce que contient le premier document; je ne généraliserais pas au comportement ultérieur de chaque robot sans tester directement vos URL déployées.

La conséquence SEO est concrète : le HTML statique lu par un robot lors de la première récupération contient le contenu de repli, pas celui de l’îlot différé. C’est parfait pour l’usage prévu des Server Islands : les informations personnalisées liées à la session (état de connexion, panier, recommandations) qui ne devraient de toute façon ni être mises en cache ni indexées. C’est inadapté au contenu indexable principal. Placez tout ce qui doit être positionné dans le modèle Astro principal, et laissez les Server Islands gérer les éléments dynamiques autour.

Modes de sortie : statique ou serveur, avec remplacement par route

Le mode de sortie par défaut d’Astro est static : les pages et les endpoints sont pré-rendus en HTML lors du build. Définissez output: 'server' dans astro.config.mjs pour passer par défaut au rendu à la demande : les pages sont rendues pour chaque requête (avec un adaptateur), ce qui convient à l’authentification, aux données en temps réel ou à la personnalisation au-delà des Server Islands. Dans les deux cas, vous pouvez remplacer le défaut par route : dans un projet statique par défaut, export const prerender = false active le rendu à la demande; dans un projet serveur par défaut, export const prerender = true réactive le pré-rendu au moment du build. Ainsi, « mon site est statique » ou « mon site est en SSR » est rarement vrai pour toutes les routes : vérifiez le réglage par route, pas seulement la configuration de niveau supérieur.

Evidence for this claim Astro uses static output and prerenders routes at build time by default. Scope: Astro default output mode; routes can opt out of prerendering. Confidence: high · Verified: Astro: On-demand rendering

Du point de vue du seul SEO, le HTML pré-rendu et le HTML à la demande sont équivalents — tous deux fournissent un HTML complet à la première requête d’un robot, une fois que vous avez confirmé que la route renvoie un statut 200 avec tout son balisage. Les routes à la demande peuvent envoyer leur HTML en flux, et des données lentes ou des conditions réseau peuvent retarder des morceaux ultérieurs; une réponse en flux ne prouve donc pas automatiquement que tout le contenu est arrivé : vérifiez-le, ne le supposez pas. La différence réelle est opérationnelle : le contenu pré-rendu reste fixe jusqu’au prochain build (ou à une actualisation d’exécution configurée séparément) et est servi depuis le bord CDN; le contenu à la demande reste actuel, mais dépend de la santé de l’adaptateur et de l’exécution en production. N’en faites pas une décision SEO : choisissez selon l’actualité des données et l’exploitation, puis validez les routes déployées, les statuts, les redirections et les en-têtes de réponse plutôt que d’extrapoler depuis le développement local.

View Transitions : compatibles avec le SEO malgré l’impression d’application monopage

Le <ClientRouter /> d’Astro (anciennement <ViewTransitions />) fournit une navigation douce de type SPA à l’aide de l’API View Transitions du navigateur et de la History API. Le fait clé : la navigation utilise history.pushState, exactement ce que Google recommande pour la navigation côté client — Google avertit que les URL fondées sur un fragment (#hash) sont quelque chose qu’il “can’t reliably resolve.” (traduction) : « ne peut pas résoudre de manière fiable ». Surtout, les View Transitions améliorent l’expérience dans le navigateur : lorsqu’il explore, Googlebot demande chaque URL et reçoit une page HTML normale et complète; la MPA sous-jacente reste intacte. Les transitions ne changent que ce que voit l’utilisateur dans le navigateur.

Donc non, les View Transitions ne transforment pas votre site Astro en SPA et ne cassent pas le SEO. Une lacune à noter : les documents View Transitions d’Astro n’ont aucune section SEO, ce qui explique peut-être la persistance du mythe « cela casse le SEO ». Pour vérifier votre propre site, récupérez directement quelques URL et confirmez que chacune renvoie un HTML complet : contrôlez votre déploiement au lieu de vous en remettre à une supposition.

Erreurs SEO courantes avec Astro

  1. Supposer qu’Astro s’occupe du SEO. Il s’occupe du HTML. Les meta, canoniques, sitemap et schéma vous reviennent.
  2. Oublier site: dans la configuration : votre sitemap ne se génère silencieusement pas.
  3. Ne pas ajouter le sitemap à robots.txt : Astro ne le fera pas.
  4. Charger l’image LCP en différé : remplacez le héros par eager + fetchpriority.
  5. Placer du contenu indexable dans une Server Island : les robots voient le repli, pas le contenu, et les Server Islands nécessitent d’abord un adaptateur.
  6. Poursuivre un score Lighthouse parfait et s’arrêter là. La vitesse est un signal de classement, pas le signal de classement. Une page rapide mais vide ne se positionne pas : le contenu, les liens et l’E-E-A-T font toujours l’essentiel du travail.
  7. Placer du contenu indexable uniquement dans un composant client:only. Contrairement aux autres directives client:*, client:only ignore totalement le rendu serveur : il n’y a aucun HTML pour ce composant avant l’hydratation du navigateur.
  8. Traiter « Astro est statique et rapide » comme une garantie de résultat. Le HTML statique ou à la demande, les îlots et les adaptateurs sont des mécanismes; ils ne garantissent pas à eux seuls l’explorabilité, l’indexation, les positions ni les Core Web Vitals. Validez la route déployée et non le schéma d’architecture.

Où ce sujet se place dans le cluster

Astro est une réponse particulière et exceptionnellement favorable au SEO aux questions que pose le SEO JavaScript sur le rendu, et un frontend courant pour les configurations de CMS headless. La performance rejoint directement les Core Web Vitals du cluster des performances web, tandis que la discipline consistant à vérifier si le contenu se trouve bien dans le HTML est la même que dans les clusters d’exploration et d’indexation.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.