Blog · Access and retrieval

JavaScript rendering is where AI visibility quietly dies

Published 8 October 2026 · Updated 12 October 2026 · 9 min read

JavaScript rendering is where AI visibility quietly dies
Photograph: Beau Carpenter / unsplash

The short answer: In the public log study this post leans on, the agents behind ChatGPT, Claude, Perplexity, Meta and Common Crawl requested a page once, read the HTML the server sent, and stopped. They did not wait for a framework to hydrate. If your headline, your prices or your product copy exist only after the browser runs JavaScript, those agents keep an empty shell, and a shell cannot be quoted. Fixing it is rarely a rewrite. It is moving the answer into the first response.

That sentence is widely repeated and badly understood. The interesting part is not that rendering fails. It is where it fails, what fails with it, and why your brand sometimes still appears in answers while the underlying page is unreadable.

A fetch, not a browser session

Picture what the crawler is. One HTTP request goes out, markup comes back, text gets pulled from that markup and cut into passages. There is no event loop. Nothing waits for an XHR call to resolve, nothing fires on scroll, and no router swaps the view.

Several of these agents do download your bundles. A log study Vercel published with MERJ on 17 December 2024, drawn from traffic to nextjs.org and the Vercel network and checked against two job board sites, recorded JavaScript assets making up 11.50 percent of the ChatGPT crawler's fetches and 23.84 percent of Claude's, and reported no sign of any of it being executed. That is one network's logs over a few months in 2024, not a census of the web. Reading a bundle as text is not running it. A product name sitting in a compiled string may be scraped as loose tokens, detached from the element it belonged to, with no evidence it was ever shown to a human.

The blanket claim that AI crawlers do not render is still too coarse. The same study put Gemini's crawling on Google's rendering infrastructure and Apple's crawler on a browser engine, while the OpenAI, Anthropic, Perplexity, Meta and Common Crawl agents sat on the other side of the line. Microsoft's assistant was left out of that study for want of a distinct user agent, so nothing measured there describes it. Two populations, one web, and one agent nobody in that dataset could see. Your page has to satisfy the stricter side.

The second failure: your routes quietly become 404s

Rendering gets all the attention. Routing is where the damage compounds.

A client-side router paints links into the DOM after load. To an agent reading raw markup there is no anchor, so there is no next page, and discovery of your own site collapses to whatever the sitemap and old training data happen to hold. The crawler then guesses, and it guesses badly. In that same December 2024 dataset, 34.82 percent of the ChatGPT crawler's fetches and 34.16 percent of Claude's landed on 404s, against 8.22 percent for Googlebot.

On those properties, in that window, roughly a third of what those two crawlers fetched reached nothing at all. Whether the same ratio holds on your site is something we have not measured and the study did not claim. Worse, many single-page apps answer a dead URL with a 200 and a shell, so the agent records a valid empty page instead of a clean miss. Serve real status codes, keep the sitemap honest, and give every route a server response. Can AI crawlers actually read your site walks through the access layer underneath all of this.

Why your brand still shows up, and why that is the trap

Here is the part that confuses teams. Their stack is fully client rendered, and they are named in answers anyway.

Two paths lead into an answer. One runs through a conventional search index, and those indexes do render. Google's own guidance on optimising for its AI features, last updated on 10 July 2026, says a page needs to be indexed and eligible for a snippet, and that content inside JavaScript can be processed as long as it is not blocked. Microsoft has written that its crawler is generally able to render JavaScript while not supporting every framework a current browser does, in a webmaster post dated 31 October 2018 that it has not since replaced. On that basis, and it is an eight year old basis, a client-rendered page can still be retrievable through Microsoft Copilot and the Bing index while a direct fetch from an assistant's own agent comes back hollow.

The second path is that direct fetch. When it fails, your presence survives only on the first path, which is somebody else's rendering budget, refreshed on somebody else's schedule. That is a rented position by any sensible definition. It is also consistent with a symptom we see in audits: the answer repeats a claim you retired long ago, because the readable copy of your page is the one an index rendered and cached, while the correction lives in a component nothing has re-rendered since. That is an inference from the output. We cannot see an engine's cache.

A two minute test

Request your page the way an agent does, strip the tags, and count what is left.

`` curl -sL -A 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot' \ 'https://example.com/your-page' \ | perl -0777 -pe 's{<(script|style)\b.*?</\1>}{ }gis; s{<[^>]*>}{ }gs' \ | tr -s ' \n' ' ' | wc -w ``

Strip script and style blocks across line breaks rather than line by line. A line based filter leaves the text of your bundles in the count and reports thousands of words no reader will ever see. The user agent string is the example OpenAI publishes in its crawler documentation, so this is still your own request from your own address, not OpenAI's.

Then grep the same output for the one sentence you want an engine to lift. If the sentence is missing, the engine is working from something other than your page.

We ran it once, on 12 October 2026, from one machine in India, against one URL: Microsoft's own Bing Webmaster Guidelines page, which is a reasonable page to pick because it is documentation that search people actually cite. The response was about 125 KB. Visible text in that raw HTML came to fifteen words, one of which was an instruction to enable JavaScript. Everything a reader sees arrives afterwards. One fetch of one URL on one day is a worked example and not a sample of anything, and we mention it because the pattern is ordinary rather than as a criticism of anyone: large engineering teams ship this configuration without noticing.

Three refinements worth adding. Compare the word count against the rendered page, since a ratio tells you more than an absolute number. Check a template, not just the homepage, because marketing pages are often static while the product catalogue is not. And run the self-check before you touch the build, since a firewall rule and a rendering gap produce the same empty result and only one of them needs engineering time.

What to move, and what to leave alone

Nobody has to server-render an entire application. Move the retrievable layer and stop.

In the first response: the H1 and every heading, the first sixty to eighty words that answer the question, the body copy, prices and specifications, canonical and meta tags, your JSON-LD block, and internal links as real anchors with real href attributes. Leave in the browser: chat widgets, carousels, comment threads, personalised blocks, cookie banners, anything behind a login. An interactive configurator is not the passage you want quoted.

Two cautions. We advise against detecting agents and serving them a special document, because you then maintain two truths and one of them drifts. That is a judgement about maintenance, not a rule the engines impose: the 2018 Microsoft post recommends precisely that technique and says matching content is not cloaking, while Google's documentation, updated 10 December 2025, calls it a workaround rather than a recommended solution and points to server-side or static rendering instead. And rule out blocking first. A rendering gap and a blocked user agent look identical from the outside, which is why the decision to block deserves to be made deliberately rather than inherited from a CDN default nobody chose.

Honest limits

Sending a copied user agent string shows what your server would send to anyone sending that string. It does not prove an engine kept your passage, ranked it above three competitors, or had any reason to quote it, and it is not a request from the engine. Access is necessary and nowhere near sufficient.

Every percentage in this post comes from one study of one network's logs in 2024, and the only measurement of our own is a single fetch of a single page on 12 October 2026. Neither licenses a claim about the web, about your site, or about agents nobody in that dataset could identify, Microsoft's among them. Crawler behaviour also changes without announcement, so a team reading those percentages as current numbers is reading them wrong.

What we cannot see at all is which copy of a page an engine held when it wrote an answer, and we have not found a way to establish that from outside. Where this post says a stale answer comes from a cached render, that is an inference from output, not something we observed.

FAQ

Does Google render JavaScript for AI Overviews? Google's documentation says content inside JavaScript can be processed when it is not blocked, and that eligibility for AI features follows from normal indexing and snippet eligibility. Being readable to Google is not the same as being readable to the agents that fetch your page directly.

Is prerendering for bots only safe? Microsoft's webmaster blog recommended it in 2018 and said matching content is not cloaking, while Google's documentation calls it a workaround and points to server-side or static rendering instead. Our own objection is maintenance rather than policy: two renderings of the same URL drift apart, and the version a human sees is the one that keeps getting updated. We have not measured how often that drift happens, so treat it as our experience.

Will server-side rendering get me cited? It removes a reason not to be. Citation depends on whether the passage answers the question, whether your identity resolves, and whether anything the engine trusts agrees with you. Rendering is the entry fee, not the result.

My site is React. Do I have to migrate everything? No. Pick the routes that answer buyer questions, render those on the server or at build time, and leave the application shell alone. In the audits we have run, most of the recoverable loss sat in a handful of templates.

Sources

Every link below was opened on 12 October 2026 and still carried the sentence it is cited for.

Related reading