JavaScript rendering: what AI crawlers see
A page built with React, Vue or Angular can look complete in every browser and still be empty to the systems deciding whether to quote it. The page a person sees and the page a crawler receives are not always the same document, and the gap between them is JavaScript. Google closes that gap by running your JavaScript. Most AI crawlers do not, which quietly turns a solved SEO problem into a live AI visibility problem.
What rendering is, and why it now splits your audience
These two approaches have names developers use as shorthand: SSR for server-side rendering, CSR for client-side rendering. With server-side rendering, or static rendering, the HTML that leaves your server already contains the content: the text, the links, the metadata. With client-side rendering, the server sends a near-empty shell plus JavaScript, and the content only exists after that JavaScript runs on the visitor's machine. Google's documentation names the extreme case: "Some JavaScript sites may use the app shell model where the initial HTML does not contain the actual content and Google needs to execute JavaScript before being able to see the actual page content that JavaScript generates" (Google's JavaScript SEO guide).
That split produces two different documents. The raw HTML is what your server returns to anyone who asks for the URL. The rendered DOM is what exists after a browser, or something acting like one, has executed the page's JavaScript. Every question in this article comes down to which of those two documents a given bot receives.
For Google, the answer has been settled for years: it gets the rendered DOM. Google Search "runs JavaScript with an evergreen version of Chromium", and its pipeline processes pages in three phases, "Crawling", "Rendering" and "Indexing". Google also states that "All pages with a 200 HTTP status code are sent to the rendering queue, no matter whether JavaScript is present on the page." The old alarm that JavaScript is bad for SEO is out of date. So is most of the folklore around it: Google's current documentation describes no five-second render timeout and no two-waves-of-indexing model, only the plain statement that a page "may stay on this queue for a few seconds, but it can take longer than that."
For years, then, "does the crawler render?" had one answer that mattered, because one crawler mattered. That is no longer true. The systems now reading your pages include the crawlers behind ChatGPT, Claude and Perplexity, and they did not inherit Google's rendering pipeline.
Do AI crawlers render JavaScript?
Most do not. That claim is repeated more often than it is evidenced.
Start with the vendors, who say nothing. OpenAI, Anthropic and Perplexity all publish documentation for crawlers including: GPTBot, OAI-SearchBot and ChatGPT-User from OpenAI, ClaudeBot, Claude-SearchBot and Claude-User from Anthropic, PerplexityBot and Perplexity-User from Perplexity. Those pages cover robots.txt user agents and published IP ranges (OpenAI's crawler documentation is typical). None of them states whether the crawler executes JavaScript. There is no policy to quote in either direction.
Google, though, concedes the point about everyone else, twice, in its own documentation. Its JavaScript guide advises: "Keep in mind that server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript." Its dynamic rendering page is blunter still: "Other search engines may choose to ignore JavaScript and won't see JavaScript-generated content" (Google on dynamic rendering).
Then came the measurements. In December 2024, Vercel and MERJ analyzed network logs from Vercel's own hosting platform, covering GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot, Meta-ExternalAgent, Bytespider and CCBot: "The results consistently show that none of the major AI crawlers currently render JavaScript" (Vercel and MERJ's crawler study). The detail worth keeping is that ChatGPT's and Claude's crawlers downloaded JavaScript without running it: "while ChatGPT and Claude crawlers do fetch JavaScript files (ChatGPT: 11.50%, Claude: 23.84% of requests), they don't execute them. They can't read client-side rendered content." One caveat on the source: Vercel sells hosting whose selling point is server-side rendering, so the study's recommendation aligns with its business, and the measurement is of its own network logs.
Not every crawler belongs in that group. "Google's Gemini leverages Googlebot's infrastructure, enabling full JavaScript rendering." Likewise, "AppleBot renders JavaScript through a browser-based crawler, similar to Googlebot." So the sweeping version, that no AI crawler renders JavaScript, is false. The accurate version is narrower: the bots measured in that test do not render, while Gemini, AppleBot and Bing do. Claude-SearchBot was not among the bots tested, and Anthropic documents no rendering behavior for it.
In August 2025, Glenn Gabe tested the same question from the other end, platform by platform (Glenn Gabe's rendering case study). He took a fully client-side-rendered site, asked each platform to retrieve specific content from specific URLs, and used non-JavaScript pages as a control group. ChatGPT reported that "it could not read the content of the page because it relied on JavaScript-based rendering": the platform diagnosed itself. "Perplexity simply failed at finding the content for every url I tested", and the site blocked no bots in robots.txt, so this was a rendering failure, not an access problem. Claude reported "the url was returned without any visible content". The control pages retrieved fine on all three platforms. Bing belongs on the rendering side too: "Bing can render JavaScript-based content fine", and so "for Bing, Search with Copilot is not being affected either".
The same study surfaced a symptom most people never connect to rendering. The site's favicon fell back to a generic default in ChatGPT and Perplexity while remaining correct in Google and Bing, and its URLs were demoted into ChatGPT's "More" and Perplexity's "Reviewed" lists rather than appearing as cited sources with a snippet. If your pages keep landing in those lists with a default icon and no quoted text, rendering is worth ruling out.
Two limits keep this finding in perspective. First, the rule this evidence supports is "be in the initial HTML response", not "avoid JavaScript": "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." Second, all of this is measured behavior, not published policy, and any of these vendors could ship a rendering pipeline without announcing it. Gabe's framing is the right one: "it's important to understand how those systems work now".
What a non-rendering crawler actually receives
For a crawler that does not execute JavaScript, the raw HTML is the whole story. The page is the server's response, byte for byte. If your content, navigation and metadata only appear after hydration, the crawler's copy of your page is the shell: script tags, an empty root element, and whatever the server happened to include around them.
Checking this costs nothing. Fetch the raw HTML, or load the page in a browser with JavaScript disabled, and read what is left. Gabe's instruction is exactly that: "Simply turn off JavaScript and check your pages." There is a reversal worth naming here. For years the standard advice was that testing with JavaScript off tells you little, and for Googlebot that is still true, because Google renders. It is the AI crawlers that made the old test useful again.
curl -s https://example.com/page In whatever comes back, look for four things:
- The main content. Is the text a crawler would quote you for present in the response, or does it arrive only after JavaScript runs?
- The links. Google's guide notes that "Google can only discover your links if they are
<a>HTML elements with anhrefattribute", and a crawler that never runs your router's click handlers is in a stricter position still. - The metadata. The
<title>and meta description should be in the response, not injected later. - The structured data. Whether your JSON-LD survives in the raw response is its own problem, covered next.
Not every pixel needs to be server-rendered. The question is whether the substance a crawler would cite survives without JavaScript. A page whose raw HTML is mostly script tags and an empty root has nothing for a non-rendering fetcher to read; a page whose raw HTML carries the article text, real links and metadata has already done the work, whatever JavaScript adds on top.
Structured data that only exists after hydration
Injecting JSON-LD with JavaScript is not a mistake by Google's rules. The guidance is explicit: "you can use JavaScript to generate the required JSON-LD and inject it into the page" (Google's JavaScript SEO basics). Google renders, so Google sees it. The question is the audience. A crawler that never runs your JavaScript never sees that JSON-LD, so every schema block you inject client-side, however valid, does not exist for exactly the engines this article is about. The leading JavaScript SEO guides do not mention this gap.
Google already leans the same way for a related signal: "The best way to set the canonical URL is to use HTML, but if you have to use JavaScript, make sure that you always set the canonical URL to the same value as the original HTML." The principle generalizes. Signals that matter belong in the HTML the server sends. If your JSON-LD, canonical URL, title or meta description are injected client-side, move them into the server response: they are small, static and cheap to render there, and they sit where every fetcher can see them.
Fixing it: render on the server, once, for everyone
The fix is to put critical content in the initial HTML response. Server-side rendering, static site generation and pre-rendering all achieve it, and the mainstream frameworks ship it: Next.js, Nuxt and SvelteKit all render on the server unless you opt out. Google recommends the same for the same reason: its "not all bots can run JavaScript" advice quoted earlier is attached to exactly this recommendation. Vercel's version, from its study, is the compact one: "Prioritize server-side rendering for critical content." Critical means the main content, the metadata, the navigation and the structured data.
Client-side rendering stays fine for enhancement. Counters, chat widgets, dashboards behind a login, interactive UI: nothing is lost when a crawler cannot see them. The test is whether a value should be quotable. If a price or a stock figure belongs in an answer about you, it belongs in the server response too.
One tempting shortcut deserves a warning. Dynamic rendering, meaning detecting bots and serving them a pre-rendered snapshot while people get the JavaScript app, was the industry's answer to this exact problem a few years ago. Google deprecated it: "Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines. Instead, we recommend that you use server-side rendering, static rendering, or hydration as a solution" (Google's deprecation notice). And it is bot detection by definition: "Dynamic rendering requires your web server to detect crawlers (for example, by checking the user agent)."
The obvious objection is fair: Google's deprecation is written for Google Search, which renders, and the reasoning does not obviously transfer to bots that do not. But the conclusion holds anyway. A second, bot-only version of your site is the added complexity and resource cost Google warned about, it depends on user-agent strings anyone can spoof, and it puts you one step from serving different content to bots and people. Google draws that line itself: "Googlebot generally doesn't consider dynamic rendering as cloaking", but "Using dynamic rendering to serve completely different content to users and crawlers can be considered cloaking." One server-rendered document for everyone is simpler and safer than a rendering layer that has to guess who is asking. If your content is in the HTML your server sends, every crawler in this article, rendering or not, receives the same complete page.
FAQ
Do AI crawlers render JavaScript?
Most do not: in Vercel and MERJ's December 2024 measurements, none of the major AI crawlers, including GPTBot, ClaudeBot and PerplexityBot, rendered JavaScript, and ChatGPT's and Claude's crawlers even fetched JavaScript files without executing them. Gemini and AppleBot do render, and Bing renders JavaScript too, so Copilot is unaffected.
Can ChatGPT see my client-side rendered content?
Not reliably. In August 2025 testing, ChatGPT itself explained that it could not read a client-side rendered page because the content depended on JavaScript, while ordinary server-rendered pages elsewhere retrieved fine in the same tests.
Is JavaScript bad for SEO?
No. Google runs JavaScript when it indexes, and sends 200-status pages to its rendering queue, so client-side rendering is much less of a visibility risk there, though rendering can still fail on blocked resources. The exposure today is with AI crawlers, not with Google.
How do I check what a crawler sees on my page?
Fetch the page's raw HTML with a tool like curl, or browse it with JavaScript disabled, and check whether the main content, the links and the structured data are still present.
Should I serve a different version of my page to bots?
No. Google deprecated dynamic rendering as a workaround, it depends on detecting crawlers by user agent, and server-side or static rendering solves the same problem for every visitor at once.
See if AI can read, trust, and cite your site
Add to ChromeFree · No signup · Every issue links back to a guide like this one