JavaScript SEO & Rendering
Why rendering is its own SEO discipline
Modern frameworks routinely build pages where the initial HTML response is nearly empty — a <div id="root"> and a bundle of JavaScript that fills it in client-side. A browser does this instantly for a human visitor. A crawler has to do extra work to see the same thing, and that extra work is neither instant nor guaranteed. JavaScript SEO is the practice of making sure whatever content matters for ranking is actually visible to a crawler, not just to a browser.
Client-side, server-side, and hybrid rendering
Client-side rendering (CSR) ships minimal HTML and builds the page in the browser via JavaScript — fast to develop, but crawlers must execute JS to see content. Server-side rendering (SSR) runs the framework on the server per request and returns fully-formed HTML — crawler-friendly by default, at the cost of server compute per request. Static site generation (SSG) pre-builds HTML at deploy time — the fastest and most crawl-friendly option for content that doesn't change per-request. Most production Next.js and similar apps today use a hybrid approach: SSG or SSR for crawlable public pages, CSR for logged-in or highly interactive views that don't need indexing.
Rendering strategies for SEO
| Strategy | Crawler sees content immediately? | Best for |
|---|---|---|
| Client-side rendering (CSR) | No — requires JS execution | Authenticated app views, dashboards |
| Server-side rendering (SSR) | Yes — full HTML per request | Dynamic public pages (search results, personalized but indexable pages) |
| Static generation (SSG) | Yes — pre-built HTML | Marketing pages, blog posts, docs |
| Hybrid (SSG/SSR + CSR islands) | Yes for indexable routes | Most production apps with mixed content needs |
How Googlebot's rendering queue actually works
Google processes JavaScript pages in two passes. First, it crawls the raw HTML response and extracts any links and content already present. Then, qualifying pages are queued for a second pass through a rendering service (built on a recent Chromium) that executes the JavaScript and captures the resulting DOM. This second pass is not instant — Google has described rendering as happening within seconds to a few days after crawling, depending on queue load. That gap means JS-dependent content can take meaningfully longer to get indexed than static HTML, and a page that errors out during rendering may never make it past the first, mostly-empty pass.
Two-wave indexing means links in JS-only content are discovered late
Common JS SEO pitfalls
A handful of mistakes recur across nearly every JS-heavy site audit:
- Content gated behind user interaction — text that only renders after a click (a 'read more' that fetches content, or tab content not in the initial DOM) is often missed, since Googlebot doesn't reliably interact with the page the way a user does.
- Blocked JS/CSS resources in robots.txt — if the rendering engine can't fetch the scripts that build the page, it renders a blank or broken shell, identical to the problem it was supposed to solve.
- Client-side-only routing without server fallback — a single-page app that handles all routing in JS needs the server to still return meaningful HTML (or at least correct status codes) for each distinct URL, or every deep link looks like the same homepage shell to a crawler on first pass.
- Long JS execution timeouts — if a page depends on multiple sequential API calls before content appears, the renderer may capture the DOM before everything resolves.
# Mistake: blocking the JS bundle crawlers need to render the page
User-agent: *
Disallow: /_next/static/
Disallow: /assets/js/
# Fix: allow rendering assets, block only non-content paths
User-agent: *
Disallow: /admin/
Allow: /_next/static/
Allow: /assets/js/Testing what Google actually sees
Don't rely on viewing page source alone — that only shows the pre-render HTML. Use Search Console's URL Inspection tool's 'View Tested Page' / rendered HTML view, which shows the DOM after Google's rendering pass, including a rendered screenshot and any JS console errors encountered. Comparing the raw HTML response against this rendered output is the fastest way to confirm whether critical content depends on JavaScript execution to appear at all.
Other crawlers render less reliably than Googlebot
What's next
These rendering fundamentals apply to any site, but single-page applications push the client-side extreme the hardest — routing, meta tags, and even the page title can all live entirely in JavaScript state.
Next: SEO for Single-Page Applications →
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.