JavaScript SEO

JavaScript SEO is the discipline of ensuring search engines can crawl, render, and index content delivered via JavaScript. The rise of single-page applications, client-side frameworks, and JavaScript-heavy CMS templates has made this one of the most common failure points in modern technical SEO.

How does Googlebot handle JavaScript?

Googlebot uses a two-pass indexing system:

  1. First pass. The HTML is fetched and processed for immediate indexing of any content present in the initial server response.
  2. Second pass (rendering). The page is queued for rendering by the Web Rendering Service, which runs the JavaScript and produces the final DOM. The rendered output is then processed for indexing.

The rendering queue is not instant, but the delay is smaller than it is often described. Google’s own documentation says a page “may stay on this queue for a few seconds, but it can take longer than that”.1 Treat seconds as the normal case and longer waits as the exception that affects lower-authority or very large sites, rather than assuming days by default. The delay still matters for time-sensitive content, because JavaScript-dependent content cannot be indexed until the render pass completes.

Other crawlers have varying levels of JavaScript support. Bing says bingbot “is generally able to render JavaScript”, while cautioning that it cannot do so reliably at scale across every page of every site.2 Most of the crawlers that build AI retrieval indexes do not execute JavaScript at all, which means client-side-rendered content is effectively invisible to them (see JavaScript SEO and AI search below).

What is render budget?

“Render budget” is an SEO-community term, not a label Google uses or a figure it publishes. It extends the more familiar crawl budget idea: where crawl budget describes how many URLs Googlebot will fetch, render budget describes the finite computational resources Google’s Web Rendering Service spends executing JavaScript on the pages it has already fetched. Treat it as a useful mental model for why the second pass is rationed, not as a documented mechanism with a number attached.

The concept matters because the second pass is far more expensive than the first. Executing JavaScript in a headless browser, waiting for the DOM to settle, and re-extracting content costs Google materially more than parsing static HTML, with practitioner estimates putting the difference at roughly an order of magnitude.3 Because that capacity is shared across the whole web, pages that depend on JavaScript to produce their content, links, or structured data sit in the rendering queue longer, and lower-authority sites tend to wait longest.

The consequences are the same ones the rendering models and common-problems sections address, viewed from the cost side:

  • Content that only exists after rendering is indexed late, or not at all. Until the second pass completes, Google’s stored version of the page is the unrendered shell.
  • JavaScript-generated internal links may not be followed promptly. If discovery of deeper pages depends on links that only appear after rendering, crawl of the rest of the site is gated behind the render queue.
  • The effect compounds on large, JavaScript-heavy sites. The more URLs that require rendering, the more the limited render capacity is spread thin.

The mitigation is unchanged: move SEO-critical content, links, and metadata into the initial server response through static rendering or SSR, so indexing never depends on the second pass. Reducing render-budget pressure is a side benefit of building this way, not a separate technique. Dynamic rendering can lighten the load for bots in the short term, but Google treats it as a workaround rather than a fix.4

Rendering models

Static rendering. Pages are generated at build time and served as fully-formed HTML. Best for SEO; Googlebot sees everything in the first pass; AI crawlers can extract content without rendering. Examples: Astro, Next.js Static Generation, Hugo, Jekyll.

Server-side rendering (SSR). Pages are generated on each request and served as fully-formed HTML. Equivalent to static rendering for SEO purposes. Examples: Next.js SSR, Nuxt SSR, Remix.

Hybrid / Incremental Static Regeneration. A mix of static and SSR. Most pages are pre-built; some are generated on demand. Equivalent to static for SEO when configured correctly.

Client-side rendering (CSR). Pages are served as a minimal HTML shell with JavaScript that fetches data and renders the content in the browser. Worst for SEO; the initial HTML contains no content; rendering depends on JavaScript execution by the crawler. Examples: traditional Create React App, Vue with no SSR.

Dynamic rendering. A workaround where the server detects bot user agents and serves a pre-rendered HTML version, while users get the client-side version. Google previously recommended this and no longer does. Its documentation is now headed “Dynamic rendering as a workaround” and opens by saying dynamic rendering “was a workaround and not a long-term solution”, recommending server-side rendering, static rendering or hydration instead.4 Use only as a transitional measure on a site that already has it.

For new builds, default to static or SSR. Client-side rendering is acceptable for authenticated dashboards and tools that don’t need to be indexed; it is not appropriate for content pages.

Common JavaScript SEO problems

Content rendered after user interaction. Content that only loads after a click, scroll, or hover is not seen by Googlebot. Tabbed content, “load more” buttons, accordions, and infinite scroll all need to be implemented carefully so the content is in the initial render.

Async content fetched from APIs. When content is fetched client-side from an API, the initial HTML doesn’t include it. Googlebot’s second pass may eventually capture it, but with delay and reduced reliability. Server-render or pre-render this content.

JavaScript-generated meta tags. Title tags, meta descriptions, and canonical tags injected by JavaScript can be missed or mis-prioritised. Render these server-side.

Hash-based URLs (/#/page). Fragment URLs are not separate pages from a crawler perspective. They aren’t indexed independently. Use the History API to produce real URLs.

Render-blocking JavaScript. Heavy synchronous JavaScript in the page head delays rendering, hurting both Core Web Vitals and Googlebot’s ability to process the page within reasonable time bounds.

Infinite scroll without pagination. Content loaded only through scroll triggers is hard for crawlers to access. Implement true pagination URLs underneath the infinite scroll behaviour.

Debugging JavaScript rendering

Search Console URL Inspection. Shows the rendered HTML and screenshot for any URL, as Googlebot saw it. Compare to what users see; differences indicate rendering problems.

Rich Results Test. Renders pages with Googlebot’s rendering engine and reports what it sees. The Mobile-Friendly Test was retired in December 2023; Rich Results Test and URL Inspection are the current alternatives for checking rendering.

Crawl with JavaScript rendering enabled. Screaming Frog and Sitebulb both support JavaScript-rendered crawling. Compare HTML-only crawls to JavaScript-rendered crawls; large differences indicate content that is invisible to non-rendering crawlers.

Disable JavaScript in your browser. Open the page with JavaScript disabled. What’s visible is approximately what AI crawlers and basic indexers see. If critical content disappears, that content is not reaching them.

Hydration and selective rendering

Modern frameworks increasingly support partial or selective hydration: rendering most of a page server-side and only hydrating specific interactive components on the client. Astro Islands, React Server Components, and similar approaches make it possible to deliver mostly-static HTML with interactive enhancements where needed.

For SEO, the goal is to maximise the content visible in the initial server response. Interactive components (forms, menus, dynamic widgets) can be client-rendered without affecting indexing as long as the underlying content they enhance is server-rendered.

The crawlers that build AI retrieval indexes do not execute JavaScript. MERJ and Vercel tested this directly, across both Next.js and other stacks, and found that “none of the major AI crawlers currently render JavaScript”, naming GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot, Meta-ExternalAgent, Bytespider and Common Crawl’s CCBot.5 They fetch raw HTML and move on: there is no deferred rendering pass and no headless browser behind them. Claude-SearchBot did not exist when that study ran, so read its inclusion here as inference from Anthropic’s other crawlers rather than something anyone has measured.

A common misreading of log data is that AI crawlers “fetch JavaScript”, so they must process it. A December 2024 study by MERJ and Vercel found ClaudeBot requested JS files in 23.84% of its crawls; ChatGPT’s in 11.50%.5 These proportions shift as crawler behaviour evolves, but the underlying dynamic is consistent: these are static file downloads, not execution. The measurement is of behaviour rather than capability, and none of the operators documents rendering support either way, so the finding is that these crawlers do not run the code they download.

One thing they can read that a Googlebot-shaped mental model would not predict is data embedded in the initial HTML response. The same study notes that “content included in the initial HTML response, like JSON data or delayed React Server Components, may still be indexed since AI models can interpret non-HTML content”.5 The constraint is execution, not format: a JSON-LD block or a server-rendered payload in the first response reaches them, while anything a browser has to build does not.

Each major AI company operates distinct bots for different purposes: Anthropic runs ClaudeBot (training data), Claude-SearchBot (search index), and Claude-User (live per-user fetches); OpenAI runs GPTBot (training data), OAI-SearchBot (search index), and ChatGPT-User (live fetches). All share the same no-JavaScript constraint. For citation visibility, the search-index bots (OAI-SearchBot and Claude-SearchBot) are the ones that matter.

There are two exceptions. Google AI Overviews runs on Googlebot’s infrastructure and inherits its full headless-Chromium rendering, and Applebot renders through a browser-based crawler in the same way, processing JavaScript, CSS and Ajax requests.5 A React SPA may therefore appear complete in AI Overviews and to Apple’s systems while being invisible to ChatGPT, Claude and Perplexity. SSR is not a requirement for those two; it is a requirement for the rest.

Do agentic browsers render JavaScript?

Yes, and the distinction between a crawler and an agent matters. ChatGPT’s agent mode, ChatGPT Atlas and Perplexity’s Comet drive a real browser on the user’s behalf, so they see a page after its JavaScript has run, in the way a human visitor does. Chrome has started building for this surface: PageSpeed Insights now carries an Agentic Browsing category scoring how readable and operable a page is for an agent.

This does not rescue a client-side-rendered site. Agentic browsing is a live fetch of a page the agent has already decided to visit, and that decision is made from a retrieval index built by crawlers that do not render. Server-rendering governs whether you are found in the first place; browser-based agents govern what happens once they arrive.

How does ChatGPT retrieve pages?

ChatGPT’s retrieval path is not documented by OpenAI, and what has been observed of it keeps moving. A Search Engine Land analysis in October 2025 found that in 92% of agent-mode tests the agent relied on the Bing Search API, which overlaps with Bing’s SERP without mirroring it.6 Microsoft retired the Bing Search APIs in August 2025 and directed customers to its Azure grounding products,7 so the plumbing behind that finding has since changed. Research published in July 2026 indicates that ChatGPT web search routes queries through several undisclosed retrieval pipelines, one of which supplied 88.1% of primary sources in the largest sample tested.8 None of it is confirmed by OpenAI.

The conclusion survives the uncertainty. Whichever pipeline answers a query, the fetchers that reach your server do not run your JavaScript, so content that exists only after client-side rendering is not available to any of them.

For sites where AI citation visibility matters, server-rendering is the deciding factor. The “disable JavaScript in your browser” test in the debugging section above approximates what the AI indexing crawlers see.

Frequently asked questions

Can Google crawl, read, and render JavaScript?

Yes, but not in a single step. Googlebot crawls the raw HTML in its first pass and can read any content already present in that server response immediately. Content produced by JavaScript is different: Google reads it only after rendering, which happens on a separate, deferred pass through the Web Rendering Service (see How does Googlebot handle JavaScript? above). So Google can read and render JavaScript, but JavaScript-dependent content is read later than static HTML and occasionally not at all if rendering fails. The major AI crawlers apart from Applebot download JavaScript files but do not execute them, so content that only appears after rendering is invisible to them.

Can Googlebot render React?

Yes. Googlebot uses a recent version of Chromium and can execute modern JavaScript including React, Vue, and Angular. The constraints are timing (rendering happens in a separate pass, not in real time) and reliability (rendering occasionally fails for individual pages).

Should I server-render dynamic dashboards?

Generally no. Dashboards behind authentication don’t need to be indexed; client-side rendering is appropriate. Server-render content pages and let the dashboard remain client-side.

Does using noscript tags help?

Marginally. <noscript> content is processed by Google but should be a fallback, not a primary content delivery mechanism. The right answer is to render the actual content server-side.

Does server-side rendering help with Google AI Overviews?

Not in the same way it helps with other AI crawlers. Google AI Overviews uses Googlebot, which renders JavaScript, so SSR does not determine whether AI Overviews can see your content. What SSR does is avoid the second-pass indexing delay, ensuring content enters Google’s index faster. For AI citation visibility on non-Google surfaces (ChatGPT Search, Perplexity, Claude), server-rendering is the deciding factor.

Footnotes

  1. Understand the JavaScript SEO basics — Google Search Central

  2. bingbot Series: JavaScript, Dynamic Rendering, and Cloaking. Oh My! — Bing Webmaster Blog

  3. From crawl budget to render budget — Botify

  4. Dynamic rendering — Google Search Central 2

  5. The rise of the AI crawler — Vercel 2 3 4

  6. ChatGPT Agent Mode: what the data reveals — Search Engine Land

  7. Bing Search APIs retiring on August 11, 2025 — Microsoft Lifecycle

  8. ChatGPT citations change when hidden search pipelines switch — Search Engine Land