JavaScript SEO: How Googlebot Renders JavaScript and What to Check

Publication date: 15.05.2026 23:06

Googlebot renders JavaScript in two stages: first it crawls the HTML, then executes JS — sometimes weeks later. This lag causes React/Vue/Angular sites to get incomplete indexation. Here is a full diagnostic and fix checklist.


How Googlebot Processes JavaScript: WRS Explained

Googlebot uses the Wave Rendering System (WRS) — a two-stage page processing pipeline. Stage one: the crawler downloads the HTML and places the page in a rendering queue. Stage two: a Chromium engine executes JavaScript and builds the final DOM. The gap between stages can range from a few hours to several weeks, depending on the site's rendering budget and Google's infrastructure load.

We audited a React site with 800 pages — Googlebot was seeing only 12% of the content due to rendering failures. The root cause: critical body text was loaded via an API call after the component mounted, and Google simply didn't wait for the server response. After migrating to SSR, the same site gained +67% indexed pages within three months.

Googlebot two-stage rendering model (WRS) STAGE 1 HTML Crawl Crawler fetches HTML No JS executed yet Render queue hours/weeks STAGE 2 JS Rendering Chromium executes JavaScript Final DOM built Indexation If JS executed OK content enters Google's index
Googlebot's two-stage rendering model: the gap between Stage 1 and Stage 2 can span hours to weeks

Googlebot's Chromium version consistently lags behind the current release — typically by 1–2 years. According to Google's official documentation, the crawler ran Chromium 112 as of 2024, while the current browser version had long surpassed 120. This means certain modern JS APIs may not be supported by the crawler at all.

Practical rule: if your site serves different content to a regular browser vs a curl request (no JS), assume Google sees the curl version until WRS rendering completes.

SSR vs CSR vs SSG vs ISR — SEO Comparison Table

Choosing a rendering strategy is the single most important architectural decision for JavaScript SEO. Each model has a distinct impact on indexation reliability, page speed, and maintenance complexity.

Rendering Type How It Works SEO Reliability TTFB Complexity
SSR (Server-Side Rendering) HTML generated on server per request High — Google gets ready HTML Higher (server load) Medium
CSR (Client-Side Rendering) Empty HTML shell; JS builds DOM in browser Low — depends on WRS success Lower (static shell) Low
SSG (Static Site Generation) HTML pre-built at deploy time Maximum — clean static HTML Minimal (CDN) Low
ISR (Incremental Static Regeneration) Static pages regenerated on a schedule High — HTML always ready Minimal Medium
Hydration / Islands SSR + selective client-side hydration High when implemented correctly Low High

For eCommerce and large catalogues, we recommend ISR or SSR via Next.js / Nuxt.js. SSG suits blogs and landing pages where content changes infrequently. Pure CSR is acceptable only for authenticated apps (dashboards, SaaS behind login) where SEO is irrelevant.

JS Site Diagnostics Checklist: Tools and Steps

Diagnosing rendering issues requires working with several tools in sequence. Here is the workflow we follow during a technical SEO audit:

  1. Google Search Console → URL Inspection. Open any suspicious page, click "View Crawled Page". GSC shows a screenshot of what Google sees after rendering, plus a list of blocked resources.
  2. Screaming Frog in JavaScript mode. Enable Configuration → Spider → Rendering → JavaScript. Compare Word Count with JS on vs off — a gap over 20% signals a rendering problem.
  3. Rich Results Test (search.google.com/test/rich-results). Verifies whether Google can read structured data after JS rendering.
  4. Request Indexing via GSC → URL Inspection → Request Indexing. Forces a fresh render and crawl of a specific page.
  5. Chrome DevTools → Coverage. Shows how much JS actually executes on load — helps identify dead code bloating your render time.
  6. URL Inspection API. Programmatic indexation status checks via Google Search Console API — essential for mass audits of large sites.
Pro tip: run two Screaming Frog crawls of the same site — one with JS, one without. If Word Count in JS rendering mode is 30%+ higher, you have content that Googlebot may not see until its rendering queue processes the pages.

The Rendering Budget Problem

The rendering budget is the limited resource Googlebot allocates to JS rendering for each domain. Google does not publish exact figures, but based on our audits of large sites (10,000+ pages): once the budget is exhausted, some pages get indexed from their HTML shell only — JavaScript never executes.

Factors that drain the rendering budget faster:

  • Overall crawl budget — more popular domains get more rendering resources from Google
  • JS bundle size and complexity — heavy bundles (2+ MB) burn through the budget quickly
  • Number of third-party resources — fonts, tracking scripts, chat widgets all delay rendering
  • JS execution time — if a script runs longer than ~5 seconds, Googlebot may abort rendering
  • JavaScript errors — uncaught exceptions halt script execution entirely
Auditing a Vue.js store with 3,200 product pages: 41% of pages were indexed without JS rendering — that content was effectively invisible to search. The culprit: a 4.1 MB bundle and 23 third-party scripts loaded in the document head.

To detect budget exhaustion, check Google Search Console → Coverage → "Indexed, not submitted in sitemap" and "Discovered — currently not indexed". Cross-reference those URLs in Screaming Frog JS mode — if content exists but Google misses it, the rendering budget is the likely bottleneck.

Dynamic Content and data Attributes: What Google Actually Sees

Googlebot reads the DOM after rendering — so it can see content that appeared via JavaScript. But several common patterns cause content loss:

  • Event-triggered content (scroll, click, hover) — the crawler does not interact with pages, so lazy content behind "Show More" buttons stays invisible
  • Infinite scroll — Google sees only the first batch of content. Fix: pagination with real URLs
  • Content in modals and popups — if hidden via display:none or visibility:hidden, Google de-prioritises it
  • data attributes — Google reads them but does not index them as text content. Critical information (name, description, price) must live in the visible DOM, not only in data-*
  • API-dependent content — if text comes via fetch(), Google sees it only if the request completes during the rendering window
For eCommerce: price, availability, and product name must not be loaded via a separate API call after the page loads. If they exist only in a JS request — embed them in the initial HTML via SSR or pre-rendering.
Content visibility comparison: browser user vs Googlebot Content Visibility: Browser User vs Googlebot Browser User + HTML text content + JS-rendered content + Content after scroll / click events + Infinite scroll pages + Modal and popup content + data attributes (read by JS) Googlebot (WRS) + HTML text content +/- JS-rendered content (after WRS) - Content after scroll / click events - Infinite scroll (first batch only) - Hidden modal content (display:none) - data attributes (not indexed as text)
Content visible to a browser user is not always visible to Googlebot — especially event-driven and dynamically loaded elements

Single Page Applications are a high-risk zone for internal link equity. SPA frameworks use client-side routing, which introduces several crawlability traps:

  • JavaScript event handler links: <div onclick="navigate('/category')"> — Googlebot does not follow these. The linked page never gets crawled and receives no PageRank.
  • Missing href attribute: <a> without href, or with href="#" — Google ignores them as link signals.
  • History API without server fallback: React Router or Vue Router change URLs via pushState(), but if the server returns 404 on direct access — Googlebot logs an error and stops crawling that path.
  • Links inside Shadow DOM: content and links inside Web Components / Shadow DOM are read by Googlebot with limitations.
  • JavaScript redirects: chains of JS-based redirects (via window.location) don't pass PageRank as efficiently as server-side 301s.

Correct approach: all navigational links use <a href="/real-path">. The client-side router can intercept clicks for SPA navigation, but the href must be a real URL. This solves two problems at once: Googlebot crawlability and correct behaviour when opening links in a new tab.

Structured Data in JS Sites — When Google Can't Read It

JSON-LD in the document body is typically readable by Google even without JavaScript rendering — one of the few areas where JS sites have a built-in advantage. But there are important exceptions:

  • JSON-LD generated via JavaScript: the markup is only visible to Google after rendering. Until WRS completes, pages may have no structured data in the index.
  • Template-generated JSON-LD with character errors: if values are injected via JS templates and contain unescaped quotes or special characters, the schema breaks silently.
  • Duplicate schema from components: React/Vue component re-renders can easily produce multiple identical <script type="application/ld+json"> blocks on the same page.
  • Dynamic values (price, rating) from API: if a Product schema is built from an API response that hasn't arrived yet, Google sees empty fields — which can lead to rich result eligibility being revoked.
Solution: embed critical JSON-LD blocks (Article, Product, BreadcrumbList) directly in the server-rendered HTML via SSR or SSG. Validate with Rich Results Test — it shows what Google sees after rendering.

JavaScript SEO Fix Checklist

After diagnosis, here is the prioritised fix sequence — from critical to optimisation-level items.

  1. Implement SSR or SSG for critical pages. In Next.js: use getServerSideProps (SSR) or getStaticProps (SSG). In Nuxt.js: use asyncData. At minimum, cover the homepage, category pages and product/service pages.
  2. Audit all internal links. Run Screaming Frog or Ahrefs Site Audit — identify all links missing href or using JavaScript in href.
  3. Set up a server-side fallback for SPA routing. Every URL accessible via the client router must return 200 with full HTML on direct access.
  4. Move critical meta tags to server-rendered HTML. Title, description, canonical and hreflang must be in the server response, not JS-generated at runtime.
  5. Optimise your JS bundle. Targets: under 150 KB for the initial bundle (gzip), code splitting for non-critical modules, lazy loading below-the-fold components.
  6. Defer or remove unnecessary third-party scripts. Every external script (pixels, live chat, analytics) adds to rendering time. Use defer or async attributes.
  7. Embed critical JSON-LD schemas in server HTML. Don't generate Product, Article or FAQ schema via client-side JS — include them in the SSR response.
  8. Replace infinite scroll with pagination. Or provide individual URL-addressable routes for each content batch, accessible via direct URL.
  9. Add JavaScript error handling and monitoring. Uncaught exceptions stop script execution. Add a global error handler and implement JS error monitoring (Sentry, LogRocket).
  10. Set up pre-rendering as a fallback. Tools like Rendertron or Prerender.io serve static HTML to bot requests — a viable interim solution while full SSR is in development.

After deploying fixes, re-audit with GSC and Screaming Frog. SSR migration results typically appear in GSC within 3–6 weeks: the count of indexed URLs rises and "Discovered — currently not indexed" errors decline.

If you need expert help with a technical SEO audit of your JS site, or a migration strategy to SSR — we run full rendering architecture diagnostics and deliver a prioritised fix plan with ROI estimates. Learn more about our website promotion services.


Frequently Asked Questions

Does Googlebot index React websites?

Yes, but with a delay. Googlebot renders JavaScript in two stages — first it crawls the HTML, then (days or weeks later) it renders the JS. Until rendering completes, pages may be indexed without some of their content.

Which is better for SEO: SSR or CSR?

SSR is more reliable for SEO because Google receives ready-made HTML without needing to execute JavaScript. CSR depends on successful rendering, which can fail due to rendering budget limits or uncaught JS errors.

How can I check what Googlebot sees on a page?

Use Google Search Console → URL Inspection → "View Crawled Page". Screaming Frog in JavaScript rendering mode shows the difference in content with and without JS. Rich Results Test verifies whether structured data is visible after rendering.

Does Google read content loaded via fetch/XHR?

Yes, if JavaScript executed successfully and the content is present in the DOM after rendering. If content loads after scroll or click events, Google won't see it — the crawler does not interact with pages.

Is your JS site being poorly indexed?

We run a technical SEO audit covering rendering, internal links, structured data and crawl budget. You get a report with specific fixes and impact-based prioritisation.

Order a technical audit or learn about our promotion services

Seo Factory
The content published on SEO-FACTORY is created by a team of specialists in SEO, digital marketing, PPC advertising, and web analytics. The main goal of the project is to provide practical and easy-to-understand materials that help businesses, website owners, and marketers better understand modern Google algorithms, SEO principles, and online promotion strategies. The authors regularly work with commercial projects in Ukraine and international markets, testing SEO strategies, analyzing search algorithm updates, studying behavioral ranking factors, link building, AI search technologies, content marketing, and Google Ads campaigns. Because of this, the published materials are based not only on theory but also on real-world practical experience. Articles on SEO-FACTORY include: up-to-date market data and industry research; practical insights and real case studies; analysis of Google updates and SEO trends; technical optimization recommendations; modern approaches to increasing organic traffic. The project focuses on creating expert-level content without generic advice or unnecessary filler. The main emphasis is placed on practical value, clear explanations, and modern digital marketing approaches relevant