Key Takeaways:
Google renders JavaScript – but with delays, crawl budget costs, and a blind spot that keeps growing in 2026. While Google’s Web Rendering Service has been processing JS for years, virtually all major AI crawlers (GPTBot, ClaudeBot, PerplexityBot) do not render JavaScript. Sites relying on client-side rendering are effectively invisible to a growing share of AI-powered search.
- Two-wave crawling: Google first fetches raw HTML (Phase 1), then the WRS renders with headless Chromium – with a delay of hours to weeks (Phase 2).
- AI crawler problem: GPTBot, ClaudeBot, PerplexityBot, Bytespider, and Meta-ExternalAgent do not render JavaScript. Critical content must be in the initial HTML.
- Recommendation for 2026: Server-side rendering (SSR) or static site generation (SSG) as the foundation – not CSR. Dynamic rendering is a migration workaround, not a new-build strategy.
On March 4th, 2026, Google removed a warning from its official JavaScript SEO documentation. The “Design for accessibility” section – which recommended keeping pages functional without JavaScript – was dropped with the note that the information had become “outdated and no longer as helpful as before.” Google has been rendering JavaScript for years, so JS no longer makes indexing harder.
That sounds like an all-clear. It isn’t. The question “Can Google render JavaScript?” was largely settled back in 2019. The relevant question in 2026 is: Which crawlers actually reach your JavaScript-generated content? And that’s where things get uncomfortable. While Google has steadily improved its Web Rendering Service (WRS), most AI crawlers – GPTBot, ClaudeBot, PerplexityBot, Bytespider, Meta-ExternalAgent – render no JavaScript whatsoever. None of them.
In my technical audits, I regularly see single-page apps that are indexed correctly by Google but are practically invisible in ChatGPT Search or Perplexity. That is the real JavaScript SEO problem in 2026 – not whether Google can handle it, but who else can keep up.
In this article: How Google’s WRS works technically, what can go wrong in the two-wave crawl, why AI crawlers don’t render JS, and which rendering strategy is right for 2026.
Google’s Web Rendering Service: The Two-Wave Crawl
Google’s rendering infrastructure centers on the Web Rendering Service (WRS). The WRS runs a headless Chromium browser to process JavaScript – the same Chromium build that powers Google Chrome. Since 2019, this Chromium build has been “evergreen,” meaning it’s automatically updated to current versions. This means modern JavaScript syntax (ES6+, async/await, Promises, Fetch API) is fully supported.
The crawling process runs in two clearly separated phases:
Phase 1 – HTTP Crawl: Googlebot fetches the raw HTML from the server. No JavaScript, no CSS. Whatever is in the initial HTML at that point is immediately evaluated and used for indexing. Title tags, meta descriptions, canonical URLs, robots meta tags – all are read from this HTML. The 2 MB limit applies here: bytes beyond 2 MB are completely ignored.
Phase 2 – Rendering Queue: Pages containing JavaScript are queued by Googlebot for rendering. Once Google’s resources allow, the WRS renders the page with headless Chromium. Only then does Google see the JavaScript-generated content. How long does it take? Google provides no concrete numbers. In practice, the range spans from a few hours to several weeks – depending on the domain’s crawl frequency, server performance, and available WRS capacity.
What the WRS processes: CSS, JavaScript, XHR requests and API calls. What it doesn’t process: images and videos are not downloaded. This means that with APIs that have long response times, the WRS may abort rendering before content has loaded.
For a detailed look at Google’s overall crawling mechanism – crawl budget, priorities, frequency – see my article on Google crawling and indexation.
What Google Sees After Rendering – And What It Misses
When Phase 2 completes successfully, Google sees the fully rendered state of the page. Text, internal and external links, structured data in JSON-LD format (even if the script tag was injected via JS), images with correct alt tags – all of this is indexable. How Google fundamentally parses and processes HTML – before rendering even comes into play – I cover in my article on HTML Parsing & SEO. Native HTML lazy loading (loading="lazy" attribute) is not a problem. Infinite scroll is trickier, but solvable through pagination with correct canonical URLs.
The Classic JS SEO Failures – Still Just as Relevant in 2026
In my technical SEO work, certain patterns keep appearing. The most frequent mistakes:
Setting canonical URLs via JavaScript: Google’s documentation is clear – canonical tags must be in the initial HTML, not set via JavaScript. If the canonical is only set after rendering, Google may treat the wrong URL as canonical – or no URL at all. This is especially critical for e-commerce sites with dynamically generated URL parameters.
Fragment-based routing (#): When your SPA uses fragment URLs (e.g., example.com/#/product/123), Googlebot sees these as a single page with fragments – not as separate pages. The correct solution is the browser’s History API, which generates clean URLs without fragments.
HTTP status codes via JavaScript: 404 pages that are only marked as “not found” client-side but return HTTP status 200 – this is a classic SPA problem. Google sees a 200 page and indexes it as empty or misleading content.
For a detailed overview of common structured data errors, see my article on FAQ Rich Results and schema markup – many of the foundational principles apply equally to JavaScript-generated markup. If you want to know whether structured data provides a specific advantage for AI Overviews, see my piece on structured data and AI Overviews.
AI Crawlers and JavaScript: The Overlooked Problem in 2026
This is the part that many 2026 JS SEO articles still overlook: Google’s ability to render JavaScript is the exception – not the rule. The vast majority of crawlers consuming your content work without JavaScript rendering.
An overview of the most relevant AI crawlers and their rendering status as of mid-2026 – individual platform infrastructure can change over time:
| Crawler / Bot | Operator | JavaScript Rendering | Platform |
|---|---|---|---|
| Googlebot / WRS | Yes – headless Chromium | Google Search, Google AI | |
| AppleBot | Apple | Partial (browser-like) | Siri, Spotlight |
| GPTBot / OAI SearchBot | OpenAI | No* | ChatGPT Search |
| ClaudeBot | Anthropic | No* | Claude / claude.ai |
| PerplexityBot | Perplexity AI | No* | Perplexity |
| Bytespider | ByteDance | No* | TikTok Search |
| Meta-ExternalAgent | Meta | No* | Meta AI |
* Observation, as of May 2026, no official vendor statement. Since crawler infrastructure can change at any time, site owners should regularly check their visibility in AI-powered search.
What does this mean in practice? ChatGPT and Claude do sometimes download JavaScript files, but they don’t execute them. They typically cannot read content that is only generated in the browser through client-side rendering. If your product descriptions, pricing, or main content are only rendered via JavaScript into the DOM, these crawlers see an empty page – or at best the HTML skeleton.
In my work with clients, this is no longer an abstract problem. At an e-commerce client running a Vue.js SPA without SSR, GPTBot traffic was simply zero. Not because the content was poor, but because GPTBot couldn’t see anything. Indexation in ChatGPT Search was effectively non-existent.
How AI crawlers affect overall traffic and visibility is a topic that goes beyond the scope of this article. Relevant in this context: Google has introduced a dedicated user agent for AI agents – what that means, I cover in my article on the Google user agent for AI agents. If you want to make your content specifically visible for AI searches, see the llms.txt guide. And how Google weights its algorithm for AI-powered search is covered in my piece on the Google algorithm: crawling, indexing and ranking.
Rendering Strategies Compared: CSR, SSR, SSG and Dynamic Rendering
The four common rendering approaches differ fundamentally in where and when HTML is generated (technical background: web.dev: Rendering on the Web):
Client-Side Rendering (CSR)
The browser receives a minimal HTML page with an empty <div id="app"></div>. JavaScript loads, executes, and only then generates the visible content. This is the classic SPA approach with React, Vue or Angular without server-side rendering.
For Google: Works after Phase 2 – but with delays and crawl budget costs. For all other crawlers: Usually invisible.
Server-Side Rendering (SSR)
The server renders the page fully on each request and delivers complete HTML. Next.js, Nuxt.js and Remix support SSR natively. Every crawler – Google, GPTBot, ClaudeBot – immediately receives complete HTML.
Downside: Server load under high traffic. Upside: Best crawlability for all bots, no rendering queue problem.
Static Site Generation (SSG)
HTML is generated once at build time and served as a static file. Astro, Next.js (getStaticProps), Nuxt.js (nuxt generate) or 11ty are typical SSG tools. Maximum performance, perfect crawlability for all bots, no server-side rendering overhead.
Limitation: Dynamic content (user-specific, real-time data) requires client-side loading or ISR.
Dynamic Rendering
Middleware detects crawlers via user agent and delivers statically pre-rendered HTML only to bots. Regular users receive the SPA. Since Google recommends SSR frameworks, dynamic rendering is officially a migration workaround – not a preferred approach for new projects.
The problem with dynamic rendering for AI crawlers: many AI bots aren’t included in standard bot-detection lists. You’d need to manually add GPTBot, ClaudeBot, PerplexityBot etc. and update the list as new crawlers emerge. That’s maintenance-heavy and error-prone.
| Strategy | Google SEO | AI Crawlers | Performance | Effort |
|---|---|---|---|---|
| CSR (SPA) | Risk (queue delay) | Invisible | Good post-hydration | Low |
| SSR | Very good | Very good | Higher TTFB | Medium |
| SSG | Very good | Very good | Optimal | Medium |
| Dynamic Rendering | Good (if correct) | Partial (manual) | Good for users | High (maintenance) |
| Hybrid (SSR + CSR) | Very good | Good | Good | High |
Framework Check: Which JavaScript Framework Is SEO-Friendly?
The framework doesn’t determine SEO success or failure. The rendering configuration does. That said, there are clear differences in how easily a framework enables good rendering:
Next.js is the market leader for React-based SSR and SSG projects. App Router, Server Components, getStaticProps and ISR (Incremental Static Regeneration) offer granular control over what gets rendered server-side versus client-side. Technically very strong for SEO when rendering modes are used deliberately – not on autopilot.
Nuxt.js is the Vue.js equivalent of Next.js and equally capable in rendering flexibility. SSR, SSG and hybrid modes are natively supported. The natural choice for teams with a Vue background.
Astro takes a different approach: “Islands Architecture” or “Partial Hydration.” By default, static HTML pages are served without any client-side JavaScript. JavaScript is only loaded where interactive components actually need it. From an SEO perspective – and especially from an AI crawler perspective – this is the cleanest approach. Downside: highly dynamic applications are more complex to build with Astro.
Remix is strongly oriented toward web standards and native browser APIs. Server-side rendering is the default. A very solid choice for content-driven sites.
Angular (without Universal) and plain React/Vue without SSR are no longer a viable option for SEO-relevant projects in 2026 if content needs to be visible to AI crawlers.
One technical aspect that often gets underestimated: oversized JavaScript bundles can cause timeouts during WRS rendering. The Googlebot 2 MB crawl limit applies to external resources too. Bundle splitting and code splitting are therefore not just performance optimizations – they’re directly SEO-relevant.
Monitoring: Detecting Rendering Problems in Search Console
Google has removed an outdated note from its documentation: the browser quick-check where you disabled JavaScript to see what Googlebot sees. That was a widespread method for years – it’s now outdated. The correct workflow:
URL Inspection Tool in Search Console: Returns the rendered HTML that Googlebot last saw, including a screenshot. Click “View tested page” – there you’ll see exactly which resources were loaded, which errors occurred, and how the page looks rendered. This is the most direct signal Google offers.
Rich Results Test: For JSON-LD validation and structured data verification. Shows whether Google can read your markup – whether it’s directly in the HTML or injected via JavaScript.
Lighthouse in Chrome DevTools: Provides performance metrics (LCP, CLS, INP) and shows how JavaScript rendering affects Core Web Vitals. High JavaScript execution times directly translate into poor INP scores. A complete optimization guide for all three metrics is in my article on Core Web Vitals: LCP, INP & CLS optimization.
Log file analysis: Server logs show when Googlebot crawls your pages (Phase 1) and when the WRS returns for rendering (Phase 2 – identifiable by the different user agent string of the Googlebot renderer). Large gaps between Phase 1 and Phase 2 signal that your pages are being given low priority in the rendering queue.
For broader technical SEO monitoring – including Core Web Vitals, crawl budget management and indexation status – see my articles on Google crawling and the indexation process.
Frequently Asked Questions (FAQ)
Does Google render JavaScript for all pages?
Yes – in principle, Google renders all pages with HTTP status 200 that aren’t excluded from rendering via robots meta tag or X-Robots header. However, the rendering happens asynchronously in a queue, not immediately on the first crawl. The delay between Phase 1 crawl and Phase 2 rendering can be several weeks for pages with low crawl frequency. For frequently crawled pages, the delay is significantly shorter, but rarely under a few hours.
Why don’t AI crawlers render JavaScript?
It comes down to infrastructure and cost: full JavaScript rendering with headless Chromium requires significant compute per crawled page. Google can afford this because rendering is built into the core infrastructure. AI crawlers like GPTBot, ClaudeBot or PerplexityBot are primarily optimized for rapidly ingesting large volumes of text. Headless browser rendering would reduce crawling speed by a factor of 10 to 100. That’s not scalable – neither for the crawler operators nor for the crawled servers.
Do I need to avoid JavaScript for good rankings?
No – avoiding JavaScript entirely is not a requirement. The requirement is that critical content (text, links, heading structure, structured data) is available in the initial HTML or delivered through server-side rendering. Interactive UI elements, animations, dynamic filter options – all of that should and can use JavaScript. The problem only arises when content-relevant material is generated exclusively through client-side rendering.
Is dynamic rendering a valid solution for JavaScript SEO?
As a migration workaround for existing SPAs – yes. For new projects – no. Google itself has removed dynamic rendering from its list of recommended solutions for new websites. The core problem: dynamic rendering is based on user-agent detection. That means you need to manually maintain and update the list of bots to serve, whenever new AI crawlers emerge. That’s error-prone. SSR or SSG solve the problem structurally, not symptomatically.
Can I inject JSON-LD structured data via JavaScript?
Technically it works – Google reads JSON-LD even when injected into the DOM via JavaScript, provided Phase 2 rendering completes successfully. For maximum reliability and AI crawler compatibility, it’s best to place JSON-LD directly in the initial HTML. If schema markup is only important for Google and you’re confident rendering is reliable, JavaScript injection is acceptable. For pages with high commercial importance, I’d take the safer route.
Conclusion: The Right Rendering Strategy for 2026
Google’s decision to drop the “disable JavaScript” recommendation from its docs is a signal: the war “Can Google render JS?” is won. Anyone who has migrated their stack to SSR or SSG in recent years is in good shape.
The new front is AI search. And there, the answer to the rendering question is still a clear no for most bots. In my work with clients, I see how underestimated this point is – especially in teams with a strong developer background who argue “but Google renders it.” True. GPTBot doesn’t. Perplexity doesn’t. And that’s becoming increasingly traffic-relevant.
The action framework for 2026 is clear: SSG as default for content-heavy pages, SSR where dynamic content is needed, client-side JavaScript only for interactive elements – never for content-relevant material. Dynamic rendering only as a migration workaround for legacy SPAs, not as a new-build approach.
Last updated: mid-2026. In particular, the information about JavaScript rendering behavior of AI crawlers is based on observation and may change as crawler infrastructure evolves. Recommendation: regularly audit AI search visibility via log analysis or dedicated crawler testing.
- Check initial HTML output in browser DevTools for completeness (don’t disable JS)
- Use URL Inspection Tool in Search Console, not the old “JS-off test”
- Set canonical URLs exclusively in the initial HTML
- Return HTTP status codes correctly server-side (no “soft 404” via JS)
- Place JSON-LD in the initial HTML, don’t inject it via JS after load
- Use Screaming Frog with GPTBot user agent for AI crawler visibility check
- Check JavaScript bundle size – anything over 2 MB is ignored by the WRS


