Skip to content
SEOMagics
TECHNICAL SEO

JavaScript Rendering and AI Crawlers: What GPTBot Cannot See

Here's what most JavaScript SEO advice still gets wrong in 2026: it assumes rendering is a solved problem because Googlebot handles it. Googlebot does.

By SEO Magics Research Team··8 min read
JavaScript Rendering and AI Crawlers: What GPTBot Cannot See — cover illustration

JavaScript Rendering and AI Crawlers: What GPTBot Cannot See

Bottom line: JavaScript SEO for AI crawlers comes down to one hard fact: GPTBot, ClaudeBot, and PerplexityBot fetch your JavaScript files but never execute them. Anything injected client-side - tabbed content, lazy-loaded tables, hydrated FAQs - is invisible to them. Only Google's renderer runs JS. If your text appears after hydration, the biggest AI engines see an empty shell.

Here's what most JavaScript SEO advice still gets wrong in 2026: it assumes rendering is a solved problem because Googlebot handles it. Googlebot does. But Vercel and MERJ's analysis of AI crawler behavior - covering 569 million GPTBot fetches and 370 million ClaudeBot fetches in a single month - found no evidence that any major AI crawler renders JavaScript at all. They request your .js bundles (ChatGPT in 11.50% of requests, Claude in 23.84%) and then do nothing with them. The content you worked hardest on can be the content ChatGPT literally cannot read.

Key Takeaways:

  • —GPTBot, OAI-SearchBot, ClaudeBot, and PerplexityBot do not execute JavaScript - they parse only the raw HTML your server returns, per Vercel's crawler data.
  • —Google's Gemini is the exception: it reuses Googlebot's headless-Chrome renderer, so a page that "works in Google" can still be blank to ChatGPT.
  • —Client-rendered tabs, lazy-loaded tables, and hydrated FAQ accordions are the three patterns that most reliably vanish from a no-JS fetch.
  • —JSON-LD schema injected by client-side JavaScript is invisible to AI crawlers for the exact same reason - it never hits the initial HTML.
  • —You can verify any page yourself with a one-line curl command using a GPTBot user agent; no paid tool required.

Why can't GPTBot see JavaScript content?

Why cant GPTBot see JavaScript content

Think of two different machines reading your page. Googlebot runs a two-phase process: it grabs the HTML, queues the page, then comes back with a headless Chrome instance that executes your JavaScript and indexes the final DOM. AI crawlers skip phase two entirely.

When GPTBot requests a page, it reads the HTTP response and stops. No browser. No DOM construction. No hydration. If your framework ships a near-empty <div id="root"></div> and defers the real content to a JavaScript bundle, that bundle is downloaded and discarded. The Vercel/MERJ data is blunt about it: the crawlers fetch JS files but "don't execute them" and "can't read client-side rendered content."

This matters more now than it did a year ago because the traffic has moved. GPTBot alone logged 569 million fetches in the window Vercel measured. These aren't fringe bots scraping the long tail - they're the pipelines feeding ChatGPT, Claude, and Perplexity answers that increasingly replace a click to your site. Our broader take on controlling that access lives in our guide to GPTBot, ClaudeBot, and what robots.txt really does.

What content patterns survive a no-JS fetch? (The test matrix)

Test matrix table showing client-rendered, lazy-loaded, and hydrated patterns against no-JS visibility

This is the part no other guide on this keyword actually ships. Everyone tells you "render server-side." Nobody shows you which specific patterns break and lets you check your own pages in under a minute. So here is the matrix, built from auditing how common component patterns behave when JavaScript never runs.

The rule to internalize: a pattern survives only if its text is present in the raw HTML before any script executes. Interactivity is fine. Invisible-until-hydrated is fatal.

Content patternIn raw HTML?Visible to GPTBot/ClaudeBot?Fix
Static server-rendered copy (SSR/SSG)Yes✅ VisibleNone needed
Client-rendered tabs (content mounts on click)Only active tab, often none❌ Hidden tabs invisibleRender all tab panels in HTML; toggle with CSS
Lazy-loaded data tables (fetch on scroll)No❌ InvisibleServer-render the first data set
Hydrated FAQ accordions (answers in JS state)Sometimes answers missing⚠️ Often partialPut full Q&A in HTML; collapse with <details> or CSS
Infinite-scroll / "load more" contentFirst batch only⚠️ Only first batchPaginate with crawlable <a href> links
Modal / popup contentNo❌ InvisibleMove critical copy out of modals
Client-injected JSON-LD schemaNo❌ InvisibleInject schema server-side in the <head>
CSS-hidden content (display:none in HTML)Yes✅ Visible (present in source)Fine for AI crawlers

The counterintuitive line in that table: CSS-hidden content is fine, but JavaScript-mounted content is not. An accordion whose answers sit in the HTML and collapse via CSS is readable. An accordion whose answers only exist in React state after useEffect runs is not. Same visual result for a human; opposite outcome for GPTBot. If FAQ visibility is your goal, our breakdown of FAQ pages AI engines actually quote pairs directly with this.

How do I check my own pages? (Run this curl command)

You don't need a crawler subscription to test this. You need one command. Here is the process, in order.

  1. Fetch the page as GPTBot sees it. Run this in your terminal:
 curl -A "Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)" -s https://yoursite.com/your-page | less

This returns the exact raw HTML your server sends to GPTBot - before any JavaScript runs.

  1. Search for your real content. Pipe it to grep for a sentence you know is on the page: curl -A "GPTBot/1.0" -s https://yoursite.com/page | grep -i "your headline text". No match means that text isn't in the HTML - it's JavaScript-injected and invisible.
  2. Check your schema. Run grep "application/ld+json" against the same output. If your structured data doesn't appear, it's being injected client-side and no AI crawler will read it.
  3. Confirm against a browser. Open the page normally, then view the live DOM in DevTools. Content that shows in DevTools but not in the curl output is your gap.
  4. Cross-check with Google. Use the URL Inspection tool in Google Search Console to see the rendered HTML Googlebot gets. If content appears there but not in your curl fetch, you've confirmed the split: visible to Google, invisible to ChatGPT.

That last step is the one founders miss. A page can rank in Google - because Googlebot rendered it - while being a blank shell to the AI engines now intercepting the query. You can automate this whole sweep across a site with our AI SEO audit tool, which flags pages where critical content fails a no-JS fetch.

Does this mean every SPA is invisible to AI search?

Not quite - and the nuance is where teams waste money. A single-page app built with modern server-side rendering or static generation ships real HTML on the first response, then hydrates for interactivity. That page is fully visible to GPTBot. The problem isn't the framework; it's the rendering strategy.

Flowchart showing SSR, SSG, and CSR paths and which reach AI crawlers

The failure mode is pure client-side rendering: an empty shell plus a bundle that builds the page in the browser. Vercel's data notes the crawlers can pick up JSON or delayed React Server Components if those land in the initial HTML response. The dividing question is never "React or not" - it's "is the text in the HTML before JS runs, yes or no." Our developer handoff SEO checklist covers how to specify this before a rebuild, which is far cheaper than retrofitting it after.

Which AI crawlers render JavaScript, and which don't?

Short answer: almost none of the ones that matter for AI answers. Here's the current landscape from the Vercel/MERJ analysis and Google's own JavaScript SEO documentation.

CrawlerPowersRenders JavaScript?
GooglebotGoogle Search, AI Overviews, GeminiYes (headless Chrome)
GPTBot / OAI-SearchBotChatGPT, ChatGPT SearchNo
ClaudeBotClaudeNo
PerplexityBotPerplexityNo
AppleBotApple intelligence / SiriYes
CCBotCommon Crawl (training data)No

The strategic read: Gemini gets your rendered content for free because it rides Googlebot's infrastructure. Every other major AI assistant is reading raw HTML only. So if you're optimizing to get cited inside ChatGPT and Perplexity - the core of generative engine optimization - client-side rendering is a self-inflicted wound. Getting cited is hard enough without handing the crawler a blank page.

How do I fix JavaScript content for AI crawlers?

Before-and-after of a page's HTML source moving content from JS bundle to server response

Fixing this is less about rewriting your app and more about moving content across a line. The checklist, in priority order:

  1. Server-render or statically generate your primary content. Headings, body copy, and the first data set must be in the HTML response. This single change resolves most AI-visibility gaps.
  2. Move JSON-LD schema server-side. Inject structured data into the <head> at build or request time, never via a client script. Which types to prioritize is in our guide to schema markup for AI search.
  3. Render all tab and accordion content in HTML. Toggle visibility with CSS, not conditional mounting.
  4. Paginate instead of infinite-scroll for any content you want crawled, using real <a href> links.
  5. Re-test with the curl command above after each deploy. Rendering regressions are silent - nothing errors, the content just quietly disappears from the HTML.

Avoid dynamic rendering (serving a prerendered version only to bots) as a long-term fix. Google has discouraged it as a workaround, and maintaining a separate bot path is fragile. True SSR or SSG is the durable answer, and it's what we specify in AI-native SEO engagements for growth-stage sites.

How We Assessed This

The patterns and recommendations here were built from two inputs. First, the public Vercel and MERJ dataset on AI crawler behavior across hundreds of millions of fetches, cross-referenced with Google Search Central's JavaScript SEO documentation for the two-phase rendering model. Second, our own technical audits of growth-stage sites, where the standard workflow fetches each key URL with an AI-crawler user agent, diffs the raw HTML against the rendered DOM in Chrome DevTools, and confirms against Google Search Console's URL Inspection tool. We use Screaming Frog with JavaScript rendering toggled off to simulate the no-JS view at scale, then validate schema delivery server-side. The test matrix in this article reflects component patterns we repeatedly see break on a no-JS fetch - not a controlled lab study, and we've flagged where behavior is partial rather than binary. Where we could not source a precise citation rate by rendering method, we've described the mechanism qualitatively rather than quote an unverified number, because the measurement methodology behind those figures isn't public. SEO visibility inside AI engines is still a moving target across 12-month optimization cycles, and crawler behavior can change without announcement - so re-testing beats trusting last quarter's result.

FAQ

Do AI crawlers like GPTBot execute JavaScript?

No. Based on Vercel and MERJ's analysis, GPTBot, ClaudeBot, and PerplexityBot fetch JavaScript files but do not execute them. They read only the raw HTML your server returns, so any content built in the browser is invisible to them.

Why does my page rank in Google but not appear in ChatGPT?

Because Googlebot renders JavaScript and the AI crawlers don't. Google runs a headless Chrome pass that builds your client-rendered content; GPTBot stops at the raw HTML. A page that's complete after hydration can be a blank shell to ChatGPT while still ranking in Google.

How do I test if AI crawlers can see my content?

Run curl with a GPTBot user agent against your URL and search the output for your real content. If a sentence that's visibly on the page doesn't appear in the raw HTML, it's JavaScript-injected and invisible to AI crawlers. The step-by-step commands are in the section above.

Does server-side rendering fix the AI crawler problem?

In most cases, yes. Server-side rendering and static generation put your real content in the initial HTML response, which is all AI crawlers read. The goal is text present before JavaScript runs - the framework matters less than the rendering strategy.

Is client-side JSON-LD schema read by AI crawlers?

No. Schema injected by client-side JavaScript never reaches the initial HTML, so AI crawlers can't see it - the same failure as any other client-rendered content. Inject structured data server-side in the <head> instead.

Which AI assistant can see my JavaScript content?

Primarily Google's Gemini, because it reuses Googlebot's renderer. AppleBot also renders JavaScript. ChatGPT, Claude, and Perplexity do not, so optimizing for those engines means your content must live in the raw HTML.

See exactly what AI crawlers miss on your site

If GPTBot can't read a page, it can't cite you - and you won't see an error, just missing visibility in ChatGPT and Perplexity answers. Start with a free pass of our AI SEO audit tool to flag pages where critical content fails a no-JS fetch. For a deeper read across a whole site, SEO Magics runs AI-native technical audits as part of our monthly plans - Foundation ($1,500/mo), Growth ($3,500/mo), and AI Authority ($7,500/mo), detailed at how much SEO costs. If you want a second opinion on why your content isn't getting cited, book a strategy call and we'll walk your pages through the exact curl test above.

See where you stand in AI search. Free.

Run the free AI-Search Audit in 2 minutes, no email required. Or book a 30-minute call and we'll walk your site live and leave you with 3 to 5 quick wins. No pitch.

Response

<24 hrs

Audit

Free · 2 min

Pricing

Public · no quote

Lock-in

3 months min