Field notes
Do AI crawlers render JavaScript? What GPTBot and ClaudeBot see
Googlebot and Applebot run your scripts. GPTBot, ClaudeBot and PerplexityBot read only the raw HTML. What each crawler sees and how to check your own pages.
Open one of your product pages in a browser and it looks complete: name, price, sizes, stock. Now fetch the same URL with curl. If the response is a <div id="root"></div>, a few script tags and nothing else, you are looking at the page most AI crawlers get.
Google renders JavaScript, so a client-rendered page can do fine in Google Search. The crawlers behind ChatGPT, Claude and Perplexity were measured not running scripts, even when they downloaded them. For them, content that appears only after JavaScript runs is not on the page.
This post covers which crawlers render JavaScript and which don't, what a non-rendering crawler actually sees, how to check your own pages and what to fix first.
Who renders and who doesn't
The most cited measurement is Vercel and MERJ's December 2024 analysis of crawler traffic on nextjs.org and Vercel's network, checked against two job boards on different stacks: "none of the major AI crawlers currently render JavaScript" (Vercel). The search engines document their own behavior.
| Crawler | Runs JavaScript | Source |
|---|---|---|
| Googlebot | Yes, with an evergreen Chromium | |
| Applebot | May render pages in a browser | Apple |
| Bingbot | Renders, but asks you not to depend on it | Bing |
| GPTBot, OAI-SearchBot, ChatGPT-User | No | Vercel |
| ClaudeBot | No | Vercel |
| PerplexityBot | No | Vercel |
| Meta-ExternalAgent | Not in 2024; a 2026 test saw its Chrome-based version run scripts | Vercel, JS SEO Lab |
| Bytespider, CCBot | No | Vercel |
A few details change how you read that table.
- Google's AI features ride on Googlebot. Vercel found that Gemini uses Googlebot's infrastructure and renders fully. For AI Overviews and AI Mode, Google says a page must be indexed and eligible to appear in Search with a snippet, with "no additional technical requirements" (Google).
- Bing renders, with a warning. Bing's guidelines list "hiding critical content behind client-side rendering" as something to avoid, and say content that can't be reliably rendered "may not be indexed or selected for grounding results" (Bing). In one 2026 test, Bingbot never followed a JavaScript-only link in 20 days of crawling (Search Engine Land).
- The AI operators don't say. OpenAI's crawler docs, Anthropic's crawler page and Perplexity's crawler docs say what each bot is for, not whether it runs scripts. The measurement is from late 2024, and newer independent tests mostly agree. In a 41-day test published in August 2026, GPTBot, ClaudeBot, OAI-SearchBot, ChatGPT-User and PerplexityBot never reached a page linked only by JavaScript (Search Engine Land). A smaller 2026 test saw GPTBot run a simple inline script a handful of times, but never a React app (JS SEO Lab). Claude-SearchBot is untested in both. Plan as if they read only the HTML.
A browser user agent doesn't mean a browser
Two things in your logs can make a crawler look more capable than it is.
The user agent string. OAI-SearchBot's documented user agent starts with Mozilla/5.0 (Macintosh; ...) Chrome/131.0.0.0 Safari/537.36 before naming itself (OpenAI), yet it is on Vercel's list of bots that don't render.
Requests for script files. Vercel saw JavaScript files make up 11.50% of ChatGPT's crawler fetches and 23.84% of Claude's on nextjs.org, yet neither executed them (Vercel). Downloading main.js is not the same as building your page.
Browser agents are the exception. They drive a real browser for a person, so they run your scripts like any visitor, a split we describe in the field guide to AI visitors. Even there, when OpenAI launched ChatGPT agent it described both a visual browser and "a text-based browser for simpler reasoning-based web queries" (OpenAI), and the agent chooses which to use.
What a non-rendering crawler sees
A crawler that doesn't run scripts gets only the bytes your server sent. In practice:
- Client-rendered content is missing. Prices, specs, stock and policies fetched after load are not there. Vercel's advice is to server-render main content, metadata and navigation, and keep client-side rendering for extras such as view counters and chat widgets (Vercel).
- Data in the HTML may still count. Vercel notes that content included in the initial response, "like JSON data or delayed React Server Components, may still be indexed since AI models can interpret non-HTML content." That is a possibility, not a promise.
- Tags added by scripts are invisible. Google can pick up a canonical link or JSON-LD that JavaScript injects, though it recommends setting the canonical in HTML (Google). A crawler that never runs the script never sees either.
- Links added by scripts aren't followed. Google parses links again after rendering (Google). A crawler that doesn't render only finds the
<a href>links in the original HTML, so pages reachable only through script-built menus may never be found. - Every route looks like a page. A single-page app often answers 200 for any path and shows "not found" only after scripts run. Google calls this a soft 404 and suggests redirecting to a URL that returns a real 404, or adding
noindexwith JavaScript (Google). The second fix only works for crawlers that run scripts. More in why AI agents hit your 404 pages.
How to check a page
You don't need a crawler to see what a crawler sees.
- Fetch the raw HTML and look for the facts. Pick something only the rendered page would show, such as the price:
curl -sL https://yourdomain.com/products/trail-jacket | grep -cF "184.00"
A count of 0 means the price arrives through JavaScript. A match inside a script tag or JSON blob means the data is in the response, but not necessarily readable as page text. View Source in a browser shows the same thing; Inspect shows the page after scripts ran, so it can't answer this question.
- Don't judge by size. On 17 October 2026, Bing's webmaster guidelines page answered our plain fetch with about 126 KB of HTML whose only readable message was "You need to enable JavaScript to run this app." The guideline text quoted above appeared only after rendering in a headless browser. Search for the text, not the byte count.
- Don't treat Google's tools as the answer for everyone. The URL Inspection tool shows the HTML Googlebot received (Google), and Googlebot renders. A page that passes there can still be blank to GPTBot.
- Check robots.txt for the renderers. Google won't render JavaScript from blocked files (Google), and Apple says Applebot may not render a page properly if the scripts, CSS or XHR requests it needs are blocked in robots.txt (Apple). Disallowing
/static/to save crawl budget can break rendering for the crawlers that do run scripts.
What to fix first
- Server-render or pre-render the facts. Google recommends server-side rendering, static rendering or hydration, and describes dynamic rendering as "a workaround and not a long-term solution" (Google).
- If you must use dynamic rendering, keep the content the same. Pre-rendered HTML for bots and the client-rendered app for people isn't cloaking for Google if the content is similar. Different content is (Google).
- Put the title, description, canonical and structured data in the first response. They are small and cheap to move server-side.
- Use real links and real status codes. An
<a href>for every page you want found, and a 404 for pages that don't exist. - Leave the extras client-side. Chat and live counters can load after the page.
The other walls agents hit, from challenges to custom controls, are in where agents get stuck. If a page is fine in curl and agents still don't read it, check whether the request reached your server at all: your firewall may block AI agents that robots.txt allows.
How Ethogram helps
Ethogram runs on your server, not in the browser, which is how it sees crawlers that never run JavaScript (docs). When your collector forwards the response and an agent keeps retrying a page, Ethogram looks for a reason, and one of them is JavaScript-only page: a 200 HTML page under 2 KB served to an agent that doesn't run JavaScript, meaning anything but a browser agent (why agents get stuck). Loop insights name the most common reason. It needs the response size, which streamed pages often don't send. Size only catches the smallest shells, as the Bing example shows, so pair it with the curl check. Each agent's profile compares versions of its user agent, including the share of visits that fetched a JavaScript file, so a crawler that starts or stops fetching scripts after an update stands out (agent versions). The Pages tab lists the 200 paths named agents requested most this week and which classes read each, so you know where to run the curl check first (Pages). Pricing includes a free trial.
If you want to know which of your pages AI crawlers read and where they find an empty shell, see how Ethogram works.
- crawlers
- agent readiness
- agent traffic