ssrchecker
HomeLearnJavaScript SEO

JavaScript SEO: how rendering decides whether you get indexed

Short answer
Search engines can execute JavaScript, but they do it in a second pass that may be delayed or skipped. Content that only exists after JavaScript runs is therefore indexed slowly, partially, or not at all. Serving complete HTML on the first request removes that risk entirely.

This is the whole of JavaScript SEO in one sentence, and almost every specific problem below is a variation of it. The rest of this guide is about recognising which variation you have and what to do about it.

It matters more now than it did five years ago, not less. Google has been rendering JavaScript since 2019 and does it well. But the crawlers that increasingly decide whether your content gets surfaced — the ones behind AI answers and chat assistants — largely do not render at all. A site that squeaked by on Google's patience is now invisible to a growing share of the traffic that matters.

How search engines actually crawl a page

Indexing a JavaScript page happens in two separate passes, often days or weeks apart. Understanding the split explains nearly every symptom in this guide. If you want the mechanics in depth — the render queue, the timeouts, what decides your place in line — the dedicated guide on how Googlebot renders JavaScript covers only that.

01
First pass — crawl
The crawler requests the URL and receives raw HTML. No JavaScript runs. It reads the title, meta tags, links and text that are physically present in that response, then queues any links it found. If your page is an empty shell, this pass finds an empty shell.
02
Second pass — render
At some later point the URL enters a rendering queue. A headless browser loads it, executes JavaScript, waits for the DOM to settle, and the result is indexed. This pass is where client-rendered content finally becomes visible — if the page gets that far.

The gap between the two passes is the entire problem. Rendering is expensive — a headless browser per URL, at the scale of the web — so it is rationed. Pages compete for it, and a page that looks empty and low-value on the first pass competes badly.

This is also why the failure is so confusing to diagnose. Your page eventually gets indexed, so nothing looks broken. It just took six weeks, and your competitor's server-rendered equivalent took two days. Multiply that across a catalogue of ten thousand URLs and the compounding difference is enormous.

Diagram showing the two-pass crawling process: initial crawl of raw HTML, then a delayed render queue where JavaScript executes
The render queue is where client-rendered content waits. Some of it waits a long time.

The five rendering modes, and which are safe

Almost every framework offers several of these, often per route. The names differ but the underlying question is always the same: is the HTML complete when it leaves the server? If the CSR-versus-SSR distinction is the part you're shaky on, the SSR vs CSR guide is the one-page version.

ModeNameWhat happensFor SEO
CSRClient-side renderingBrowser builds the page from JavaScript. Raw HTML is a near-empty shell.Risky
SSRServer-side renderingServer builds the HTML per request. Complete on arrival.Safe
SSGStatic site generationHTML built once at deploy time and served as files.Safe
ISRIncremental regenerationStatic pages rebuilt on a schedule or on demand.Safe
HybridMixedShell rendered server-side, key content fetched client-side.Usually a bug

The important and frequently missed point: SSR, SSG and ISR are equivalent for SEO. All three deliver complete HTML on the first request. Choosing between them is a question of data freshness and infrastructure cost, not of rankings — the SSR vs SSG vs ISR guide works through that tradeoff. If someone proposes migrating from static generation to server rendering for SEO reasons, that is not a rendering fix and it will make your pages slower to serve.

One term the table doesn't name because it isn't a rendering mode at all: hydration. That is the step where the browser attaches JavaScript to already-rendered HTML to make it interactive, and it has its own failure mode — a mismatch that can blank a page that looked perfect in the raw HTML. The hydration guide explains where it breaks.

Why JavaScript sites fail to index

So does JavaScript hurt SEO? Not in itself — plenty of JavaScript sites rank perfectly. It hurts when it moves content out of the first-pass HTML, and it does that through four distinct mechanisms, worth separating because they need different fixes.

01
The render never happens
A page that looks empty on the first pass is a poor candidate for expensive rendering. Search Console reports this as “Discovered — currently not indexed”: the URL is known, and rendering it was not judged worthwhile.
02
The render happens but times out
Rendering has time limits. A page making sequential API calls, or waiting on a slow third-party script, can be captured mid-load with the content still absent.
03
Links only exist after JavaScript
Crawlers follow links found in HTML. If your navigation or pagination is generated client-side, whole sections of the site are never discovered — not slowly indexed, never found at all.
04
Metadata is set client-side
Titles, descriptions and canonicals written by JavaScript are absent on the first pass. This is why Google sometimes shows a title that is not the one you set — it captured the placeholder.

The third one is the most damaging and the least discussed. Slow indexing is a delay; undiscovered URLs are a permanent hole in the site. If your category pagination or faceted navigation only renders client-side, the products behind it may as well not exist.

Symptoms, and what each one actually means

Rendering problems announce themselves indirectly. These are the complaints that turn out to be rendering, and what each usually indicates. Each links through to a guide that starts from that exact symptom.

SymptomUsual cause
“Discovered — currently not indexed”The URL looked low-value on the first pass and never earned a render.
“Crawled — currently not indexed”It was rendered, but what was found was judged thin or duplicate.
View source is nearly emptyClient-side rendering. Whether a crawler waits for the content is not guaranteed.
Google shows the wrong titleThe title is being set client-side, after the first-pass capture.
Blog indexes fine, product pages don'tThe blog is static; the catalogue is client-rendered. Very common split.
Traffic dropped after a migrationA rendering mode changed during the move, usually silently and per-route.
New pages take weeks to appearRender-dependent pages sit in a slower queue than server-rendered ones.

If one of these is what brought you here, the fix guides are organised by symptom — pick the row that matches what you're seeing and start there.

How to diagnose it properly

Three methods, in ascending order of reliability. The first two are worth knowing mainly so you understand why they mislead people.

Disabling JavaScript in your browser is the classic advice and it is misleading. It shows you the page without JavaScript, but your browser has already applied cookies, cached assets and your session. It also does not tell you what a crawler would do differently. It catches only the most catastrophic cases.

Viewing sourceis better — that really is the raw HTML — but on a modern site it is tens of thousands of lines, and the question "is my content in here?" is genuinely hard to answer by scrolling. It also tells you nothing about how much is missing relative to the rendered page.

Fetching the page twice and comparing is the method that actually answers the question. Request the URL as raw HTTP with no JavaScript, then load the same URL in a real browser, then diff the two. The size of the gap is the answer, and the specific missing elements tell you where to look. That is what the tool below does.

Check what a crawler sees on your page
https://

Whatever you check, check the templates that generate revenue rather than the homepage. Homepages are usually the most carefully optimised page on a site while product, category and article templates use entirely different data-fetching patterns. A homepage passing tells you very little.

How to fix a rendering problem

Fixes in order of durability. The first is almost always the right answer; the others are compromises with specific tradeoffs.

01
Move data fetching to the server
Fetch on the server and pass the result down as props, so the HTML leaves complete. In modern frameworks this is usually the default and the client-side version is something that was chosen deliberately at some point. Most durable fix, no added infrastructure.
02
Statically generate what doesn't change
Content that changes rarely — articles, docs, marketing pages — should be built once and served as files. Faster and cheaper than rendering per request, and identical for SEO.
03
Use incremental regeneration for large catalogues
For thousands of pages that change occasionally, regenerate on a schedule or on demand. You get static HTML without a full rebuild per change.
04
Prerendering as a stopgap
A service intercepts crawler requests and returns a cached rendered snapshot. Works, and sometimes the only realistic option for a legacy app — but it adds a dependency, a cost, and a second version of your site that can silently drift from the real one.

That last option deserves a caveat, because the ground has shifted under it: Google deprecated its own dynamic-rendering recommendation and now treats it as a workaround rather than a blessed path. It still works, but it is no longer the advice — the dynamic rendering and prerendering guide covers when it's still reasonable and when it's a trap. And one thing that is not a fix at all: adding structured data describing content the crawler cannot see. Schema markup annotates content; it does not substitute for it. Marking up a product whose name and price only exist after hydration does not make the product visible — it just makes the markup inconsistent with the page.

AI crawlers are stricter than Google

This is the part that has changed most recently, and it moves the calculation for anyone who has been getting away with client rendering. The guide on AI crawlers and JavaScript goes further; the short version follows.

Google renders JavaScript. The crawlers behind AI assistants and answer engines largely do not — most fetch the raw HTML and work with what they find. A site that Google eventually indexes after a delay may be permanently invisible to them, because there is no second pass to wait for.

Practically, that means the tolerance for client-side rendering is narrowing. The argument "Google handles it fine" was always about one crawler being unusually capable and unusually patient. As more discovery happens through systems that read raw HTML and nothing else, first-pass completeness stops being a nice-to-have.

Five myths worth retiring

“Google renders JavaScript, so this doesn't matter”
Google renders JavaScript in a delayed, rationed second pass. Other crawlers mostly don't render at all. Capability is not the same as guaranteed, timely execution.
“We have SSR, so we're fine”
SSR is usually configured per route. It is entirely normal for a homepage to be server-rendered while product templates fetch their content client-side. Check the templates that matter.
“Static generation is worse than SSR for SEO”
They are identical from a crawler's perspective — both deliver complete HTML. Static is usually faster and cheaper.
“Dynamic rendering is the recommended fix”
It was, and Google has since stepped back from that recommendation, treating it as a workaround rather than the answer. It still works, but real server rendering is the durable fix and prerendering is the stopgap.
“The page ranks, so rendering is fine”
Something ranking tells you that page was indexed. It says nothing about the thousand URLs behind client-rendered pagination that were never discovered.

Where to go from here

Three ways in, depending on what you know. If you know your framework, the check pages cover the particular ways each one fails. If you have a specific symptom, the fix pages start from the symptom rather than the cause. If you want the concepts first, the rest of the guides go deeper on each piece.

Check your framework
Eleven frameworks — Next.js, React, Vue, Nuxt, Angular, Astro, SvelteKit and more — each with its own failure modes.
/check
Fix a specific symptom
Start from what you're seeing in Search Console or the browser and work backwards to the cause.
/fix
Go deeper on the concepts
The full set of guides: SSR vs CSR, hydration, how Googlebot renders, AI crawlers and more.
/learn

Or, if you'd rather not own this yourself, the rendering audit and implementation service is for teams who want it diagnosed and fixed for them.

JavaScript SEO FAQ

Yes. Google executes JavaScript and indexes the resulting content. However it does so in a second pass that happens some time after the initial crawl, and that pass is rationed based on how valuable the page appears. Content that only exists after JavaScript runs is therefore indexed more slowly and less reliably than content present in the initial HTML.