Guide JavaScript SEO

Comment assurez-vous moteur de recherches peut explorer, rendre, et indexer JavaScript-dependent contenu — réel liens, parity, lazy-loading, infinite scroll, soft-404s, et testing.

Première publication : 23 juin 2026 · Dernière mise à jour : 3 août 2026 · Avancé
1 indice probant sur cette page

JavaScript SEO est à propos de si moteur de recherches peut explorer, rendre, et indexer contenu que dépend on JavaScript. Google peut exécuter JS — le échec modes sont plus spécifique: parity (raw vs rendu), interaction (Google ne fait pas scroll or click), state (le renderer est stateless), et timing. Garder liens as réel anchors, ne pas bloquer JS/CSS, préférer SSR/prerendering pour contenu que doit classer, et watch infinite scroll — a tall rendre viewport peut obtenir deux pages indexé as un.

TL;DR — Google peut exécuter votre JavaScript, donc “peut Google lire JS?” est le incorrect question. Le échec modes sont parity (raw vs. rendu DOM), interaction (Google ne fait pas scroll or click), state (le renderer est stateless), et timing. Garder liens as réel <a href> anchors, ne pas bloquer JS/CSS, lazy-charger on viewport pas interaction, retourner réel statuses pour client-side 404s, et remember a raw noindex peut empêcher rendu avant JavaScript peut supprimer il. Combine directives que étaient en réalité processed, mais ne faites pas assume a universal raw/rendu winner. Watch infinite scroll surtout: a tall rendre viewport peut trigger le loader et merge deux URLs dans un indexé page. Pour le renderer internals et qui rendu mode à pick, voir rendu.

Peut Google lire JavaScript? Oui — c’est pas le question

Google peut exécuter votre JavaScript — le réel risques sont parity, interaction, state, et timing. Source : /technical-seo/javascript-seo/

Three stages exécuter left à correct: explorer, rendre, et indexer. Le rendre stage branches dans four échec modes: parity, où le rendu DOM peut pas match expectations; interaction, où contenu exige a scroll or click; state, où contenu relies on cookies or storage que le renderer clears; et timing, où contenu est deferred behind lent JavaScript.

© Patrick Stox LLC · CC BY 4.0 ·

«Google processes JavaScript apps in three phases: “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” The middle phase runs your JS in an evergreen, headless Chrome to build the DOM that gets indexed. “Rendering is important because websites often rely on JavaScript to bring content to the page, and without rendering Google might not see that content.”

Preuve à l’appui de cette affirmation Google processes JavaScript web apps in three main phases: crawling, rendering, and indexing; without rendering, Google might not see JavaScript-provided content. Portée : Google Search's processing of JavaScript pages; successful rendering does not guarantee indexing or ranking. Niveau de confiance : élevé · Vérifié : Google Search Central: Understand the JavaScript SEO basics

» (Traduction) (Résumé en français de la section vingt-deux, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«So Google can run your JavaScript. The useful questions are more specific: » (Traduction) (Résumé en français de la section vingt-trois, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«- Parity — does the rendered DOM actually contain what you think it does? » (Traduction) (Résumé en français de la section vingt-quatre, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.) «- Interaction — does anything require a scroll/click Google won’t perform? » (Traduction) (Résumé en français de la section vingt-quatre, sous-partie deux : le texte source est conservé pour vérification lors de la relecture francophone.) «- State — are you relying on cookies/localStorage the stateless renderer clears? » (Traduction) (Résumé en français de la section vingt-quatre, sous-partie trois : le texte source est conservé pour vérification lors de la relecture francophone.) «- Timing — is critical content deferred behind slow or late JavaScript? » (Traduction) (Résumé en français de la section vingt-quatre, sous-partie quatre : le texte source est conservé pour vérification lors de la relecture francophone.)

«On timing specifically: Google queues a crawled page (one that returned a 200) for rendering, and “the page may stay on this queue for a few seconds, but it can take longer than that.” There’s no published fixed delay or timeout — and a page that returns a non-200 status, or that starts out with a noindex directive, can skip the render queue rather than wait for JavaScript to change it.

Preuve à l’appui de cette affirmation Google queues crawled pages with a 200 response for rendering; the page may stay in that queue for a few seconds but can take longer, with no published fixed delay or timeout, and non-200 or initial noindex responses may skip rendering. Portée : Google Search's documented render-queue behavior; not a guaranteed or universal timing figure. Niveau de confiance : élevé · Vérifié : Google Search Central: Understand the JavaScript SEO basics

» (Traduction) (Résumé en français de la section vingt-cinq, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«The mechanics of how Google renders — the Web Rendering Service, statelessness, caching, the “two waves” myth — live on the rendering page. Here I’ll focus on the practical problems and fixes. » (Traduction) (Résumé en français de la section vingt-six, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«## Links must be real <a href> anchors » (Traduction) (Résumé en français de la section vingt-sept, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«This is the single most common JS-SEO bug. “Google can only discover your links if they are <a> HTML elements with an href attribute.” A clickable <div> with an onclick handler is invisible to Google as a link — it won’t be followed, and pages that depend on it for discovery can go uncrawled. It’s perfectly fine to inject links with JavaScript, as long as they end up as real <a href> anchors in the rendered DOM. Those rendered anchors are parsed after JavaScript runs, though — landing in the rendered DOM makes a link discoverable, it’s not a promise that the URL gets crawled, indexed, or treated the same as a link present in the raw HTML.

Preuve à l’appui de cette affirmation Google can reliably discover links only when they are HTML anchor elements with an href attribute. Portée : Link discovery by Google Search; this does not claim that every discovered URL will be crawled or indexed. Niveau de confiance : élevé · Vérifié : Google Search Central: Make your links crawlable

» (Traduction) (Résumé en français de la section vingt-huit, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«## Lazy-loaded and interaction-gated content » (Traduction) (Résumé en français de la section vingt-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«The renderer doesn’t behave like a curious user: “Google Search does not interact with your page.” No scrolling, no clicking, no hovering. So any content that only loads on one of those events won’t be seen. » (Traduction) (Résumé en français de la section trente, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Google’s guidance: charger contenu quand il enters le viewport, pas quand le utilisateur acts — “assurez-vous que votre lazy-loading implementation charge tout pertinent contenu whenever il est visible dans le viewport,” et “ne pas ajouter lazy-loading à contenu que est probable à être immédiatement visible quand a utilisateur opens une page.” Utiliser IntersectionObserver or native loading="lazy" pour images — jamais a scroll or click handler — donc le contenu charge during a normal rendre.

Preuve à l’appui de cette affirmation Google Search does not interact with a page, so lazy-loaded content should load when it becomes visible in the viewport rather than requiring user interaction. Portée : Google Search's documented rendering behavior for lazy-loaded content; other crawlers can behave differently. Niveau de confiance : élevé · Vérifié : Google Search Central: Fix lazy-loaded content

Infinite scroll: quand two pages obtenir indexé as un

Google's tall rendre viewport peut trigger an infinite-scroll loader et merge deux pages dans un indexé URL. Source : /technical-seo/javascript-seo/

A normal navigateur viewport arrête après le premier page, mais Google's rendre viewport expands beaucoup taller. Le expansion reaches an infinite-scroll trigger, fires le loader sans a réel utilisateur scroll, et appends le suivant page dans le même DOM. Google alors indexes les deux pages' contenu sous un URL.

© Patrick Stox LLC · CC BY 4.0 ·

Ce est le un presque nobody explique, et c’est worth le entier section.

Googlebot peut rendre à a viewport considerably taller que a typical navigateur window. Google ne fait pas publish an exact rendre viewport size — et il peut modifier — donc ne pas design contre a spécifique number; tester votre propre implementation à la place. Ce que matters est le mechanism: si votre infinite-scroll loader fires fondé on scroll position or viewport height, a taller-que-attendu rendu viewport peut trigger le loader during rendu itself — et le suivant article or produit page’s contenu obtient appended dans le même DOM. Maintenant deux distinct URLs’ contenu a été rendu ensemble, et Google peut indexer les as un page. Dans mon propre experience, “occasionally, deux pages obtenir indexé as un” — j’ai avait pages reported as “non indexée” que étaient en réalité indexé as partie de un autre page (généralement le previous post dans le feed), parce que “quand Google resized le viewport à être plus long … il triggered le infinite scroll et chargé un autre article dans quand il était rendu.” Confirmer si votre propre setup fait ce par checking Inspection d’URL’s rendu HTML pour une page vous’d expect à arrêter court — ne pas assume a size et ne pas assume vous êtes sûr.

Là are two layers to getting ce correct.

«Make infinite scroll search-friendly in the first place. Support paginated loading underneath the infinite scroll. Each chunk should have “its own persistent, unique URL,” the content on each URL should stay the same each time it loads, you should avoid relative parameters like ?date=yesterday, you should “link sequentially to the individual URLs so that search engines can discover the URLs in a paginated set,” and when a new chunk loads on scroll you should “update the displayed URL using the History API.” Use real <a href> pagination links and unique URLs — “don’t use URL fragment identifiers” (the part after a #) for page numbers, because Google ignores them. As I say in my JavaScript SEO guide, “if you have an infinite scroll setup, I still recommend a paginated page version so that Google can still crawl properly.” » (Traduction) (Résumé en français de la section trente-sept, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Si a buggy loader est actively merging pages, le fastest corriger est blunt: “bloquer le JavaScript fichier que handles le infinite scrolling donc le functionality ne peut pas trigger.” Si le loader ne peut pas exécuter during rendre, il ne peut pas append le suivant page’s contenu, et chaque URL renders as itself à nouveau.

Soft-404s après client-side routing

Unique-page apps peut swap contenu sans modification le code d’état HTTP, donc a “pas trouvé” view peut encore retourner 200. Google peut classify que réponse as a soft 404 après evaluating le renvoyé contenu, mais a static récupérer alone ne peut pas prove que Google a fait que classification. Deux corrections: navigate avec le History API, et pour a genuine pas-trouvé state soit route à a URL que renvoie a réel 404 status or ajouter a noindex balise. Et ne pas lean on URL fragments pour routing — “le AJAX-exploration scheme a été deprecated since 2015, donc vous pouvez’t rely on URL fragments à fonctionner avec Googlebot.”

A client-side redirection a le même evidence problème: le initial réponse peut remain 200 jusqu’à JavaScript exécute. Google prend en charge JavaScript redirections seulement as a fallback quand serveur-side or meta-refresh redirections ne sont pas possible. Rapport le static status et le observed rendu navigation séparément; ne faites pas rewrite le HTTP status dans le audit or appel chaque rendu URL modifier a redirection.

ne pas bloquer JavaScript or CSS dans robots.txt

Google ne va pas rendre JavaScript depuis bloqué fichiers or on bloqué pages. A robots.txt règle que disallows votre bundle (or le /_next/, /static/, /assets/ directory il lives dans) peut break rendu entirely — Google récupère le shell, ne peut pas exécuter le scripts, et indexes an vide page. Vérifier Inspection d’URL’s page resources pour n’importe quoi bloqué.

DOM parity et stage-aware robots directives

Comparer votre raw HTML (View Source) contre le rendu HTML (Inspection d’URL). Contenu que seulement exists dans le rendu HTML encore indexes — si il renders. Contenu dans aucun ne fait pas exist à Google.

il y a un stage-order risque Google documents directement: “Quand Google encounters le noindex balise, il peut skip rendu et JavaScript execution, qui signifie en utilisant JavaScript à modifier or supprimer le robots meta balise depuis noindex peut pas fonctionner as attendu.” Si votre raw HTML ships an initial noindex vous meant à swap out avec JavaScript, Google peut act on que raw noindex et jamais exécuter le script que voudrait ont supprimé il.

Ne faites pas turn ce into a universal “rendered wins” rule. Reconciliation is field-specific:

«| Field | What the raw/rendered comparison can establish | | --- | --- | | Main content and links | Google can use content and real <a href> links produced during rendering if rendering succeeds. Raw availability reduces that dependency. | | Title and description | Google can process JavaScript-set metadata, but title links and snippets are selected from several sources. Show both states; do not claim the rendered, first, or last value is guaranteed. | | Robots directives | A raw noindex may cause Google to skip rendering, so JavaScript removal may never be seen. Adding restrictions later is not evidence that an earlier restriction was cancelled. | | Canonical | Google’s JavaScript guidance says not to set one value in source and then change it with JavaScript. Use one method and verify one rendered-head declaration. | | HTTP status and redirect | JavaScript cannot change the response status already received. Record the static status and any observed rendered navigation as separate facts. | » (Traduction) (Résumé en français de la section quarante-huit, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Que matrix est pourquoi an auditor devrait garder source, rendu, réponse-header, et observed-recherche state distinct plutôt que collapsing les dans un “effective” valeur.

Pick a rendering mode que puts content in the DOM

La plupart JS-SEO risque comes bas à comment le HTML est produced. La version courte: SSR, static/prerendering, et hydration tout put contenu dans (or quickly dans) le DOM, qui reduces comment beaucoup votre visibility dépend on le renderer succeeding; complet client-side rendu laisse plus riding on rendu completing correctement, on temps, chaque temps. Dynamic rendu est a workaround, pas a peer option — as de Google’s guidance dernier mis à jour December 2025, il décrit dynamic rendu as a workaround plutôt que a à long terme solution et recommends rendu côté serveur, static rendu, or hydration à la place. As Je put il dans mon JavaScript SEO guide, “quelconque kind de SSR, static rendu, et prerendering setup est going à être fine pour moteur de recherches.” Le complet menu — CSR, SSR, SSG, hydration, ISR, edge, streaming, et dynamic rendu — avec a trade-off tableau est on le rendu page. Google séparément décrit rendu côté serveur or pre-rendu as a bon idea pour utilisateurs et robots d’exploration. Preuve à l’appui de cette affirmation Google describes server-side rendering or pre-rendering as a good idea because it makes a website faster for users and crawlers. Portée : Google Search guidance for JavaScript sites; the source does not prescribe one framework or guarantee indexing. Niveau de confiance : élevé · Vérifié : Google Search Central: Understand the JavaScript SEO basics

Comment tester

Inspection d’URL dans Search Console est le source de truth: exécuter a actif tester, alors regarder à le rendu HTML, le screenshot, et le page resources / console messages à voir ce que chargé et ce que failed. Le Résultats enrichis Tester donne a rapide rendu-HTML vérifier. À scale, utiliser a robot d’exploration que executes JavaScript (Ahrefs Site Audit, Screaming Frog dans JS-rendu mode) à diff raw vs. rendu à travers le site.

A render diff is diagnostic, pas a score: investigate essential elements que apparaître seulement après JavaScript—or disappear après rendering.

An illustrative page a 1 titre dans les deux raw et rendu HTML, 18 titres dans raw HTML et 19 rendu, 42 lien internes dans raw HTML et 71 rendu, 0 produit descriptions dans raw HTML et 12 rendu, et 6 balise canonicals dans raw HTML mais seulement 1 rendu. Ces counts sont synthetic.

JavaScript n’est pas mauvais pour le SEO, et c’est pas evil. c’est simplement différent depuis ce que nombreux SEOs sont utilisé à. Fonctionner avec votre developers, obtenir votre important contenu dans le DOM, et let Google’s propre outils — pas votre assumptions — être le arbiter de ce que rendu.

Où to go suivant: the JavaScript SEO cluster

Ce hub is the map. Chaque topic ci-dessous is its propre deep dive:

Rendu et architecture

  • SEO pour a CMS headless — comment decoupled frontends affecter exploration, rendu, metadata, sitemaps, et balise canonicals; qui rendu mode à pick; et le headless-spécifique échec modes vous devez know.

«Framework-specific guides » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.) «- React SEO — why CSR-first React creates indexing risk, how Google renders React apps, React Router and History API, react-helmet-async for meta tags, and when to reach for Next.js. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie deux : le texte source est conservé pour vérification lors de la relecture francophone.) «- Angular SEO — Angular’s SPA defaults, @angular/ssr (Angular Universal’s successor), the built-in Title and Meta services, prerendering, and incremental hydration in modern Angular. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie trois : le texte source est conservé pour vérification lors de la relecture francophone.) «- Next.js SEO — Pages Router vs App Router, the Metadata API, next/image and CWV, ISR timing and Googlebot, sitemaps, and the most common Next.js SEO mistakes. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie quatre : le texte source est conservé pour vérification lors de la relecture francophone.) «- Nuxt SEO — SSR by default, useSeoMeta(), Nuxt’s rendering modes, the @nuxtjs/seo module ecosystem, and how Nuxt compares to plain Vue for indexability. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie cinq : le texte source est conservé pour vérification lors de la relecture francophone.) «- Vue SEO — Vue 3’s CSR default and what that means for crawlers, createWebHistory(), @unhead/vue, prerendering options without a meta-framework, and when Nuxt is the right call. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie six : le texte source est conservé pour vérification lors de la relecture francophone.) «- Svelte SEO — Svelte vs SvelteKit, SSR by default in SvelteKit, <svelte:head>, the adapter-static + ssr: false trap, adapter choices, and AI crawler implications. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie sept : le texte source est conservé pour vérification lors de la relecture francophone.) «- Astro SEO — zero-JS by default, islands architecture, @astrojs/sitemap, astro:assets, View Transitions and History API, Server Islands fallback behavior, and Astro’s Core Web Vitals advantages. » (Traduction) (Résumé en français de la section cinquante-neuf, sous-partie huit : le texte source est conservé pour vérification lors de la relecture francophone.)

Ajouter une note d’expert

Épingler une citation d’expert

Nouvelle personne ? Créez son profil non revendiqué à /admin/experts/ → Épingler une citation d’expert d’abord.