Why AI Search Can't See Your React or SPA Site — and the Fix That Doesn't Need a Rebuild
You built a clean single-page app. It looks great, it's fast, it works perfectly in your browser. Then you ask ChatGPT about your product and it has no idea you exist. Same with Perplexity. Same with Google's AI Overviews.
The problem usually isn't your content. It's when your content appears.
Key takeaways
- Many AI crawlers read the raw HTML your server sends — not the page your browser builds after running JavaScript.
- A client-side-rendered (CSR) single-page app often ships an almost-empty HTML shell, so the crawler sees a blank page.
- This hits React, Vue, and most vibe-coded SPAs (Lovable, Bolt, v0) by default.
- You don't always need to rebuild: prerendering, SSR/SSG, or a static fallback can make your real content visible.
- You can check what a crawler actually sees in about 60 seconds.
What "client-side rendering" actually means
When someone visits a server-rendered page, the server sends back HTML that already contains the words, headings, and links. The browser just displays them.
A client-side-rendered app works differently. The server sends a near-empty file — often just this:
<div id="root"></div>
<script src="/app.js"></script>
Your browser then downloads the JavaScript, runs it, calls your APIs, and builds the page live. A human never notices; it happens in milliseconds. But a machine that only reads the first response sees <div id="root"></div> and nothing else.
Why AI crawlers often stop at the empty shell
Classic Google has spent years building a two-stage renderer that executes JavaScript before indexing. Many AI answer engines have not. Their crawlers are frequently lighter: they fetch the HTML, extract the text, and move on. If the meaningful text only exists after JavaScript runs, there's nothing to extract.
So the model never ingests your value proposition, your feature list, your FAQ, or your pricing. When a user later asks it a question your page answers perfectly, you're simply not in the running — not because you ranked low, but because you were never read.
How do I know if my site is client-side rendered?
Two quick tests:
- View source, not inspect. Right-click → "View Page Source" (not "Inspect"). This shows the raw HTML the server sent. If you don't see your real headline and body text in there — only script tags and an empty
<div>— your content is rendered client-side. - Disable JavaScript in your browser's dev tools and reload. If the page goes blank or shows a spinner forever, that's roughly what a non-rendering crawler gets.
The fix — and why you probably don't need a rebuild
You have three practical paths, from lightest to heaviest:
1. Prerendering (lightest). A prerender service or build step generates a static HTML snapshot of each route and serves that snapshot to bots. Your app stays exactly as it is for human visitors; crawlers get fully-formed HTML. This is the fastest win for an existing SPA you don't want to touch.
2. Static generation (SSG). If your content doesn't change per-request — marketing pages, docs, a blog — generate real HTML at build time. Frameworks like Next.js, Astro, and Nuxt do this natively. The page ships complete on the first response.
3. Server-side rendering (SSR). The server renders the full HTML for each request, then "hydrates" into an interactive app in the browser. Best for dynamic, logged-out content that must always be current.
For most vibe-coded marketing sites, SSG or prerendering is enough — and neither forces you to rewrite your app.
The low-effort middle ground: even if you keep your SPA, make sure your most important text lives in the initial HTML — a real
<h1>, a paragraph describing what you do, and your key links. A page that's 90% interactive but ships its core message in plain HTML is already miles ahead of an empty<div id="root">.
Where this fits with the rest of your AI visibility
Rendering is the foundation. If the crawler can't read your text, nothing else matters — your structured data, your FAQ sections, your headings. They all have to exist in HTML a machine can parse before it ever runs JavaScript.
In our audit of 301 vibe-coded sites, the biggest single divide wasn't the builder — it was the domain setup: sites on a proper root domain averaged an AI Visibility Score of 43.8, versus just 24.3 for those stuck on a shared subdomain. Rendering is the same kind of invisible, structural issue: fix the plumbing, and your content finally reaches the models.
Check what the crawler sees — in 60 seconds
Don't guess whether your content survives the trip to an AI crawler. Run a free SearchAudit scan: paste your URL and we'll show you what an AI actually reads, whether your core text made it into the HTML, and exactly what to fix first — no account, no credit card.
→ Run your free 60-second audit
Suggested internal links (A1):
/blog/why-ai-search-cant-see-your-site/blog/json-ld-structured-data-ai-search/blog/make-lovable-site-visible-to-ai/blog/same-ai-visibility-fix-five-stacks/blog/301-vibe-coded-sites-ai-visibility



