Google has rendered JavaScript for years, but the common belief that "Google renders JS, so client-side frameworks are fine for SEO" remains one of the more expensive misunderstandings in technical SEO.
It misses two operational realities. First, Googlebot uses two-wave indexing: initial HTML is fetched and indexed first, and the Web Rendering Service executes JavaScript later — often delayed relative to the first pass depending on site authority and server load. Second, as of their currently published documentation, the major AI search crawlers largely don't render JavaScript at all — OpenAI's GPTBot, Anthropic's ClaudeBot, and PerplexityBot are documented as not running headless browsers. That's current, publicly stated behaviour rather than a permanent architectural guarantee, and it's worth re-checking each crawler's own documentation periodically since it can change without much notice. As things stand, though, content that relies on client-side execution or hydration to populate text or internal links is effectively invisible to those crawlers.
Understanding JavaScript hydration — and where it breaks — is the practical difference between pages that get crawled and indexed accurately and pages that silently underperform for reasons nobody on the team has diagnosed.
What hydration actually means for SEO
In modern JavaScript frameworks (React, Next.js, Vue, Nuxt, Angular), hydration is the client-side process where the framework runtime attaches event listeners and reconstructs the virtual DOM over static HTML delivered by server-side rendering.
- Hydration mismatch errors — when server-rendered HTML doesn't match the client-side virtual DOM state (dynamic timestamps, personalisation tokens, client-only checks), the framework discards and rebuilds that DOM branch. If Googlebot's rendering pass catches that rebuild mid-flight, content can appear to vanish or flash empty.
- Layout shift overhead — components that fetch secondary data post-mount to insert links, prices, or availability shift page elements after the initial paint, which is exactly what Cumulative Layout Shift measures.
- Deferred link discovery — links that exist only as client-side routing handlers rather than standard anchor tags in the server HTML aren't discoverable in the first crawl pass, which delays crawling of whatever they point to.
[Server Output] → Static HTML sent to browser/crawler [Client Execution] → JS bundle downloads & runs [Hydration Step] → Virtual DOM attaches to static HTML (now interactive)
How to audit and diagnose it
This doesn't need to be guesswork. Three checks will tell you whether hydration is costing you anything on a given template:
- 1Fetch the raw HTML as Googlebot would (curl with a Googlebot user-agent) and confirm critical copy, canonical tags, and structured data are present in the raw response — not just the rendered DOM.
- 2Compare that raw output against the fully hydrated DOM in Chrome DevTools to see exactly what changes during hydration.
- 3Check browser console/production logs for hydration mismatch warnings — most frameworks log these explicitly when server and client output disagree.
What to actually do about it
Move non-interactive content — body copy, structured data, footer links — into server-only rendering (React Server Components, Astro islands) so it never depends on client-side hydration to exist in the DOM. Keep client-side state hooks scoped to the smallest possible component rather than wrapping entire layouts in client context providers that force full-page rehydration. And treat HTML validation as a build-time check, not a nice-to-have — invalid nesting is one of the more common triggers for hydration mismatches in the first place.
The test that matters isn't "does Google eventually render this" — it's "does the content exist in the DOM at the moment a crawler without a JS engine reads the page." For AI crawlers specifically, the answer today is generally no.
Related articles
Extracting Googlebot Insights From Server Log Files
GSC gives you aggregates. Log files are the only record of what actually happened, request by request.
React Server Components vs. Traditional SSR: The Technical SEO Comparison
Traditional SSR solves the blank-page problem but still ships a full JS bundle to hydrate. RSC changes that calculation — here's what actually improves.
Dynamic Rendering in 2026: Why Client-Side-Only Rendering Is a Liability for Search
Prerendering for Googlebot used to be a viable patch for client-side apps. It doesn't cover the crawlers that matter most now.
Optimising INP for Heavy JavaScript Frameworks
INP measures total interaction time, not just when the browser started responding. On heavy JS frameworks, hydration is usually the hidden cost.

Written by
Paul Lovell
International SEO Consultant & Founder of Always Evolving SEO. 15+ years running technical audits, log-file analysis, and root-cause fixes for multimillion-dollar businesses — speaker at SMX London, Search & Content Summit, and SEMrush events.