DomainLens

Guides

JavaScript SEO: Why Google Might Not See Your Content

Google renders JavaScript — that is settled. What is not settled is whether it renders yours in time, completely, and before deciding what the page is about.

Vérifiez votre site avant de corriger

Lancez un audit DomainLens frais et utilisez le rapport comme liste de priorités.

Lancer un audit SEO gratuit

Rendering happens in two passes

Googlebot fetches the HTML first and indexes what is there. Rendering — executing the JavaScript to see the final DOM — happens later, from a queue, when resources allow. The gap between the two used to be days; it is usually much shorter now, but it is still a gap.

The consequence is that anything only present after JavaScript runs is discovered later than everything in the initial HTML, and only if rendering completes successfully. For a page whose entire body is client-rendered, the first pass sees an empty shell.

In the initial HTMLOnly after renderRisk
Title, canonical, robots metaInjected by scriptMay be missed or applied late
Body contentFetched client-sideIndexed empty on the first pass
Internal links with hrefBuilt by a routerDiscovery is delayed or lost
Structured dataInjected by a tag managerFrequently not seen
Status coden/a — always server-sideSoft 404 if the shell returns 200

What actually breaks

The blocked-resource case is the one people miss, because the page works perfectly in a browser that is not subject to your robots.txt. A disallowed /api/ path is invisible locally and fatal for rendering.

  • Links rendered as clickable divs or buttons with no href — a crawler has nothing to follow.
  • Content behind an interaction: tabs, accordions or "load more" that require a click.
  • A canonical or robots tag written by JavaScript, which may be evaluated after the decision is made.
  • Routes that return 200 with an app shell for URLs that do not exist, producing unbounded soft 404s.
  • Blocked resources: a script or API the crawler cannot fetch means the render produces nothing.

How to check what Google actually sees

  1. 1Fetch the URL with curl and read the raw HTML — that is the first pass, before any JavaScript.
  2. 2Compare it against the rendered DOM in your browser's inspector. The difference is what depends on rendering.
  3. 3Run URL Inspection in Search Console and open "View crawled page" to see Google's rendered HTML.
  4. 4Check the page resources list there for anything that failed to load.
  5. 5Read the JavaScript console messages Google reports; a runtime error mid-render truncates everything after it.
The first-pass view
# What Googlebot indexes before rendering
curl -s https://example.com/page | head -c 2000

# Is the main content there, or just a shell?
curl -s https://example.com/page | grep -c '<div id="root"></div>'

# Are the links real anchors?
curl -s https://example.com/page | grep -oE '<a [^>]*href="[^"]+"' | head

# Did the canonical survive into the served HTML?
curl -s https://example.com/page | grep -oE '<link[^>]+canonical[^>]*>'

The rendering strategies, ranked by risk

Hydration mismatch deserves its own mention: when the server HTML and the client render disagree, frameworks may discard the server output and rebuild. The crawler can catch either version, so the page becomes non-deterministic.

StrategyWhat the first pass seesVerdict
Static generationEverythingSafest
Server-side renderingEverythingSafe
Hydration on top of SSREverythingSafe if hydration matches
Client-side renderingAn empty shellDepends entirely on the render pass
Dynamic renderingEverything, for botsWorks; Google calls it a workaround

What to fix first

Render the title, canonical and robots directives server-side, always — they decide indexing and must not wait for a script. Then make links real anchors with href attributes. Then get the main content into the initial HTML. Those three cover almost every JavaScript SEO failure worth fixing. For framework specifics see the React checklist , the Next.js checklist and Vue SPA SEO checklist .

How DomainLens contributes

DomainLens reads the served HTML — the same first pass Googlebot indexes — and reports whether the title, canonical, robots directives, content and links are present in it. A page that looks complete in a browser and empty in the audit has told you exactly where the problem is. See crawlable links and indexability for the link half of it.

Does Google index JavaScript content?
Yes, after a second rendering pass. The risk is not whether it can, but whether your content survives that pass intact and in time.
Is client-side rendering bad for SEO?
It is riskier rather than forbidden. Everything depends on the render pass completing, so any blocked resource or runtime error costs you the whole page.
How do I know if rendering is my problem?
Fetch the URL with curl. If the main content, canonical and links are absent from that output but present in your browser, rendering is the dependency.
Is dynamic rendering still acceptable?
It works and Google supports it, but it is described as a workaround rather than a recommendation. Server-side rendering or static generation is the durable answer.

Vérifiez-le sur votre site

Ressources associées