Guide JavaScript SEO

How to assurez-vous moteur de recherches peut explorer, render, and index JavaScript-dependent content — réel liens, parity, lazy-loading, infinite scroll, soft-404s, and testing.

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

JavaScript SEO is à propos de si moteur de recherches peut explorer, render, and index content que dépend on JavaScript. Google peut run JS — the échec modes are plus spécifique: parity (raw vs rendered), interaction (Google doesn't scroll or click), state (the renderer is stateless), and timing. Garder liens as réel anchors, don't block JS/CSS, préférer SSR/prerendering pour content que doit rank, and watch infinite scroll — a tall render viewport peut obtenir two pages indexé as un.

TL;DR — Google peut run votre JavaScript, so “can Google read JS?” is the incorrect question. The échec modes are parity (raw vs. rendered DOM), interaction (Google doesn’t scroll or click), state (the renderer is stateless), and timing. Garder liens as réel <a href> anchors, don’t block JS/CSS, lazy-load on viewport pas interaction, retourner réel statuses pour client-side 404s, and remember a raw noindex may prevent rendering avant JavaScript peut supprimer it. Combine directives que were en réalité processed, but ne faites pas assume a universal raw/rendered winner. Watch infinite scroll surtout: a tall render viewport peut trigger the loader and merge two URLs into un indexé page. Pour the renderer internals and qui rendering mode to pick, voir rendering.

Peut Google lire JavaScript? Yes — that’s pas the question

Google can run your JavaScript — the real risks are parity, interaction, state, and timing. Source : /technical-seo/javascript-seo/

Three stages run left to right: crawl, render, and index. The render stage branches into four failure modes: parity, where the rendered DOM may not match expectations; interaction, where content requires a scroll or click; state, where content relies on cookies or storage that the renderer clears; and timing, where content is deferred behind slow JavaScript.

© Patrick Stox LLC · CC BY 4.0 ·

Google processes JavaScript apps in three phases: “Google processes JavaScript web apps in three principal phases: 1. Exploration 2. Rendering 3. Indexation.” The middle phase runs votre JS in an evergreen, headless Chrome to construire the DOM que obtient indexé. “Rendering is important parce que websites souvent rely on JavaScript to bring content to lune page, and sans rendering Google pourrait pas voir que content.”

Evidence for this claim Google processes JavaScript web apps in three main phases: crawling, rendering, and indexing; without rendering, Google might not see JavaScript-provided content. Scope: Google Search's processing of JavaScript pages; successful rendering does not guarantee indexing or ranking. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

So Google peut run votre JavaScript. The utile questions are plus spécifique:

  • Parity — fait the rendered DOM en réalité contain ce que vous think it fait?
  • Interaction — fait anything exiger a scroll/click Google won’t perform?
  • State — are vous relying on cookies/localStorage the stateless renderer clears?
  • Timing — is critical content deferred behind slow or late JavaScript?

On timing specifically: Google queues a crawled page (un que renvoyé a 200) pour rendering, and “lune page may stay on ce queue pour a few seconds, but it peut prendre plus long que que.” There’s aucun publié fixed delay or timeout — and une page que renvoie a non-200 status, or que starts out with a noindex directive, peut skip the render queue plutôt que wait pour JavaScript to modifier it.

Evidence for this claim 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. Scope: Google Search's documented render-queue behavior; not a guaranteed or universal timing figure. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

The mechanics of how Google renders — the Web Rendering Service, statelessness, mise en cache, the “two waves” myth — live on the rendering page. Ici I’ll focus on the practical problems and fixes.

Liens doit be réel <a href> anchors

Ce is the unique la plupart courant JS-SEO bug. “Google peut seulement découvrir votre liens si ils are <a> HTML elements with an href attribute.” A clickable <div> with an onclick handler is invisible to Google as a lien — it won’t be followed, and pages que depend on it pour discovery peut go uncrawled. It’s perfectly fine to inject liens with JavaScript, tant que ils fin up as réel <a href> anchors in the rendered DOM. Ceux rendered anchors are parsed après JavaScript runs, though — landing in the rendered DOM rend a lien discoverable, it’s pas a promise que the URL obtient crawled, indexé, or treated the même as a lien présent in the raw HTML.

Evidence for this claim Google can reliably discover links only when they are HTML anchor elements with an href attribute. Scope: Link discovery by Google Search; this does not claim that every discovered URL will be crawled or indexed. Confidence: high · Verified: Google Search Central: Make your links crawlable

Lazy-loaded and interaction-gated content

The renderer doesn’t behave comme a curious utilisateur: “Recherche Google ne fait pas interact with votre page.” Aucun scrolling, aucun clicking, aucun hovering. So quelconque content que seulement loads on un of ceux events won’t be seen.

Google’s guidance: charger content quand it enters the viewport, pas quand the utilisateur acts — “assurez-vous que votre lazy-loading implementation loads tout relevant content whenever it is visible in the viewport,” and “don’t ajouter lazy-loading to content que is probable to be immédiatement visible quand a utilisateur opens une page.” Utiliser IntersectionObserver or native loading="lazy" pour images — jamais a scroll or click handler — so the content loads during a normal render.

Evidence for this claim 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. Scope: Google Search's documented rendering behavior for lazy-loaded content; other crawlers can behave differently. Confidence: high · Verified: Google Search Central: Fix lazy-loaded content

Infinite scroll: quand two pages obtenir indexé as un

Google's tall render viewport can trigger an infinite-scroll loader and merge two pages into one indexed URL. Source : /technical-seo/javascript-seo/

A normal browser viewport stops after the first page, but Google's render viewport expands much taller. The expansion reaches an infinite-scroll trigger, fires the loader without a real user scroll, and appends the next page into the same DOM. Google then indexes both pages' content under one URL.

© Patrick Stox LLC · CC BY 4.0 ·

Ce is the un almost nobody explique, and it’s worth the whole section.

Googlebot peut render at a viewport considerably taller que a typical navigateur window. Google doesn’t publish an exact render viewport size — and it peut modifier — so don’t design contre a spécifique number; tester votre propre implementation à la place. Ce que matters is the mechanism: si votre infinite-scroll loader fires fondé on scroll position or viewport height, a taller-than-expected rendering viewport peut trigger the loader during rendering itself — and the suivant article or product page’s content obtient appended into the même DOM. Now two distinct URLs’ content has been rendered ensemble, and Google peut index les as un page. In my propre experience, “occasionally, two pages obtenir indexé as un” — I’ve had pages reported as “non indexée” que were en réalité indexé as partie of un autre page (usually the previous post in the feed), parce que “quand Google resized the viewport to be plus long … it triggered the infinite scroll and chargé un autre article in quand it was rendering.” Confirmer si votre propre setup fait ce by checking Inspection d’URL’s rendered HTML pour une page you’d expect to arrêter short — don’t assume a size and don’t assume you’re safe.

Là are two layers to getting ce correct.

Faire infinite scroll search-friendly in the premier placer. Prise en charge paginated chargement underneath the infinite scroll. Chaque chunk devrait have “its propre persistent, unique URL,” le contenu on chaque URL devrait stay the même chaque temps it loads, vous devez éviter relative parameters comme ?date=yesterday, vous devez “lien sequentially to the individual URLs so que moteur de recherches peut découvrir l’URLs in a paginated définir,” and quand a nouveau chunk loads on scroll vous devez “mettre à jour the affiché URL en utilisant the History API.” Use real <a href> pagination links and unique URLs — “don’t utiliser URL fragment identifiers” (the partie après a #) pour page numbers, parce que Google ignores les. As I dire in my JavaScript SEO guide, “si vous have an infinite scroll setup, I encore recommend a paginated page version so que Google peut encore explorer correctement.”

Si a buggy loader is actively merging pages, the fastest fix is blunt: “block the JavaScript fichier que handles the infinite scrolling so the functionality can’t trigger.” Si the loader can’t run during render, it can’t append the suivant page’s content, and chaque URL renders as itself à nouveau.

Soft-404s après client-side routing

Single-page apps peut swap content sans modification le code d’état HTTP, so a “not found” view peut encore retourner 200. Google may classify que réponse as a soft 404 après evaluating the renvoyé content, but a static récupérer alone ne peut pas prove que Google has made que classification. Two fixes: navigate with the History API, and pour a genuine not-found state soit route to a URL que renvoie a réel 404 status or ajouter a noindex tag. And don’t lean on URL fragments pour routing — “the AJAX-crawling scheme has been deprecated since 2015, so vous pouvez’t rely on URL fragments to fonctionner with Googlebot.”

A client-side redirection has the même evidence problem: the initial réponse peut remain 200 jusqu’à JavaScript runs. Google supports JavaScript redirections seulement as a fallback quand server-side or meta-refresh redirections ne sont pas possible. Report the static status and the observed rendered navigation separately; ne faites pas rewrite the HTTP status in the audit or appel every rendered URL modifier a redirection.

Don’t block JavaScript or CSS in robots.txt

Google won’t render JavaScript from blocked fichiers or on blocked pages. A robots.txt rule que disallows votre bundle (or the /_next/, /static/, /assets/ directory it lives in) peut break rendering entirely — Google récupère the shell, can’t run the scripts, and indexes an vide page. Vérifier Inspection d’URL’s page resources pour anything blocked.

DOM parity and stage-aware robots directives

Comparer votre raw HTML (View Source) contre the rendered HTML (Inspection d’URL). Content que seulement exists in the rendered HTML encore indexes — si it renders. Content in neither doesn’t exist to Google.

There’s un stage-order risk Google documents directement: “Quand Google encounters the noindex tag, it may skip rendering and JavaScript execution, qui signifie en utilisant JavaScript to modifier or supprimer the robots meta tag from noindex may pas fonctionner as attendu.” Si votre raw HTML ships an initial noindex vous meant to swap out with JavaScript, Google peut act on que raw noindex and jamais run the script que voudrait have supprimé it.

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

FieldCe que the raw/rendered comparison peut establish
Principal content and liensGoogle peut utiliser content and réel <a href> liens produced during rendering si rendering succeeds. Raw availability reduces que dependency.
Title and descriptionGoogle peut traiter JavaScript-set metadata, but title liens and snippets are selected from several sources. Montrer les deux states; ne faites pas claim the rendered, premier, or dernier valeur is guaranteed.
Robots directivesA raw noindex may causer Google to skip rendering, so JavaScript removal may jamais be seen. Ajout restrictions plus tard n’est pas evidence que an précédent restriction was cancelled.
CanonicalGoogle’s JavaScript guidance dit pas to définir un valeur in source and alors modifier it with JavaScript. Utiliser un méthode and vérifier un rendered-head declaration.
HTTP status and redirectionJavaScript ne peut pas modifier la réponse status déjà reçu. Record the static status and quelconque observed rendered navigation as separate facts.

Que matrix is pourquoi an auditor devrait garder source, rendered, response-header, and observed-search state distinct plutôt que collapsing les into un “effective” valeur.

Pick a rendering mode que puts content in the DOM

La plupart JS-SEO risk comes bas to how the HTML is produced. La version courte: SSR, static/prerendering, and hydration tout put content in (or quickly into) the DOM, qui reduces how beaucoup votre visibility dépend on the renderer succeeding; complet client-side rendering leaves plus riding on rendering completing correctement, on temps, every temps. Dynamic rendering is a workaround, pas a peer option — as of Google’s guidance dernier mis à jour December 2025, it describes dynamic rendering as a workaround plutôt que a long-term solution and recommends rendu côté serveur, static rendering, or hydration à la place. As I put it in my JavaScript SEO guide, “quelconque kind of SSR, static rendering, and prerendering setup is going to be fine pour moteur de recherches.” The complet menu — CSR, SSR, SSG, hydration, ISR, edge, streaming, and dynamic rendering — with a trade-off table is on the rendering page. Google separately describes rendu côté serveur or pre-rendering as a bon idea pour utilisateurs and robots d’exploration. Evidence for this claim Google describes server-side rendering or pre-rendering as a good idea because it makes a website faster for users and crawlers. Scope: Google Search guidance for JavaScript sites; the source does not prescribe one framework or guarantee indexing. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

Comment tester

Inspection d’URL in Search Console is the source of truth: run a live tester, alors regarder at the rendered HTML, the screenshot, and the page resources / console messages to voir ce que chargé and ce que failed. The Résultats enrichis Tester donne a rapide rendered-HTML vérifier. At scale, utiliser a robot d’exploration que executes JavaScript (Ahrefs Site Audit, Screaming Frog in JS-rendering mode) to diff raw vs. rendered à travers le site.

A render diff is diagnostic, not a score: investigate essential elements that appear only after JavaScript—or disappear after rendering.

An illustrative page has 1 title in both raw and rendered HTML, 18 headings in raw HTML and 19 rendered, 42 internal links in raw HTML and 71 rendered, 0 product descriptions in raw HTML and 12 rendered, and 6 canonical tags in raw HTML but only 1 rendered. These counts are synthetic.

JavaScript n’est pas bad pour le SEO, and it’s pas evil. It’s simplement différent from ce que nombreux SEOs are utilisé to. Fonctionner with votre developers, obtenir votre important content into the DOM, and let Google’s propre outils — pas votre assumptions — be the arbiter of ce que rendered.

Où to go suivant: the JavaScript SEO cluster

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

Rendering and architecture

  • SEO pour a CMS headless — how decoupled frontends affecter exploration, rendering, metadata, sitemaps, and balise canonicals; qui rendering mode to pick; and the headless-specific échec modes vous devez know.

Framework-specific guides

  • React SEO — pourquoi CSR-first React creates indexation risk, how Google renders React apps, React Router and History API, react-helmet-async pour meta tags, and quand to reach pour Suivant.js.
  • 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.
  • Suivant.js SEO — Pages Router vs App Router, the Metadata API, next/image and CWV, ISR timing and Googlebot, sitemaps, and the la plupart courant Suivant.js SEO mistakes.
  • Nuxt SEO — SSR by par défaut, useSeoMeta(), Nuxt’s rendering modes, the @nuxtjs/seo module ecosystem, and how Nuxt compares to plain Vue pour indexability.
  • Vue SEO — Vue 3’s CSR par défaut and ce que que signifie pour robots d’exploration, createWebHistory(), @unhead/vue, prerendering options sans a meta-framework, and quand Nuxt is the correct appel.
  • Svelte SEO — Svelte vs SvelteKit, SSR by par défaut in SvelteKit, <svelte:head>, the adapter-static + ssr: false trap, adapter choices, and AI robot d’exploration implications.
  • Astro SEO — zero-JS by par défaut, islands architecture, @astrojs/sitemap, astro:assets, View Transitions and History API, Server Islands fallback behavior, and Astro’s Core Web Vitals advantages.

Add an expert note

Pin an expert quote

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