Your Site May Be Invisible to ChatGPT: A Ten-Minute Check You Can Run With curl
The pattern turns up often enough to be predictable. A company rebuilt its site on React or Vue two or three years ago. Rankings held. Search Console looks healthy. Then somebody asks ChatGPT or Perplexity a question the company should obviously own, and the answer names three competitors and not them. The instinct is to blame the model, or to start writing more content. Usually the cause is much duller: the pages have no text in them until JavaScript runs, and most AI crawlers never run it.
This is a genuinely new failure mode. For a decade the working assumption in web development was that if Googlebot could render your app, you were fine. That assumption is now doing real damage, because the systems generating answers do not share Googlebot’s rendering pipeline.
Why Google seeing your site proves nothing about ChatGPT seeing it
Googlebot runs a headless browser. It fetches the HTML, queues the page, executes the JavaScript, and indexes what the DOM looks like afterwards. Google’s own JavaScript SEO documentation describes that three-stage crawl, render and index process in detail. It works, with a delay, and a lot of single-page applications rank perfectly well because of it.
AI crawlers largely do not do this. The best available primary evidence is the joint Vercel and MERJ server-log study, published in December 2024, which analysed real request logs rather than surveys. Its headline finding was blunt: none of the major AI crawlers rendered JavaScript. OpenAI’s and Anthropic’s crawlers did download JavaScript files, at 11.5% and 23.84% of their fetches respectively, and simply never executed them. Two exceptions were noted: Google’s Gemini crawling rides on Googlebot’s infrastructure and therefore does render, and AppleBot uses a browser-based crawler.
Three caveats belong with that study, and they matter more than the headline. It is dated, so treat it as a snapshot of December 2024 rather than a permanent law of nature. The logs came mainly from one large documentation site plus Vercel’s network, so it is a deep sample rather than a census of the web. And the authors excluded Microsoft Copilot because it did not present a distinct user agent at the time.
What has not changed is the incentive. Rendering JavaScript is expensive. Google built that capability over years because search was its core business. A crawler assembling a training corpus, or fetching a page to ground an answer in the next two seconds, has no reason to pay for a browser engine per URL. Nothing in the vendors’ own documentation suggests otherwise. OpenAI’s crawler documentation describes user agents, IP ranges and robots.txt handling and says nothing at all about rendering. Neither does Anthropic’s crawler documentation.
Two things are worth adding for honesty. MERJ returned to the subject in a May 2026 piece on serving the right representation to the right crawler, and it repeats that these agents may not execute JavaScript without publishing fresh measurements. So the strongest available evidence is one study, from one network, twenty months old, never refreshed. That is thinner than the confidence with which the claim usually gets repeated, and you should know that before you spend a quarter on it.
The other thing is that Google agrees with the conclusion anyway. Buried in that same JavaScript SEO documentation is the line that server-side rendering or pre-rendering is still a great idea, because not all bots can run JavaScript. That is the search engine with the most expensive rendering pipeline in the world telling you not to depend on rendering.
So the practical rule is this: assume the AI crawler sees exactly what curl sees, and treat any rendering as a bonus you did not pay for.
The ten-minute check
You do not need a tool, a subscription or a dashboard for this. You need curl, a browser, and one important page: not the homepage, but the page you would actually want quoted. A service page, a pricing page, a specification.
Save the raw response once and run everything against the file, so all six checks look at the same bytes.
curl -sL “https://yoursite.com/your-key-page/” > raw.html
1. Is there any text at all
Strip the tags and count what is left. If a page you know contains eight hundred words returns forty, you have your answer immediately.
sed ‘s/<[^>]*>/ /g’ raw.html | tr -s “[:space:]” ” ” | wc -w
2. Grep for a sentence you can see on screen
Open the page in a browser, copy a distinctive full sentence from the middle of the body copy, and look for it in the file. This is the single most decisive check in the list, because it is immune to any argument about how the counting works.
grep -c “a full sentence copied from the rendered page” raw.html
Zero means that sentence does not exist until JavaScript runs. To a crawler that does not run JavaScript, it does not exist at all.
3. Look for the empty shell
Client-rendered applications usually leave a fingerprint: a single mount point with nothing inside it.
grep -o ‘id=”root”‘ raw.html ; grep -o ‘id=”__next”‘ raw.html ; grep -o ‘id=”app”‘ raw.html
Finding the element is not itself a problem. Finding it empty, with the visible copy nowhere else in the file, is.
4. Compare the raw file against the rendered DOM
In the browser console on the same page, run the line below and compare it with the number from step one. A rendered count of two thousand words against a raw count of sixty is a complete diagnosis.
document.body.innerText.split(/\s+/).length
Google’s URL Inspection tool gives you the same comparison from Google’s side, under “view crawled page”, and it is worth doing both, because they can disagree.
A gap on its own is not automatically a crisis, and it helps to know what normal looks like. The HTTP Archive Web Almanac measured exactly this difference across the web and found the median desktop home page gains about 18% more words after rendering, rising to roughly 32% at the tenth percentile. In other words, a modest gap is ordinary. A gap of ninety-something percent is a different animal.
5. Check what a bot user agent gets
Some firewalls, bot managers and CDN rules serve a challenge page or a 403 to anything that looks like a crawler. That is a separate failure with identical symptoms.
curl -sL -A “Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot” -o /dev/null -w “%{http_code} %{size_download}” “https://yoursite.com/your-key-page/”
Compare the status code and byte count against a plain request. A 403, a redirect to a challenge, or a body that is suddenly a tenth of the size all mean the page is being withheld before rendering even becomes the question.
6. Confirm the structured data is in the raw HTML too
Schema injected by a tag manager after page load has exactly the same problem as body copy injected after page load.
grep -c “application/ld+json” raw.html
Reading the results
| What you saw | What it means | Roughly what it costs to fix |
|---|---|---|
| Raw word count close to rendered, key sentence present | Nothing to do. Server-rendered or static already | Nothing |
| Body copy present, but prices or specs missing | Partial hydration. The commercially useful part is the invisible part | Days. Move those blocks into the server response |
| Empty mount point, near-zero raw text | Full client-side rendering. Non-rendering crawlers see a blank page | Weeks to months, depending on the framework |
| Bot user agent gets 403 or a challenge | Edge or WAF rule, not a rendering problem | Hours. A configuration change |
| Raw HTML fine, structured data missing | Schema injected client side by a tag manager | Hours to days |
What the check does not tell you
It tells you whether a machine can read the page. It does not tell you whether anything will cite it. Readability is a precondition, not a strategy, and it is worth being honest about the size of the gap between the two. A page that is perfectly crawlable and says nothing specific will be ignored just as thoroughly as one that is blank.
The check also says nothing about whether crawlers are actually visiting. That lives in your server logs, filtered by user agent, and it is a different afternoon’s work. Plenty of sites are perfectly readable and simply never fetched.
Four ways out, in ascending order of pain
| Approach | What it does | Good when | The catch |
|---|---|---|---|
| Static generation | Builds real HTML files ahead of time | Marketing pages, docs, catalogues that change on a schedule | Rebuild time grows with page count |
| Server-side rendering | Renders each request on the server, hydrates after | Content that is personalised or changes constantly | Real server cost and a more complex deployment |
| Prerendering at the edge | Serves a cached rendered snapshot to crawlers | You cannot touch the application soon | A bolt-on that drifts out of sync with the live app |
| Hybrid: static shell plus client widgets | Text and prices in the HTML, interactivity on top | Most business sites, honestly | Requires deciding what is content and what is application |
The trade-offs behind these are well covered in the reference write-up on rendering on the web, which predates the AI crawler question entirely and is better for it. Nothing in that analysis was invalidated by AI search. What changed is that the cost of getting it wrong went up.
The choice interacts heavily with the content management setup. If you are already weighing a decoupled front end, the same decision decides this one, and our piece on who actually needs a headless CMS covers where that architecture earns its keep and where it is expensive theatre. The same applies to the app-versus-web question: a site that is really an application in a browser tab has this problem structurally, which is part of the argument in choosing between a mobile app and a PWA.
Why this is so common now
Two forces put it there. Component frameworks became the default way to build anything, including brochure sites that have no interactivity worth the name. And generated code amplifies it: an assistant asked to build a landing page will reach for the pattern it has seen most, which is a client-rendered app, whether or not the page needs one. We wrote about that failure family in what breaks in AI-generated sites, and this is one of its quietest members, because nothing looks broken.
Google’s own guidance, updated in July 2026, is worth reading closely here because it is easy to misread as reassurance. Its guide to optimising for generative AI features says that Google is able to process content within JavaScript as long as it is not blocked, and that no special files or markup are needed. Both statements are true, and both are scoped to Google. They say nothing about the systems that answer questions outside Google Search, and that gap is exactly what this check measures.
The short version
Run curl against your most commercially important page. Count the words. Grep for one sentence you can see on screen. If that sentence is not there, no crawler that skips JavaScript can quote you, and most of them skip it. The fix is architectural rather than editorial, it usually means moving text into the server response, and it is far cheaper to decide during a rebuild than to retrofit afterwards. If a migration is already on the table, this is the moment the decision is nearly free, and it is one of the first things we check when we build a corporate site that is meant to be quoted rather than merely visited.










