Googlebot Isn't a Browser — Except When It Is
Google's Web Rendering Service (WRS) runs a headless version of Chrome to process JavaScript-heavy pages. As of 2026, it's based on the latest stable Chrome version (they keep it updated within about two weeks of new Chrome releases). This is a big deal — it means Google can theoretically see anything Chrome can render.
But "can render" and "will render quickly" are very different things.
The Two-Phase Indexing Process
Google processes pages in two distinct phases:
Phase 1: Crawl. Googlebot fetches the HTML. It parses whatever's in the initial response — static HTML, meta tags, canonical tags, and any content that's in the source before JavaScript runs. Links found in this phase are added to the crawl queue immediately.
Phase 2: Render. The page enters the rendering queue. WRS fires up headless Chrome, executes JavaScript, waits for the DOM to settle, then indexes the final rendered content. Links discovered only after rendering are also added to the crawl queue, but later.
The gap between Phase 1 and Phase 2 is the critical issue. Google has said the queue is "generally seconds to minutes," but in my experience with less frequently crawled sites, it can take days or even weeks. High-authority sites with fresh content are rendered much faster than smaller sites with infrequent updates.
What This Means in Practice
If your content is rendered by JavaScript:
- Important content might not be indexed for days after the page is crawled
- Meta tags injected via JavaScript (title, description, canonical) are read during rendering, but there's a delay
- Links that only exist after JavaScript execution are discovered later, slowing down crawl propagation
- If the rendering fails for any reason, the page is indexed based on Phase 1 HTML only
What Makes Rendering Fail?
WRS has some important limitations:
- It doesn't support
localStorageorsessionStoragein a meaningful way (they're available but ephemeral) - It doesn't interact with the page — no clicks, no scrolls, no form submissions
- It has a timeout (about 5 seconds for initial rendering, though Google hasn't published exact numbers)
- It doesn't support WebSocket connections for real-time data
- Service workers are not executed
If your app relies on user interaction to reveal content (click to expand, tab navigation, infinite scroll), that content won't be seen. If your API calls take more than a few seconds, the content might not be there when Google takes its snapshot.
Framework-Specific Considerations
React (Client-Side Rendered)
A vanilla Create React App renders everything client-side. Googlebot sees an empty <div id="root"></div> in Phase 1. Everything depends on Phase 2 rendering. For important content, this is risky — any rendering failure means zero content is indexed.
Next.js
Next.js with SSR (Server-Side Rendering) or SSG (Static Site Generation) delivers full HTML in Phase 1. This is the gold standard for SEO. The page is indexable immediately, and JavaScript enhancement happens on top. Even if rendering fails, all the content is there.
Use getServerSideProps for pages with dynamic data or getStaticProps for pages that can be pre-built. The newer App Router with Server Components takes this even further — less JavaScript ships to the client, which means less that can go wrong during rendering.
Vue/Nuxt
Similar story: plain Vue.js is client-rendered and has the same risks as React. Nuxt provides SSR and SSG options that solve the SEO problem. Use them.
Angular
Angular Universal provides SSR. Without it, Angular apps are client-rendered. I'll be honest — Angular SSR has historically been harder to set up correctly compared to Next.js or Nuxt, though it's gotten better with recent versions.
Dynamic Rendering: The Temporary Fix
Dynamic rendering means serving pre-rendered HTML to bots while serving the JavaScript version to regular users. Google officially supports this approach, though they've called it "a workaround rather than a long-term solution."
Tools like Rendertron or prerender.io sit between your server and search engine bots. When they detect a bot user agent, they serve a pre-rendered HTML snapshot. Users get the normal JavaScript app.
The downsides: you're maintaining two versions of your site (sort of), the pre-rendered snapshots need to stay current, and there's a risk that Google views it as cloaking if the bot version differs significantly from the user version. Google has explicitly said dynamic rendering is fine as long as the content is the same.
Testing What Google Sees
Use these tools in order of reliability:
- URL Inspection Tool (Search Console) — shows you the rendered HTML that Google actually processed. This is the ground truth.
- Rich Results Test — renders the page and shows you the DOM. Also indicates JavaScript errors.
- Chrome DevTools — disable JavaScript (Settings → Debugger → Disable JavaScript) to see what Phase 1 crawl sees.
Don't rely on "Fetch as Google" alone — it shows you what Google receives, but the rendering environment might differ from production WRS in subtle ways.
My Recommendation
If you're starting a new project: use a framework with built-in SSR/SSG (Next.js, Nuxt, SvelteKit). The SEO benefits are automatic and you don't have to think about rendering issues.
If you have an existing client-rendered SPA: add SSR to your critical pages first — homepage, product pages, landing pages, blog posts. You don't need to convert the entire app. Focus on pages that drive organic traffic.
If SSR isn't feasible: implement dynamic rendering as a temporary solution while you plan a longer-term migration. It's not perfect, but it's significantly better than relying entirely on Google's rendering queue.