AI crawlers do not execute JavaScript
Key takeaways
- No major AI crawler executes JavaScript; they parse the raw HTML response and nothing else.
- Google is the exception, so a client-rendered page can appear in AI Overviews while being invisible to ChatGPT, Claude and Perplexity.
- One curl command with a crawler user-agent and a word count tells you whether you have this problem.
- Client-side injected JSON-LD does not exist as far as these crawlers are concerned.
- This is why static auditing matches reality instead of compromising on it.
No major AI crawler executes JavaScript. GPTBot, ClaudeBot and PerplexityBot fetch your raw HTML and parse what is in it — observed across hundreds of millions of fetches. If your content arrives via client-side rendering, those engines see an empty shell, and no amount of content strategy changes that.
What does the evidence actually say?
Large-scale fetch analysis of AI crawler traffic found no JavaScript execution by the major AI crawlers: they request the document, and whatever the server returns in that response is the entire page as far as they are concerned. The exception is Google, whose rendering infrastructure predates and is separate from its AI surfaces — so a client-rendered page can be visible to Google's AI results while being completely invisible to ChatGPT, Perplexity and Claude.
This is one of the few genuinely binary facts in this field. Most AEO advice is about degrees of better. This one is on or off.
What breaks in practice?
- Client-rendered single-page applications. The crawler receives a root div and a script bundle. Word count on arrival is often under fifty.
- Tabs and accordions populated by fetch calls. The visible content exists only after an XHR that never fires.
- Infinite-scroll or paginated lists. Only the first server-sent chunk exists; the rest of your catalog is unreachable.
- Cookie or consent walls that gate the DOM. If the content appears only after a click, it does not appear.
- Client-side injected structured data. JSON-LD written by a tag manager after load is not in the response body, so it is not there at all.
How do you test your own site in one command?
Fetch your page the way a crawler does, with no JavaScript, and count the words. If the number is small, you have found your problem:
curl -sA "GPTBot/1.4 (+https://openai.com/gptbot)" https://example.com/ | wc -w
Compare that against what you see in a browser. A page showing 1,200 words to a human and 60 to that command is invisible to every non-Google answer engine. Our audit performs exactly this comparison automatically across nine user-agents and grades it as body parity against a browser baseline.
| Architecture | What the crawler receives | Verdict |
|---|---|---|
| Static HTML | The complete document | Ideal |
| Server-side rendering | The complete document, generated per request | Ideal |
| Static site generation | The complete document, generated at build | Ideal |
| Hydration over server-rendered HTML | Complete, provided the server-rendered pass contains the real content | Verify the first byte |
| Client-side rendering only | An empty shell and a script tag | Invisible |
Why does this make static auditing sufficient?
Because the auditor and the engine are looking at the same bytes. A tool that spins up a headless browser to evaluate your page is measuring something no AI crawler will ever see, and paying for the privilege. Skipping rendering is not a cost saving that degrades the result; it is the only measurement that matches what the engines do. It also means a per-page check costs a few HTTP requests, so auditing ten thousand pages is arithmetic rather than a budget conversation.
If our fetcher cannot see it, neither can ChatGPT.
— the design principle behind the AnswerOpen engine
What is the fix?
- Server-render or pre-render every page you want cited. This is the whole fix; everything else is detail.
- Put your structured data in the server response, not in a tag manager.
- Make sure content hidden behind tabs, accordions and consent gates is present in the HTML even when collapsed.
- Give paginated content real, crawlable, server-rendered URLs.
- Re-run the curl check above afterwards and confirm the word count moved.
Further reading: crawlable is not indexed, the extractability checks in full, and the rest of the resources. Primary source on crawler behavior: OpenAI's published bot documentation.
Primary sources
Everything asserted above traces to one of these. Operator documentation changes often; check the current version before relying on any of it.
- OpenAI crawler documentation — the authoritative list of GPTBot, OAI-SearchBot and ChatGPT-User behavior
- Anthropic crawler documentation — ClaudeBot, Claude-SearchBot and Claude-User
- Perplexity bot documentation — PerplexityBot and Perplexity-User
- Server-side rendering (Wikipedia) — background on the rendering strategies compared above
Frequently asked questions
Do any AI crawlers render JavaScript?
Google's infrastructure renders, and its AI surfaces are downstream of that. The dedicated AI crawlers, including GPTBot, ClaudeBot and PerplexityBot, fetch the document and parse the response body without executing scripts.
How do I test my own site?
Fetch the page with a crawler user-agent and count the words: curl with an AI bot user-agent piped to a word count. Compare it with what a browser shows. A page showing 1,200 words to a human and 60 to that command is invisible to non-Google engines.
Does server-side rendering fix it completely?
It fixes the core problem, provided the server-rendered response genuinely contains the content rather than a loading state. Check the first byte, not the hydrated result, and move any structured data out of your tag manager into the server response.
What about content behind tabs or accordions?
It is fine if the markup is present in the HTML and merely hidden with CSS. It is invisible if the content is fetched when the control is clicked.
Does this mean my JavaScript site cannot rank at all?
It can still rank in Google, which renders. What it cannot do is get cited by the engines that do not, which is most of them.