All posts
Rendering

Can AI crawlers read your site? the rendering problem, measured

By Jānis Plūme, Founder, Outbound Pros · 12 min read · 2026-08-06

Quick answer

No, the major AI crawlers do not execute JavaScript. GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot and PerplexityBot read whatever HTML arrives in the first response and nothing else. A client rendered React, Vue or Angular site sends them an empty root element and a script tag, so the page is functionally blank to every one of them. Googlebot and Bingbot do render, which is why a site can look perfectly healthy in Search Console and still contribute nothing to a ChatGPT answer. The fix is prerendering, static generation or server side rendering. The test takes one command and it is included below.

Do AI crawlers execute JavaScript?

No. On every public measurement available, the crawlers that build AI answer surfaces fetch HTML, do not run scripts, and read only what arrived in the initial response.

The evidence base is thinner than the confidence with which people repeat it, so here is exactly what it consists of. Vercel and MERJ published a server log study on 17 December 2024, run against nextjs.org and cross validated on two unrelated stacks, one on Next.js and one on a custom framework. They found no JavaScript execution by any major AI crawler. ChatGPT's agents fetched JavaScript files in 11.50% of requests and Claude's in 23.84%, then did nothing with them. The study's stated conclusion was that the crawlers cannot read client side rendered content. Microsoft Copilot was excluded from the study because it does not use a unique user agent.

Since then, every 2026 source that claims to have retested reports the same result, and no credible measurement contradicts it. The weakness worth naming is that most of those 2026 sources are re-citing the December 2024 work instead of re-running it. We label this strong and not confirmed for exactly that reason. It is the right assumption to build on and it is worth re-testing yourself instead of trusting the field's collective memory. We intend to re-run it on our own properties and publish what we get.

None of the three vendors documents rendering behaviour. OpenAI, Anthropic and Perplexity all publish crawler pages describing purpose, user agent strings, IP ranges and robots.txt handling, and all three are silent on rendering. That silence is why the answer has to come from server logs rather than documentation.

Which surfaces render JavaScript and which do not?

Two groups, and the split does not follow company lines. It follows whether the fetcher is a search index crawler or an answer time fetcher.

SurfaceRenders JavaScriptConfidenceBasis
Googlebot, which feeds AI Overviews and AI ModeYesConfirmedGoogle's own guide states it processes content within JavaScript as long as it is not blocked. Deferred second pass, budget limited
Bingbot, which feeds Copilot and candidate retrieval for ChatGPTYesConfirmedEvergreen Bingbot has run on Chromium based Edge since the 2019 to 2020 rollout
ChatGPT Atlas browser and agent modeYesStrongBoth operate inside a real Chromium session. These are user driven, not the crawlers that build the retrieval set
GPTBot, OAI-SearchBot, ChatGPT-UserNoStrongVercel and MERJ, plus consistent 2026 replication
ClaudeBot, Claude-SearchBot, Claude-UserNoStrongSame
PerplexityBot, Perplexity-UserNoStrongSame

Read the table with the pipeline in mind rather than the brand. Bing renders and can therefore hand ChatGPT a candidate URL. OAI-SearchBot then fetches that URL itself to pull the sentence it will quote, and it does not render. Being findable and being quotable run through two different fetchers with two different capabilities.

What does an AI crawler actually receive from a single page app?

A shell. Typically a head with your title, meta description and any JSON-LD you injected server side, then a body containing one empty element and a script bundle reference. Every word of your positioning, your proof, your headings and your FAQ lives inside JavaScript that never runs.

That is why this failure is so hard to notice from the inside. Your browser renders it. Your team sees the page. Your screenshot tool sees the page. Lighthouse renders it. Search Console reports on Googlebot, which renders it. Nothing in a normal marketing workflow shows you the crawler's view, and the one tool that would, a raw fetch with a bot user agent, is not in most marketers' hands.

There is also a size tell. Compare the byte count of a route you know is empty against a route you know is full. If they are within a few hundred bytes of each other, the second route is not really there.

What did we measure on our own site?

On 6 August 2026 we fetched every route type on outboundpros.io with the documented GPTBot user agent and recorded what came back. We published the failing rows because a case study with no failures in it is not a measurement, it is an advertisement.

Route typeBytes to GPTBotState
/ homepage5,179Empty root div, head tags only
/blog index34,123Prerendered, full content
/blog/{slug} article21,139Prerendered, full content
/agency-directory26,717Prerendered, full content
/reviews index8,199Prerendered, full content
/reviews/{slug}15,595Prerendered, full content
/tools/gtm-audit5,519Stub, one heading and one paragraph
/services/managed-linkedin-outreach5,669Stub, one heading and one paragraph

Three things are worth pulling out of that table.

The empty baseline is about 5,179 bytes. Everything in the head, none of the body. That means the 5,519 byte tools route and the 5,669 byte service route each contained roughly 300 to 500 bytes of real content, which is a heading and a sentence. If you are auditing your own site, establish your baseline first, then read every route against it.

The prerendering worked where it had been applied. The blog on outboundpros.io and the reviews engine returned full content because a build step had been written for those route patterns. This is not a story about a broken tool. It is a story about partial coverage, which is the far more common failure and the harder one to spot, because your spot check will probably land on a route that passes.

The pages that failed were the commercial ones. The homepage, which is the single page most likely to be retrieved when someone asks an assistant what a company does, served nothing. The LinkedIn service page on the parent site served nothing. A prospect asking Claude or ChatGPT about the company would be answered from the blog, or from somebody else's site, and never from the pages built to convert.

Methodology. One curl fetch per route type against the live site on 6 August 2026, using the documented GPTBot user agent string, byte count taken from the raw response body, no JavaScript execution, no cache warming. It measures the first response to a non rendering crawler. It does not measure whether those URLs were subsequently cited anywhere, it does not describe Googlebot's view, and it is one site at one moment. When the parent's prerender coverage is extended, both the before and the after rows stay on this page, because the delta is the more citable asset.

You need real HTML in the first response. Server side rendering is one way to get there and it is usually not the cheapest one.

ApproachWhat the crawler getsCost to implementBest for
Prerender at buildReal HTML per route, written to static files by a postbuild stepLow. A script and a build hookMarketing sites, docs, anything where content changes on deploy rather than per request
Static site generationReal HTML per route, generated by the frameworkLow to medium, if you are already on a framework that supports itContent sites, blogs, most B2B marketing estates
Server side renderingReal HTML per requestMedium to high. Runtime, caching and cost implicationsPersonalised or frequently changing pages, logged in experiences
Dynamic rendering, bots get a rendered copyReal HTML, served conditionally by user agentMedium, plus maintenanceLegacy stacks where nothing else is viable. Google has deprecated it as a recommendation, treat it as a stopgap
Client side onlyAn empty elementZeroApplications behind a login, where no crawler was ever going to matter

For most B2B marketing sites the answer is prerender at build, because the content changes when you deploy and not when a user arrives. It is a script, a build hook and an afternoon. The reason so many teams reach for a full server side rendering migration instead is that the problem gets framed as an architecture problem when it is really a delivery problem.

One deployment detail that is easy to miss and expensive to get wrong. Some hosting products serve the client rendered bundle regardless of what your build produced, which means you can add a perfect prerender step and change nothing about what the crawler sees. Verify at the edge, on the live domain, not in your build output.

How do you test your own site with one command?

Fetch your own homepage with the documented GPTBot user agent string and look for your body copy in the response. If what comes back is an empty root element, that is your answer and you are done, because nothing else on a GEO roadmap matters until it changes. The three steps after it exist only to tell you how bad the problem is and which routes carry it, and the whole sequence takes about five minutes.

Step 1. Fetch your homepage as GPTBot.

curl -s -A "GPTBot" https://yourdomain.com/ | head -50

Step 2. Look for your actual words. Not your title tag, not your meta description, not your JSON-LD. Your H1, your subhead, a sentence from the middle of the page. If what you see is an empty root div followed by a script tag, your homepage is blank to every non rendering AI crawler.

Step 3. Establish your empty baseline and compare every route type against it.

for u in "/" "/pricing" "/blog" "/blog/some-post" "/product"; do
  printf "%s " "$u"; curl -s -A "GPTBot" "https://yourdomain.com$u" | wc -c
done

Routes clustered within a few hundred bytes of your smallest result are empty. Routes several times larger are real. Partial coverage shows up immediately in this list and almost never shows up any other way.

Step 4. Repeat with the other documented agents: OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot and Perplexity-User. You are checking two things per agent: a 200 response, and body copy in the payload. A 403 or a challenge page means the block is at your CDN and not in your code, which is a different fix and a common one.

If you would rather not run commands, our AI Visibility Checker does the same fetches from a URL field and shows you the response, ungated.

What does extractability not fix?

Passing gate one gets you read. It does not get you quoted, and conflating the two is the most common mistake made by teams who have just fixed their rendering and expect a result.

The 2026 measurement framework published as arXiv 2604.25707, built on 602 controlled prompts and 21,143 search layer citations across ChatGPT, Google and Perplexity, found that the citations with the most influence over an answer were "longer, more structured, semantically aligned, and richer in extractable evidence such as definitions, numerical facts, comparisons, and procedural steps". A perfectly prerendered page of adjectives has nothing in it to lift. Fixing rendering moves you from invisible to eligible, which is a large move and not a finished one.

The other thing it does not fix is corroboration. Multiple 2026 measurements point the same way on broad B2B category queries: the majority of citations go to third party sources instead of to vendor sites, because an engine asked to evaluate a category reaches for something that looks like an evaluation. The exact percentages circulating are vendor published with no methodology and we are not going to print them. The direction is consistent enough to plan around, and the implication is uncomfortable if you only own your own site. This is also the honest limit of what any owned media programme can do for you, which is why the demand generation problem and the demand capture problem are worth separating. If yours turns out to be the first one, it belongs with the demand generation work on the agency side of the group rather than with us.

Frequently asked questions

Is my React site invisible to AI crawlers?

To the non rendering ones, yes, unless something in your build produces HTML before the request arrives. React itself is not the problem, client side only delivery is. A React site using static generation or a prerender step passes this test comfortably. Check, do not assume, because the answer depends on your build and hosting and not on your framework.

Do I need to rebuild my site?

Almost certainly not. Most sites failing this test need a prerender step and a hosting change, not a rewrite. Work out which routes are actually empty before anyone scopes a migration, because partial coverage is common and the fix for four broken route patterns is much smaller than the fix everyone imagines.

Will Google still rank my single page app?

Yes, with a caveat Google states itself. Googlebot processes content within JavaScript as long as it is not blocked, but rendering happens on a deferred, budget limited second pass. So classic rankings survive client side rendering, AI crawler visibility does not, and this is exactly why so many teams pass their SEO reporting and lose the AI surfaces without ever seeing a signal.

How long after fixing this does anything change?

Unknown, and be suspicious of anyone who answers precisely. Re-crawl timing is not published by any of the three vendors, referral reporting for ChatGPT, Claude and Perplexity does not exist first party, and native app traffic sends no referrer header at all. What you can do is establish the baseline before you fix it, which most teams skip and then cannot prove anything afterwards.

Does prerendering count as cloaking?

Not when every visitor gets the same content. Cloaking is serving materially different content to crawlers than to users. Prerendering serves the same content, earlier. Where it does get uncomfortable is user agent conditional rendering that produces a different page for bots, which is why the build time approach is the cleaner one and the one we recommend.

Test it before you plan anything. Run the checker against your own homepage. It is ungated and the result is on screen. If gate one fails, nothing else on your GEO roadmap matters this quarter, and you have just saved yourself a budget cycle. If it passes, the interesting work starts, and the next page to read is our guide to the traits that separate a cited passage from an ignored one.

Run the checker on your homepage

Ungated. The result renders on the page, and the two checks that decide most results are reproducible from your own terminal.

Last updated: 2026-08-06

See what a crawler sees on your own site

Paste a URL and get the extractability read: what an assistant can actually retrieve, and what it cannot.

Run the visibility check

Free. No signup, no email capture.

Prefer to talk it through? Book a call with the team