Гайди
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.
Запусти свіжий аудит DomainLens і використовуй звіт як список пріоритетів.
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 HTML | Only after render | Risk |
|---|---|---|
| Title, canonical, robots meta | Injected by script | May be missed or applied late |
| Body content | Fetched client-side | Indexed empty on the first pass |
| Internal links with href | Built by a router | Discovery is delayed or lost |
| Structured data | Injected by a tag manager | Frequently not seen |
| Status code | n/a — always server-side | Soft 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
- 1Fetch the URL with curl and read the raw HTML — that is the first pass, before any JavaScript.
- 2Compare it against the rendered DOM in your browser's inspector. The difference is what depends on rendering.
- 3Run URL Inspection in Search Console and open "View crawled page" to see Google's rendered HTML.
- 4Check the page resources list there for anything that failed to load.
- 5Read the JavaScript console messages Google reports; a runtime error mid-render truncates everything after it.
# 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.
| Strategy | What the first pass sees | Verdict |
|---|---|---|
| Static generation | Everything | Safest |
| Server-side rendering | Everything | Safe |
| Hydration on top of SSR | Everything | Safe if hydration matches |
| Client-side rendering | An empty shell | Depends entirely on the render pass |
| Dynamic rendering | Everything, for bots | Works; 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.