📖 11 min de lecture

Next.js vs Astro pour le SEO (2026) : lequel choisir ?

Une comparaison pratique et sans esbroufe de Next.js et Astro pour le SEO — rendu, performance, i18n, et quand chacun l'emporte.

  • Next.js
  • Astro
  • Comparison

Next.js comme Astro peuvent parfaitement bien se classer. Google indexe sans broncher le HTML rendu côté serveur par l’un comme par l’autre, et « quel framework est meilleur pour le SEO » est une mauvaise question si on l’entend comme « lequel Google préfère-t-il secrètement ». La bonne question est plus étroite et plus utile : étant donné le type de site que vous construisez, quel framework fait du bon SEO le chemin de moindre résistance ?

C’est une comparaison de développeur à développeur. Nous allons examiner les pipelines de rendu réels, ce qui part vers le navigateur par défaut, comment les Core Web Vitals se comportent, et comment chaque framework gère le travail ingrat mais décisif des hreflang et des données structurées. Pas de tribalisme — juste des compromis et du code.

TL;DR — la conclusion en une ligne

Si vous construisez un site de contenu ou de marketing (blog, documentation, pages d’atterrissage, SEO programmatique), Astro vous offre dès la sortie de boîte du HTML quasi sans JS et le moins d’occasions de plomber accidentellement vos Core Web Vitals. Si vous construisez une application interactive avec une couche de contenu greffée par-dessus (tableaux de bord, SaaS avec une surface marketing, e-commerce avec forte personnalisation), Next.js vous donne un seul modèle mental pour toute l’application et un SSR/ISR mature pour les pages qui doivent être dynamiques.

DimensionAstroNext.js (App Router)
Rendu par défautSSG (HTML pré-rendu)SSR / RSC (rendu serveur par requête)
JS envoyé par défaut~0 Ko (îlots uniquement)runtime React + payload RSC
Rendu dynamiqueadaptateur SSR, à la demandeSSR, ISR, streaming, RSC — natif
Core Web Vitals par défautExcellent (peu à hydrater)Bon, mais facile à dégrader
i18nRoutage intégré + hreflang manuelconfig i18n (Pages) / manuel (App) + hreflang
Données structuréesEn ligne dans le template .astroEn ligne dans le composant / generateMetadata
Idéal pourSites de contenu et marketingApplis interactives avec contenu
Courbe d’apprentissageFaible si vous connaissez HTML/JSModérée (modèle mental RSC)

Aucun des deux choix n’est une pénalité de classement. La différence, c’est la vigilance nécessaire pour garder vos pages rapides et explorables.

🧑‍💻 Avis de développeur : le framework vous fait rarement perdre des positions à lui seul. Ce qui fait perdre des positions, c’est d’envoyer un bundle JS de 400 Ko pour afficher un paragraphe de texte, ou d’hydrater une page entière alors qu’il fallait un seul widget interactif. Astro rend cette erreur difficile ; Next.js la rend facile — mais vous donne aussi les outils pour l’éviter.

Modèles de rendu

Le SEO commence par une question : que reçoit le crawler dans la réponse HTML initiale ? Google exécute bien le JavaScript, mais le rendu est une seconde vague différée et budgétée — donc le contenu qui n’existe qu’après hydratation est un contenu dont vous pariez la visibilité sur une file de rendu. (Nous couvrons ce pipeline en profondeur dans le guide du SEO JavaScript.)

Astro : statique d’abord, avec des îlots

Le défaut d’Astro, c’est la génération de site statique. À la compilation, il exécute vos composants .astro, produit du HTML complet et — c’est là le point clé — retire le JavaScript du framework à moins que vous n’optiez explicitement un composant pour l’hydratation avec une directive client:*. C’est l’« architecture en îlots » : la page est du HTML statique, et seules les parties interactives deviennent des îlots hydratés.

---
// src/pages/blog/[slug].astro — runs at build time, never ships to the client
const { slug } = Astro.params;
const post = await getPost(slug);
---
<article>
  <h1>{post.title}</h1>
  <div set:html={post.html} />
  <!-- Only this counter ships JS. The rest is inert HTML. -->
  <LikeButton client:visible postId={post.id} />
</article>

Le crawler reçoit l’article entièrement formé dès le premier octet. Il n’y a pas de seconde vague de rendu à attendre, car il ne reste rien à rendre. Pour du contenu, on ne fait pas mieux. Astro peut aussi faire du SSR via un adaptateur (@astrojs/node, Cloudflare, Vercel) quand une route a réellement besoin de données par requête, donc « statique d’abord » ne veut pas dire « statique seulement ».

Next.js : composants serveur et rendu par requête

Next.js avec l’App Router utilise par défaut les React Server Components. Les pages sont rendues sur le serveur (ou à la compilation pour les routes statiques) et envoient du HTML au navigateur, plus un payload RSC qui permet à React de réconcilier et d’hydrater les composants client. Vous obtenez du HTML dans la réponse initiale — bon pour l’exploration — mais la page envoie aussi le runtime React et se ré-hydrate côté client.

Next.js vous offre un menu de modes de rendu plus riche, et vous choisissez par route :

  • Statique (SSG)export const dynamic = 'force-static' ou simplement aucune donnée dynamique ; pré-rendu à la compilation.
  • SSR — rendu par requête, pour du contenu qui change selon l’utilisateur, la géolocalisation ou l’heure.
  • ISRexport const revalidate = 3600 ; servir du statique, régénérer en arrière-plan. Excellent pour les gros sites de contenu qui changent souvent mais pas à chaque requête.
// app/blog/[slug]/page.tsx — Server Component, runs on the server
export const revalidate = 3600; // ISR: re-generate at most hourly

export async function generateStaticParams() {
  const posts = await getAllSlugs();
  return posts.map((slug) => ({ slug }));
}

export default async function Page({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.html }} />
    </article>
  );
}

💡 Astuce : pour le SEO, le pattern Next.js dangereux est la page côté client 'use client' qui récupère son contenu principal dans un useEffect. Ce contenu est invisible dans le HTML initial et dépend entièrement de la vague de rendu de Google. Si le contenu principal d’une route peut être rendu côté serveur, rendez-le côté serveur.

À retenir en pratique : les deux livrent du HTML indexable par défaut dans leurs configurations modernes et recommandées. Astro le livre sans aucun framework client attaché ; Next.js le livre avec une étape d’hydratation. Cette seule différence détermine l’essentiel de ce qui suit.

Performance et Core Web Vitals

Les Core Web Vitals (LCP, INP, CLS) sont un signal de classement, et plus important encore, un indicateur de l’expérience réelle des utilisateurs. Le choix du framework se manifeste le plus clairement dans la quantité de JavaScript envoyée et la part de celui-ci qui doit s’exécuter avant que la page ne soit interactive.

Charge utile par défaut

Une page de contenu Astro typique n’envoie que le JS de ses îlots — souvent littéralement zéro sur un article pur. Une page Next.js App Router typique envoie le runtime React, plus le payload RSC, plus le code de tout composant client. Ce n’est pas du « gras » — c’est le coût d’une appli React — mais sur une page composée à 95 % de prose, vous payez une interactivité que vous n’utilisez pas.

Type de pageJS client Astro typiqueJS client Next.js typique
Article statique, sans widgets~0 Ko~80–110 Ko (runtime + RSC)
Article + un widget de commentaires~15–30 Ko (un îlot)~90–130 Ko
Tableau de bord très interactifcomparable à Next une fois fortement hydraté~150 Ko+ (son terrain de jeu)

Les chiffres varient selon vos dépendances — mesurez votre propre build avec la sortie de next build ou le rapport de bundle d’Astro — mais la tendance est constante : Astro démarre près de zéro et n’ajoute du JS que là où vous le demandez ; Next démarre avec un plancher de runtime et grandit à partir de là.

Coût d’hydratation et INP

Le LCP consiste surtout à peindre rapidement le plus grand élément — les deux frameworks le font bien quand ils rendent côté serveur. La divergence la plus marquée se trouve sur l’INP (Interaction to Next Paint), qui pénalise le travail sur le thread principal. Hydrater un grand arbre React bloque le thread principal ; sur du mobile bas de gamme, cela retarde la première interaction. Les îlots d’Astro s’hydratent indépendamment et paresseusement (client:visible, client:idle), de sorte que le thread principal reste libre plus longtemps.

⚠️ Attention : un framework rapide ne sauvera pas un site lent. Des images de héros non optimisées, des scripts tiers bloquant le rendu et le décalage de mise en page dû aux polices web ruineront les CWV dans l’un comme dans l’autre framework. Lancez un véritable audit (PageSpeed Insights, Lighthouse, ou notre guide Core Web Vitals) avant de blâmer le framework.

Vérifiez ce qui part réellement avec un test rapide sur une page compilée :

# Count bytes of JS the page actually requests
curl -s https://your-site.com/blog/some-post/ \
  | grep -oE 'src="[^"]+\.js"' | wc -l

# Or inspect the initial HTML the crawler sees — is the content there?
curl -s https://your-site.com/blog/some-post/ | grep -c "<h1"

Contenu vs application

C’est là que la décision se résout généralement d’elle-même. Demandez-vous ce qu’est votre site.

Les sites de contenu et de marketing l’emportent avec Astro. Blogs, documentation, journaux de modifications, pages d’atterrissage et pages de SEO programmatique (des centaines ou des milliers d’URL générées à partir d’un modèle) sont surtout du texte et des images avec une interactivité occasionnelle. Les collections de contenu d’Astro vous offrent un frontmatter typé, du Markdown/MDX et une sortie sans JS. Vous obtenez l’ergonomie de rédaction d’une configuration façon CMS allégé avec la performance d’un HTML écrit à la main.

Astro content collection — typed, build-time, zero client JS
  src/content/
    blog/        ← MDX + frontmatter schema (Zod)
    config.ts    ← defineCollection() validates every post at build

Les applications interactives l’emportent avec Next.js. Si le produit principal est une appli — tableaux de bord authentifiés, données en temps réel, formulaires complexes, flux à état — et que le SEO compte pour une surface marketing ou de contenu autour d’elle, Next.js vous permet de tout construire dans un seul framework et un seul déploiement. Vous évitez de faire tourner deux stacks (un site marketing Astro plus une appli React séparée) et les coutures de routage/auth entre eux. L’ISR et le SSR de l’App Router gèrent aussi les pages réellement dynamiques et pertinentes pour le SEO (pages produit avec prix en direct, pages de localisation) qu’un modèle SSG pur vous forcerait à reconstruire en permanence.

La zone grise, c’est l’e-commerce et les gros sites de contenu avec un peu de dynamisme. Les deux fonctionnent. Choisissez Next.js si les pages doivent refléter un état par requête (stock, personnalisation) à grande échelle ; choisissez Astro si le catalogue est surtout statique et que vous pouvez reconstruire ou utiliser un SSR à la demande pour les quelques routes dynamiques.

i18n et données structurées

Le SEO international vit ou meurt sur les hreflang, et les résultats enrichis vivent sur le JSON-LD. Aucun des deux frameworks ne le fait à votre place complètement — vous êtes propriétaire du balisage — mais le support du routage diffère.

hreflang

Les deux frameworks attendent de vous que vous émettiez des balises hreflang réciproques. Astro dispose d’un routage i18n intégré (préfixes de locale, configuration de la locale par défaut) qui rend la génération des URL alternatives directe ; le Pages Router de Next.js avait une config i18n, tandis que l’App Router vous pousse vers des segments de locale basés sur des dossiers (app/[locale]/...) plus une bibliothèque comme next-intl. Dans les deux cas, vous générez les balises vous-même :

<!-- The same set of tags belongs on every language version of a page -->
<link rel="alternate" hreflang="en" href="https://ex.com/en/blog/post/" />
<link rel="alternate" hreflang="fr" href="https://ex.com/fr/blog/post/" />
<link rel="alternate" hreflang="x-default" href="https://ex.com/en/blog/post/" />

💡 Astuce : le bug hreflang le plus courant est l’annotation non réciproque — la page A pointe vers B, mais B ne pointe pas vers A. Générez l’ensemble complet du cluster à partir d’une seule source de vérité (une table locale → URL) et affichez-le sur chaque variante. Notre analyse détaillée se trouve dans le guide du SEO international.

Données structurées (JSON-LD)

Le JSON-LD n’est qu’une balise script, donc les deux frameworks le gèrent identiquement dans l’esprit — la seule différence, c’est vous le placez. Dans Astro, vous l’intégrez en ligne dans le template ; dans Next.js, vous le rendez depuis un composant ou le construisez dans generateMetadata.

---
// Astro: build the object in frontmatter, render as a script tag
const schema = {
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  headline: post.title,
  datePublished: post.pubDate.toISOString(),
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
// Next.js: render JSON-LD from a Server Component
export default function Page({ post }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    headline: post.title,
    datePublished: post.pubDate,
  };
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
    />
  );
}

Validez la sortie avec le Test des résultats enrichis de Google quel que soit le framework — une propriété obligatoire manquante échoue silencieusement et vous n’obtenez jamais le résultat enrichi.

Quand choisir lequel

Conseils concrets par scénario :

  • Blog, documentation ou site marketingAstro. Défaut sans JS, collections de contenu, CWV au meilleur effort avec le minimum de discipline requis.
  • SEO programmatique à grande échelle (des milliers de pages générées à partir d’un modèle) → Astro si les pages sont plutôt statiques ; Next.js avec ISR si elles ont besoin d’une fraîcheur fréquente ou par requête.
  • SaaS avec un site marketing et une appliNext.js si vous voulez une seule stack ; Astro pour le marketing + votre framework d’appli si vous voulez une vitesse maximale des pages marketing et que deux déploiements ne vous dérangent pas.
  • E-commerceNext.js pour le stock/les prix/la personnalisation par requête à grande échelle ; Astro pour les catalogues surtout statiques.
  • Appli très interactive où le SEO est secondaireNext.js. Le SEO n’est pas un enjeu ici ; choisissez pour l’expérience développeur.
  • Équipe qui connaît React à fond et livre viteNext.js réduit les frictions même pour du contenu, tant que vous restez discipliné sur le JS client.

🧑‍💻 Avis de développeur : un pattern populaire et tout à fait valable, c’est les deux — Astro pour le sous-domaine ou le chemin /blog marketing/blog, Next.js (ou votre SPA) pour app.*. Vous obtenez la performance de contenu d’Astro là où le SEO compte et l’interactivité de React là où il ne compte pas. Le coût, ce sont deux builds et un design system partagé.

Pour conclure

Arrêtez de chercher le framework que Google récompense — il n’y en a pas. Next.js comme Astro produisent du HTML explorable et classable lorsqu’ils sont configurés à la moderne. La vraie décision porte sur le comportement par défaut et les modes d’échec : Astro fait des pages de contenu rapides et sans JS le défaut et la voie de la facilité ; Next.js fait d’une application unifiée et interactive le défaut et vous donne les modes de rendu pour garder les pages dynamiques SEO-friendly quand vous y investissez la discipline.

Choisissez Astro quand le site est du contenu. Choisissez Next.js quand le site est une appli qui a aussi du contenu. Et dans le doute, mesurez le HTML initial et le JS envoyé sur un vrai build avant d’en débattre.

Étapes suivantes :