Maîtrisez le SEO JavaScript en 2026 : rendering CSR/SSR/SSG/ISR, hydration, dynamic rendering, edge SSR, Web Rendering Service Google et indexation des SPAs.
1. Comment Googlebot rend-il le JavaScript ?
Googlebot execute le JavaScript via le Web Rendering Service (WRS), base sur un Chromium "evergreen" (toujours a jour avec la version stable). Mais ce rendu n'est pas instantane : il intervient apres une premiere passe HTML, parfois plusieurs jours plus tard.
Le modele en 2 vagues (2-wave indexing)
| Vague | Action de Googlebot | Contenu vu | Latence typique |
|---|---|---|---|
| Vague 1 | Fetch du HTML brut, suivi des liens visibles | HTML initial uniquement (sans JS execute) | Quelques minutes a quelques heures |
| Vague 2 | Rendu via WRS, JS execute, DOM final indexe | Contenu apres hydration et fetch client | Quelques heures a 7 jours selon budget |
Le rendering budget : la contrainte cachee
Comme le crawl budget, Google applique un rendering budget : le nombre de pages que WRS rendra sur ton domaine par jour. Plus tes pages sont lourdes en JS, moins Google en rendra dans le temps imparti.
- Pages legeres — Plus rendues, indexees plus vite
- Pages avec JS bloquant — Risque de timeout WRS (~5s)
- Fetch API cote client — Doit aboutir dans le budget WRS
- Code split inutile — Gaspille le budget de rendering
2. CSR vs SSR vs SSG vs ISR : quel rendering choisir ?
Le choix de la strategie de rendering est la decision SEO la plus impactante d'un projet JS moderne. Voici le comparatif complet pour 2026.
| Strategie | Lieu du rendu | LCP | Indexation | Cas d'usage |
|---|---|---|---|---|
| CSR (Client-Side Rendering) | Navigateur uniquement | Mauvais (3-6s) | Lente, depend du WRS | Dashboards, apps privees |
| SSR (Server-Side Rendering) | Node.js a chaque requete | Bon (1-2s) | Immediate, HTML complet | Contenu dynamique, e-commerce |
| SSG (Static Site Generation) | Build time, fichiers statiques | Excellent (< 1s) | Optimale, CDN edge | Blogs, docs, marketing |
| ISR (Incremental Static Regeneration) | Build + revalidation a la demande | Excellent (cache CDN) | Optimale + frais | E-commerce, catalogues |
Exemple Next.js 15 : meme page, 4 modes
// app/produit/[id]/page.tsx
// 1. CSR : 'use client' + fetch cote client (a EVITER pour SEO)
'use client';
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => { fetch('/api/produit').then(r => r.json()).then(setData); }, []);
return <Produit data={data} />;
}
// 2. SSR : fetch cote serveur a chaque requete
export const dynamic = 'force-dynamic';
export default async function Page({ params }) {
const data = await fetch(`https://api.site.com/produit/${params.id}`, {
cache: 'no-store' // force SSR
}).then(r => r.json());
return <Produit data={data} />;
}
// 3. SSG : genere au build (fichier statique)
export async function generateStaticParams() {
const ids = await fetchAllIds();
return ids.map(id => ({ id }));
}
export default async function Page({ params }) {
const data = await fetch(`https://api.site.com/produit/${params.id}`).then(r => r.json());
return <Produit data={data} />;
}
// 4. ISR : SSG + revalidation toutes les 60s
export const revalidate = 60;
export default async function Page({ params }) {
const data = await fetch(`https://api.site.com/produit/${params.id}`, {
next: { revalidate: 60 }
}).then(r => r.json());
return <Produit data={data} />;
}
3. Hydration : LCP, INP et couts caches sur mobile
L'hydration est l'etape ou React/Vue/Angular "rattache" leurs listeners au HTML pre-rendu cote serveur. Le contenu reste indexable, mais la facture cote performance est lourde — surtout pour l'INP, devenu Core Web Vital officiel en mars 2024.
Pourquoi l'hydration tue le INP ?
- Long task > 50ms — Le main thread est bloque pendant l'hydration
- Bundle JS lourd — React + framework + app = 200 a 500 Ko gzipped
- Parsing + execution — 1 a 3s sur mobile milieu de gamme
- Click ignore — Pendant l'hydration, les clics ne fonctionnent pas
3 strategies pour limiter le cout
| Strategie | Principe | Framework | Gain INP |
|---|---|---|---|
| Partial Hydration | Hydrater seulement les composants interactifs | Astro, Marko | -40 a -70% |
| Progressive Hydration | Hydrater par priorite (visible d'abord) | React 19, Vue 3.4 | -20 a -40% |
| Resumability | Reprendre l'etat serveur sans re-executer | Qwik | -80 a -95% |
<!-- Astro : partial hydration via directives client:* -->
<!-- Le carousel n'hydrate qu'au scroll : INP epargne -->
<Carousel client:visible />
<!-- Le menu hydrate immediatement (interactif des le LCP) -->
<Menu client:load />
<!-- Le footer n'hydrate jamais (statique) : 0 JS livre -->
<Footer />
4. Dynamic Rendering : la solution pour les SPAs existantes
Le Dynamic Rendering consiste a livrer du HTML pre-rendu aux bots (Googlebot, bingbot) et la version SPA aux humains. Google l'a longtemps qualifie de "workaround", mais le confirme toujours comme legitime en 2026.
Quand l'utiliser ?
- SPA Angular/React/Vue existant — Migration SSR trop couteuse
- Site lourd en JS — Bundle > 500 Ko, code legacy
- Indexation lente — Pages absentes de Google malgre sitemap
- Solution temporaire — Pont avant migration SSR/SSG
Architecture type
// Express middleware (Node.js) : detection User-Agent
const BOT_UA = /googlebot|bingbot|yandex|duckduckbot|baiduspider|perplexitybot|gptbot/i;
app.get('*', async (req, res) => {
const ua = req.headers['user-agent'] || '';
if (BOT_UA.test(ua)) {
// Bot : on demande a Rendertron / Puppeteer un HTML pre-rendu
const html = await fetch(`https://renderer.internal/render/${encodeURIComponent(req.url)}`)
.then(r => r.text());
res.send(html);
} else {
// Humain : on sert la SPA classique
res.sendFile(path.join(__dirname, 'dist/index.html'));
}
});
5. Edge SSR et Streaming SSR : le standard 2026
L'Edge SSR execute le rendu cote serveur sur des CDN comme Cloudflare Workers, Vercel Edge ou Deno Deploy. Resultat : un TTFB sous 100ms partout dans le monde, sans serveur central a scaler.
Edge vs Node SSR : le comparatif
| Critere | Node SSR classique | Edge SSR |
|---|---|---|
| TTFB monde | 200 a 800ms | 30 a 100ms |
| Runtime | Node.js complet | V8 isolates (limite) |
| Cold start | 200ms a plusieurs secondes | < 5ms |
| APIs Node | fs, child_process, etc. | Web APIs uniquement (fetch, crypto) |
| Impact LCP | Bon | Excellent (TTFB minimal) |
Streaming SSR : envoyer le HTML par morceaux
Avec React 18+ et le Streaming SSR, le serveur envoie le HTML progressivement (sans attendre que tout soit pret). Le navigateur affiche le shell des le premier byte : LCP divise par 2 en moyenne.
// React 19 : Suspense + streaming
import { Suspense } from 'react';
import { renderToPipeableStream } from 'react-dom/server';
function App() {
return (
<html>
<body>
<Header /> {/* HTML envoye immediatement */}
<Suspense fallback={<Skeleton />}>
<ProductList /> {/* envoye plus tard, quand pret */}
</Suspense>
<Footer />
</body>
</html>
);
}
6. Islands Architecture et Resumability : le futur
L'Islands Architecture (Astro, Fresh) et la Resumability (Qwik) ont un objectif commun : livrer le moins de JavaScript possible. C'est la reponse moderne au probleme d'hydration.
Islands : composants interactifs isoles
- HTML statique par defaut — Pas de JS sur 80% de la page
- Composants "ilots" — Hydrates uniquement si interactifs
- Multi-framework — Mix React + Vue + Svelte sur la meme page
- SEO parfait — HTML complet livre, indexation immediate
Qwik : zero hydration grace au resumability
Qwik serialise l'etat React-like dans le HTML. Au lieu de "re-executer" tout le code cote client, le navigateur "reprend" l'etat la ou le serveur s'est arrete. Resultat : 1 ko de JS initial, peu importe la taille de l'app.
7. Diagnostiquer : view-source, GSC, Mobile-Friendly Test
Avant de coder, mesure. Trois outils gratuits suffisent a verifier si Googlebot voit vraiment ton contenu JS.
Outil 1 : view-source
Dans Chrome, tape view-source:https://ton-site.com/page. Tu vois le HTML brut envoye par le serveur, sans aucun JS execute. C'est exactement ce que Googlebot voit a la vague 1.
- Si le contenu y est — SSR ou SSG OK, indexation rapide
- Si vide ou skeleton — CSR pur, depend du WRS
- Si meta tags absents — Probleme critique : pas de title/description
Outil 2 : GSC URL Inspection
Dans Google Search Console, colle l'URL et clique sur "Test Live URL". Onglet "View Tested Page" + "Screenshot" : tu vois exactement le DOM rendu par WRS apres execution JS.
Outil 3 : Mobile-Friendly Test
search.google.com/test/mobile-friendly — affiche le HTML rendu et liste les ressources bloquees (CSS, JS). Indispensable pour detecter un robots.txt qui bloque tes bundles.
view-source et dans le DOM Chrome (Inspect > Elements). Un ecart > 50% = signal d'alerte pour le SEO.
8. Pieges JavaScript SEO frequents (a eviter absolument)
| Piege | Symptome | Fix |
|---|---|---|
| Soft 404 cote client | SPA affiche "404" sans code HTTP 404 | Renvoyer un vrai status 404 cote serveur (SSR) |
| Bundle JS bloque par robots.txt | Mobile-Friendly Test : ressources rouges | Autoriser Allow: /*.js$ dans robots.txt |
| Meta tags injectes en JS | view-source : title vide, OG manquant | Generer title/description cote serveur |
| Links onClick au lieu de href | Googlebot ne suit pas les liens | Toujours utiliser <a href="..."> |
| Infinite scroll sans pagination | Seules les premieres entrees indexees | Ajouter pagination avec URLs canoniques |
| Lazy hydration mal configuree | INP > 500ms, FID degrade | Hydrater les composants visibles d'abord |
| Tabs avec contenu en display:none | Contenu indexe mais avec score reduit | Render tous les onglets, masquer via CSS |
9. Impact GEO : pourquoi les moteurs IA n'aiment pas le CSR ?
Les crawlers des moteurs IA (GPTBot, PerplexityBot, ClaudeBot, Google-Extended) sont nettement moins evolues que Googlebot. La majorite n'execute pas JavaScript du tout.
| Crawler IA | Execute JS ? | Indexation contenu CSR |
|---|---|---|
| GPTBot (OpenAI) | Non confirme officiellement | HTML brut uniquement |
| PerplexityBot | Limite | HTML brut prefere |
| ClaudeBot (Anthropic) | Non | HTML brut uniquement |
| Google-Extended | Oui (partage avec WRS) | Apres rendu |
| Googlebot (Search) | Oui | Apres vague 2 (delai) |
10. Checklist JavaScript SEO 2026
Niveau 1 : indispensable
- Rendering SSR ou SSG — HTML complet dans view-source
- title et meta description cote serveur — Jamais injectes en JS pur
- Liens via <a href> — Jamais via onClick JavaScript
- Robots.txt autorise les JS/CSS —
Allow: /*.js$et/*.css$ - 404 reels cote serveur — Pas de soft 404 client
Niveau 2 : performance
- LCP < 2.5s mobile — Mesure via PageSpeed Insights
- INP < 200ms — Hydration progressive ou partielle
- Bundle initial < 100 Ko gzipped — Code splitting agressif
- Edge SSR si possible — TTFB sous 100ms partout
Niveau 3 : GEO (moteurs IA)
- HTML brut riche — Tout le contenu visible sans JS
- FAQPage schema — JSON-LD dans le HTML SSR
- Robots.txt autorise GPTBot et PerplexityBot — Sinon zero citation
- Reponses directes en debut de H2 — LLMs extraient les 2 premieres phrases
FAQ : JavaScript SEO 2026
Googlebot execute-t-il vraiment JavaScript en 2026 ?
Oui, via le Web Rendering Service (WRS) base sur Chromium evergreen. Mais le rendu est differe (2-wave indexing) et limite par un budget de rendering.
CSR ou SSR : quel rendering choisir pour le SEO ?
SSR ou SSG sont fortement recommandes : le HTML complet est livre immediatement. CSR pur ralentit l'indexation de 2 a 7 jours et penalise le LCP.
Qu'est-ce que l'hydration et impacte-t-elle le SEO ?
L'hydration attache les listeners React/Vue/Angular au HTML pre-rendu. Elle ne touche pas le contenu indexe mais penalise lourdement l'INP (Core Web Vital).
Le Dynamic Rendering est-il toujours valide en 2026 ?
Oui, Google le considere comme une solution de contournement legitime pour les SPAs lourdes existantes. Prefere SSR pour un nouveau projet.
Comment savoir si Googlebot voit mon contenu JS ?
Utilise l'URL Inspection Tool de Google Search Console (onglet "View Tested Page" + "Screenshot"). Compare avec view-source: et le DOM rendu.
Conclusion : 3 priorites a appliquer cette semaine
1. Verifie view-source
Si ton contenu n'y apparait pas, migre vers SSR ou Dynamic Rendering.
2. Mesure INP mobile
PageSpeed Insights : si > 200ms, allege l'hydration (partial, progressive).
3. Ouvre aux IA
Sers HTML statique riche + autorise GPTBot/PerplexityBot dans robots.txt.
Ressources officielles
- Google Search Central — JavaScript SEO basics — Documentation officielle WRS
- web.dev — Rendering on the Web — Comparatif CSR/SSR/SSG par Google
- Next.js Rendering Docs — Strategies de rendering App Router
- Qwik — Resumability vs Hydration — Approche zero hydration
- Astro — Islands Architecture — Partial hydration