JavaScript SEO
Last updated
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:
- First pass. The HTML is fetched and processed for immediate indexing of any content present in the initial server response.
- 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 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 practical 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; in 2022 Google updated its documentation to label dynamic rendering a workaround rather than a recommended approach.4 Use only as a transitional measure.
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.
JavaScript SEO and AI search
The crawlers that build AI retrieval indexes do not execute JavaScript. GPTBot, OAI-SearchBot, ClaudeBot, Claude-SearchBot, and PerplexityBot all fetch raw HTML and move on. There is no deferred rendering pass and no headless browser behind them.
A common misreading of log data is that AI crawlers “fetch JavaScript”, so they must process it. A December 2024 Vercel study found ClaudeBot requested JS files in roughly 24% of its crawls; GPTBot in roughly 12%.5 These proportions shift as crawler behaviour evolves, but the underlying dynamic is consistent: these are static file downloads collected as training data, not execution. The crawlers cannot run the code they download.
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.
The exception is Google AI Overviews, which runs on Googlebot’s infrastructure and therefore inherits its full headless-Chromium rendering. A React SPA may appear completely in AI Overviews while being invisible to every other AI citation surface. SSR is not a requirement for Google’s AI feature; it is a requirement for everything else.
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 practical 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, and the distinction matters. 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. Non-Google crawlers, including every major AI crawler, 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
-
Understand the JavaScript SEO basics — Google Search Central ↩
-
bingbot Series: JavaScript, Dynamic Rendering, and Cloaking. Oh My! — Bing Webmaster Blog ↩
-
ChatGPT Agent Mode: what the data reveals — Search Engine Land ↩
-
Bing Search APIs retiring on August 11, 2025 — Microsoft Lifecycle ↩
-
ChatGPT citations change when hidden search pipelines switch — Search Engine Land ↩