Related: Structured Data That Actually Earns Rich Results
"Google can render JavaScript" is true and has been for years. It is also the single most misleading sentence in technical SEO, because it gets read as "rendering is free," which it is not.
Understanding what actually happens is the difference between a site that gets indexed reliably and one that mysteriously never ranks.
Indexing happens in two waves
When Googlebot fetches a URL, it first parses the raw HTML that came back from your server. Links, text and metadata present in that HTML are processed immediately.
If the page needs JavaScript to produce its content, the URL goes into a render queue. At some later point — historically anywhere from minutes to weeks, usually much faster now but never guaranteed — a headless browser executes the JavaScript and the resulting DOM is processed.
Two things follow. Content that exists only after JavaScript runs is indexed later than content in the HTML, sometimes much later. And anything that goes wrong during rendering means the content is never indexed at all.
The failure modes
Rendering fails more often than people expect, and almost always silently:
- The renderer times out. Slow API calls in the critical path are the usual culprit. The renderer does not wait indefinitely.
- A JavaScript error throws. One uncaught exception can leave the page empty. Errors that only occur in the renderer's environment — a missing browser API, a different user agent path — are especially easy to miss.
- Content needs an interaction. Anything behind a click, a scroll or a hover does not exist as far as a crawler is concerned. Infinite scroll with no paginated URLs is the classic version.
- Resources are blocked. If
robots.txtdisallows your JavaScript bundle or your API routes, the renderer cannot build the page. Blocking/api/is a common own goal. - Rendering depends on cookies or session state. Crawlers arrive with neither.
Everyone else renders less than Google
This is the part that has become decisive. Google invested heavily in rendering. Most other crawlers did not:
- Social preview bots — Facebook, LinkedIn, Slack, WhatsApp — generally read raw HTML only. If your Open Graph tags are injected client-side, your links will preview as blank.
- Many AI answer engines fetch HTML without executing JavaScript. If your content only exists post-render, you are invisible to them regardless of how well you rank in classic search.
- Bing renders, but more conservatively.
- Various SEO and monitoring tools do not render at all, which is why their reports sometimes disagree wildly with reality.
A client-side-rendered site can rank perfectly well in Google and still be absent everywhere else. In 2026 that trade is much worse than it was in 2020.
The three rendering strategies
Client-side rendering
The server returns a near-empty HTML shell; JavaScript fetches data and builds the DOM in the browser. Simple to deploy and excellent for application-like interfaces.
Right for: dashboards, admin panels, anything behind a login, tools nobody needs to find via search.
Wrong for: marketing pages, blogs, product listings, documentation — anything whose job is to be found.
Server-side rendering
The server runs the application per request and returns complete HTML, which then hydrates into an interactive app in the browser. Crawlers get the full content in the first response.
Right for: content that changes per request or per user, large catalogues, anything personalised that still needs indexing.
Costs: real server capacity, and a slower time-to-first-byte than serving a static file. Cache aggressively or the origin becomes the bottleneck.
Static site generation
Pages are rendered to HTML at build time and served as files. Fastest possible delivery, trivially cacheable at the edge, nothing to go wrong at request time.
Right for: blogs, documentation, marketing sites, any catalogue that changes on a schedule rather than continuously.
Costs: build time grows with page count, and content is only as fresh as the last build. Incremental regeneration — rebuilding individual pages on demand — removes most of that objection and is what most modern frameworks now offer.
What about dynamic rendering?
Dynamic rendering serves pre-rendered HTML to crawlers and the client-side app to humans, switching on user agent. Google described it as a workaround years ago and now explicitly calls it a stopgap rather than a recommended architecture.
Avoid it on new builds. You maintain two rendering paths that drift apart, and serving different content by user agent is uncomfortably close to cloaking even when your intent is honest. SSR or static generation solves the same problem without the ambiguity.
Diagnosing a real problem
Work from evidence, in this order:
- Compare source with rendered DOM. View source shows what the server sent; DevTools' Elements panel shows what exists after JavaScript. If your main content is only in the second, crawlers depend on rendering.
- Fetch the page the way a crawler would.
curl -s https://yoursite.com/page | grep "some unique phrase". If the phrase is missing, no non-rendering client will ever see it. - Use the URL Inspection tool in Search Console. Its rendered screenshot and HTML show what Google actually got, which is the authoritative answer.
- Check coverage reports. "Crawled — currently not indexed" across a group of JavaScript-dependent pages is a strong signal.
- Read your server logs. They show which bots fetch what, and whether they return for the resources rendering needs.
Practical rules
- Anything that must be indexed belongs in the initial HTML response. Title, meta description, canonical, headings, body copy, structured data.
- Every indexable piece of content needs its own URL. Tabs, modals and infinite scroll all need real, linkable, crawlable addresses.
- Links must be real
<a href>elements. Adivwith a click handler is not a link and will not be followed. - Never block your JavaScript, CSS or data endpoints in
robots.txt. - Set metadata server-side. Client-side title and OG tag updates are unreliable across the wider ecosystem.
- Keep the render path fast and free of avoidable dependencies.
The short version
If a page needs to be found, render it on the server or generate it statically. If a page lives behind a login and nobody searches for it, render it in the browser and enjoy the simpler deployment.
Most sites need both, which is why frameworks that let you choose per route — rather than committing the whole application to one strategy — have won. The question is never "SSR or CSR" for a whole codebase. It is which one this particular page needs.
If you are unsure why pages are not being indexed, send us the URL and we will tell you what a crawler sees. It is a routine part of our web development work.
Comments