TL;DR
- The vast majority of AI crawlers fetch HTML but do not execute JavaScript. A SearchViu analysis of 23 major crawlers put the non-rendering share around 69%.
- GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot, Meta-ExternalAgent, and Bytespider all read raw HTML only. Google's Gemini is the notable exception because it shares Googlebot's Web Rendering Service.
- If your product data, schema, canonical tag, or meta description is injected by client-side JS, it is effectively invisible to LLM crawlers.
- SSR or SSG with hydration is the safe default for GEO. Pure CSR SPAs lose ground twice: once at ChatGPT/Claude direct fetch, and again through Bing's limited rendering feeding ChatGPT Search.
- The fastest audit: disable JavaScript in DevTools and reload. Whatever remains is what AI reads.
Rendering choice used to be a frontend concern. In 2026 it is a distribution decision. Whether an AI engine can cite your page depends on whether the crawler that visited it saw actual content or an empty <div id="root">. Below is what we know about which bots render, which don't, and how to structure a Next.js (or any framework) app so LLMs can retrieve your work.
Which AI crawlers execute JavaScript in 2026
Short answer: almost none of them.
Independent testing has repeatedly shown that the crawlers feeding today's major LLMs behave like early-2000s search bots — they issue an HTTP GET, parse the HTML response, and move on. Vercel's crawler analysis found ChatGPT's bot fetches JS files (about 11.5% of its requests) and Claude's fetches even more (roughly 23.8%), but neither executes them. Fetching a script tag is not the same as running it.
A June 2026 breakdown from Lantern lists the confirmed non-rendering set: GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, PerplexityBot, Meta-ExternalAgent, and Bytespider. Gemini is the outlier — Google's Developer Advocate Martin Splitt confirmed to Search Engine Journal in May 2025 that Gemini's crawler piggybacks on the same Web Rendering Service that powers Googlebot.
There is a secondary effect worth internalising. ChatGPT Search leans heavily on Bing's index for fresh retrieval, and Bingbot's rendering capability is limited compared to Googlebot's. So a client-only SPA loses ChatGPT visibility from two directions at once: direct fetches see nothing, and the Bing-mediated fallback sees very little either. Passionfruit's 2026 write-up walks through the mechanism.
SSR, SSG, ISR, CSR — the trade-offs for GEO
The rendering spectrum in a modern framework like Next.js gives you four practical options:
- SSG (Static Site Generation): HTML built at deploy time. Best case for crawlers — the entire page ships as HTML. Ideal for marketing pages, docs, glossaries, and evergreen content.
- SSR (Server-Side Rendering): HTML rendered per request. Same crawler benefit as SSG, with dynamic data. Costs more compute; watch cache headers.
- ISR (Incremental Static Regeneration): SSG with revalidation. Effectively the GEO sweet spot for content that changes hourly or daily.
- CSR (Client-Side Rendering): Empty shell + JS bundle. Great for authenticated app UIs. Bad for anything you want cited.
The React Server Components model in Next.js App Router defaults to server rendering, which is the right default. The trap is hydration: if your critical content — pricing, product specs, FAQ answers, author bylines — is only injected after a useEffect fires, you're back to CSR from the crawler's perspective, regardless of what the framework marketing claims.
A useful rule: anything you want an LLM to quote must exist in view-source: on the page. If it appears only in the rendered DOM after hydration, it's client-side, and non-rendering crawlers will miss it.
The metadata problem nobody talks about
Content is only half the issue. Schema markup, canonical tags, meta descriptions, and Open Graph tags injected via JavaScript are equally invisible to non-rendering crawlers. That matters because:
- Schema is one of the strongest signals LLMs use to disambiguate entities and extract structured facts.
- Canonical tags injected by JS routers can lead crawlers to index duplicate URLs — or, worse, none of them.
- OG tags matter for how ChatGPT and Perplexity render citation cards.
If you're using a client-side helm library (react-helmet without SSR, or a similar SPA pattern), your structured data likely isn't being seen by GPTBot at all. Move <script type="application/ld+json"> into the server-rendered document head. In Next.js App Router, that means the metadata export or a server component, not a useEffect.
How to test what an AI crawler actually sees
Three quick methods, ordered by rigor:
- Disable JavaScript in DevTools. Chrome: Command Menu → "Disable JavaScript" → reload. Whatever renders is roughly what GPTBot sees. Discovered Labs recommends this as the first-pass check.
curlthe URL with a crawler user-agent.curl -A "GPTBot/1.0" -L https://yoursite.com/page | less. Search the output for the text and schema you expect. This is what the bot literally receives.- Check server logs. Filter for the AI bot user-agents and inspect response bodies (or replay the requests). If your critical content isn't in the response, no amount of prompt engineering will surface it in ChatGPT.
For teams already on Next.js, the "View Page Source" trick still works — but confirm with a raw curl because some middleware branches on user-agent.
Migration path if you're stuck on a CSR SPA
You do not need to rewrite the whole app. Priorities:
- Move public marketing, blog, docs, and pricing pages to SSR or SSG first. These are the pages LLMs cite.
- Keep the authenticated app CSR. Nobody's asking ChatGPT to render your dashboard.
- Server-render
<head>, schema, and above-the-fold content even on pages that hydrate heavily below. - Pre-render dynamic routes with ISR where you can — product pages, location pages, category pages.
FAQ
Does Googlebot rendering help me with Google AI Overviews?
Yes. AI Overviews draw from Google's main index, and that index is populated by Googlebot with rendering. Gemini's dedicated crawler also renders. So Google surfaces are the one place CSR still has a fighting chance — but you're still better off with SSR for speed and reliability.
Is Next.js App Router automatically safe?
Mostly, but not by default in every pattern. Server Components render on the server, which is good. But if you wrap critical content in a "use client" component that fetches data in useEffect, that content is client-rendered and invisible to non-rendering bots. Audit component boundaries.
What about dynamic rendering (serving different HTML to bots)?
Serving a pre-rendered version to known crawler user-agents (via Prerender.io, Rendertron, or a custom edge function) is legitimate and used widely. It's not cloaking as long as the content matches what users see. For AI crawlers specifically, this is a valid workaround when a full SSR migration isn't feasible.


