JavaScript SEO: what a crawler actually sees
Client-rendered content is not automatically invisible, and server-rendered content is not automatically visible. The gap between what a browser shows and what a crawler receives has to be measured, and then closed at the layer that caused it.
Rendering failures present as indexation failures
When content depends on client-side execution, the symptom is usually a page that exists, is linked, is not blocked and does not rank. That reads as an indexing problem and is frequently worked as one, while the actual fault is that the crawler receives a document containing none of the content the page is about. Establishing this takes a comparison rather than a diagnosis; resolving it takes an application change rather than an SEO one.
- Content visible in a browser that does not appear in the crawled HTML
- A framework migration after which organic visibility fell and never returned
- Metadata that differs between the served document and the rendered page
- Internal links that resolve only after JavaScript executes
- Indexed pages whose titles and descriptions come from the application shell
- Correct behaviour in testing and different behaviour when the crawler arrives
The people who usually bring us this problem
CTO / VP Engineering
An SEO problem has been escalated to you and the answer depends on rendering architecture. You need the trade-offs stated as engineering decisions rather than as an SEO requirement.
Head of SEO / SEO Director
You suspect client-side rendering and cannot prove it. You need a rendering comparison that identifies exactly which content and which links are affected.
Head of Product
You are choosing or have chosen a front-end approach and need to know what it costs in discoverability, before it is expensive to change.
What this costs while it goes unfixed
Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.
Content investment with no discoverable surface
Content that never reaches the crawler cannot rank, and the spend behind it produces nothing. The failure is invisible from inside the CMS because the pages look correct to everyone editing them.
Rendering changes are cheaper before a migration than after
Choosing the rendering model is a decision with search consequences. Discovering those consequences once traffic has fallen means re-architecting under pressure.
Second-order effects get mistaken for separate problems
Metadata, internal link equity, canonical resolution and pagination all behave differently under client-side rendering. They surface as a cluster of unrelated faults rather than as one cause.
Capabilities
Each of these is work we carry out, not an area we advise on.
Crawler-versus-browser comparison
Fetching pages as a crawler receives them and comparing against the rendered result — which content, which links and which metadata differ, established rather than inferred.
Rendering strategy assessment
Which of server-side rendering, static generation, incremental generation, pre-rendering or client-side hydration suits the site's content and update model — and what each costs.
Metadata and canonical correctness
Titles, descriptions, canonicals, hreflang and structured data that are generated at the right time, in the document, rather than injected after execution.
Internal link crawlability
Navigation and pagination that resolve to crawlable anchors in the served HTML, so link discovery does not depend on execution completing.
Hydration and content-parity faults
Content that changes on hydration, differs between server and client renders, or depends on a fetch that a crawler will not complete.
Framework-specific remediation
Practical fixes within the framework already in use rather than a proposed replatform — the rendering model is usually adjustable without replacing the stack.
Engineering methodology
The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.
Measure before recommending
The comparison is run first and produces a list of specific differences. Rendering advice given before that step is guesswork, and the guess is wrong often enough that it is worth the fetch.
Fix at the layer that caused it
If metadata is injected client-side, the fix belongs in the rendering path, not in a plugin that patches the output. Patching symptoms across a large estate leaves the next new template broken in the same way.
Prefer the smallest sufficient change
A full SSR replatform is a large answer to a problem that frequently has a smaller one — server-rendering the templates that matter, or moving a specific fetch to the server. The heaviest option is proposed when it is genuinely the only one.
Preserve what already works
Client-side rendering is not a defect in itself, and interactive parts of a site are often better left alone. The target is a document that carries the content and links, not the removal of JavaScript.
Verify against the crawler, not the browser
Every change is checked by re-fetching as a crawler rather than by opening the page. A fix confirmed in a browser has not been confirmed at all.
What an engagement produces
Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.
Diagnosis
- Crawler-versus-browser content comparison, per template
- Affected metadata, canonical and hreflang inventory
- Internal link reachability analysis in served HTML
- Rendering-model assessment with cost per option
Remediation
- Server-side or pre-rendering for affected templates
- Metadata generation moved into the served document
- Crawlable navigation and pagination markup
- Framework-level changes alongside the client's engineers
Verification
- Re-fetch comparison confirming parity
- Indexation monitoring per template
- Checks that new templates inherit the fix rather than repeating the fault
Architecture and technology
Rendering path
- Where content is generated: build, server or client
- Metadata emission point
- Link markup in the served document
- Data dependencies that must resolve without execution
Governance
- Template review before launch
- Automated crawler-parity check in CI where feasible
- Documentation of which templates render how, and why
If this is not quite your problem
These overlap at the edges. Sending you to the right page is more useful than having you work it out.
Pages render correctly and are still not indexed
See Crawl and Indexation. Rendering is one of four possible causes, and it is worth ruling the other three out before changing the architecture.
Organic visibility fell after a platform or framework change
See Website Migrations, which covers the wider set of causes a migration can introduce.
Frequently asked
Have you done this on an engagement you can show?
We can demonstrate the rendering comparison and crawl-path analysis on your own stack during discovery. That gives you a concrete view of the problem before committing to implementation.
Do we need to move to server-side rendering?
Usually not as a whole. Most sites need the content-bearing templates to render server-side while interactive areas stay client-side. A full replatform is occasionally correct, but it is a large answer to what is often a local problem, and it carries its own migration risk — which is its own way of losing organic visibility.
Which frameworks does this apply to?
Any that render on the client: React and Next.js, Vue and Nuxt, Angular, and any single-page application. The rendering comparison is framework-agnostic because it measures the served document, and the remedies differ by framework but the diagnosis does not.
Does Google not render JavaScript anyway?
It does, and that is why the situation is more nuanced than "JavaScript content is invisible". Rendering is deferred, sometimes unreliable, and the second pass it depends on is not guaranteed on a schedule you control. The practical consequence is that client-rendered content is discovered later and less completely — which for time-sensitive content is equivalent to not being discovered at all.
Related capabilities and work
Bring us the problem you have not been able to fix
Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.