← SEODiff Research Hub

Ghost Content: How Client-Side Rendering Erases Pages from AI

Your React app looks perfect in Chrome. To ChatGPT, it's an empty page.

SEODiff Research · February 2026

v1.0 · Data from 1,000,111 domain crawl · February 24, 2026

Abstract. We introduce the concept of ghost content — web page content that exists only in JavaScript memory and is invisible to AI crawlers. Using data from SEODiff's 1,000,111-domain crawl, we quantify the ghost ratio (percentage of content invisible without JS execution) across frameworks and rendering strategies. Pure client-side rendered (CSR) applications exhibit a median ghost ratio of 97%, meaning nearly all visible content vanishes when accessed by GPTBot, ClaudeBot, or PerplexityBot. We present framework-specific remediation strategies and demonstrate that implementing SSR reduces ghost ratio to below 5% while improving AI-Trust Score by an average of 34 points.
97%
Median ghost ratio for pure CSR apps
<5%
Ghost ratio after SSR implementation
38%
Of Graveyard sites have ghost ratio >80%
+34
Avg ACRI improvement after SSR fix

Table of Contents

  1. The Ghost Content Problem
  2. What AI Crawlers Actually See
  3. Measuring the Ghost Ratio
  4. Framework-by-Framework Analysis
  5. Impact on AI-Trust Score
  6. The Fix: SSR, SSG, and ISR
  7. Verification Protocol
  8. Conclusion

1. The Ghost Content Problem

When a user visits a modern React, Angular, or Vue website, their browser downloads a JavaScript bundle, executes it, and renders the content dynamically. The user sees a beautiful, interactive page.

When an AI crawler visits the same page, it downloads the initial HTML response. If that HTML contains only a <div id="root"></div> placeholder, the crawler sees exactly that — an empty container. The content doesn't exist yet because the JavaScript hasn't executed.

We call this ghost content: content that only exists after JavaScript execution. Like a ghost, it's visible to some observers (browsers) but invisible to others (crawlers).

👤 What Users See (Browser)

✓ Full content rendered by JavaScript

🤖 What AI Crawlers See (No JS)

<html>
<head>...</head>
<body>
  <div id="root"></div>
  <script src="/bundle.js"></script>
</body>
</html>
⚠ No content — 97% ghost ratio

Google's crawler (Googlebot) has a rendering queue that eventually executes JavaScript and indexes the rendered content. But AI-specific crawlers — GPTBot (OpenAI), ClaudeBot (Anthropic), PerplexityBot, and CCBot — do not render JavaScript. They read the initial HTTP response and move on.

The implication: If your content requires JavaScript to appear, it does not exist in ChatGPT's world, Perplexity's world, or Claude's world. You are a ghost to the fastest-growing search interfaces on the planet.

2. What AI Crawlers Actually See

To illustrate the problem concretely, here is what an AI crawler receives when visiting a typical React SPA:

<!-- What GPTBot receives from a typical React SPA -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Acme Corp</title>
    <link rel="stylesheet" href="/static/css/main.a8b2c3.css">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!-- This is ALL the content GPTBot sees. -->
    <!-- The actual product info, pricing, docs = INVISIBLE -->
    <script src="/static/js/bundle.f7e8d9.js"></script>
  </body>
</html>

The entire <body> is an empty div and a script tag. The AI has no product information, no pricing, no documentation, no structured data — nothing to extract, nothing to cite.

Contrast this with a server-side rendered (SSR) page:

<!-- What GPTBot receives from a Next.js SSR page -->
<html lang="en">
  <head>
    <title>Acme Corp — Enterprise CRM Platform</title>
    <script type="application/ld+json">
    {"@context":"https://schema.org","@type":"SoftwareApplication",
     "name":"Acme CRM","applicationCategory":"BusinessApplication",
     "offers":{"@type":"Offer","price":"299","priceCurrency":"USD"}}
    </script>
  </head>
  <body>
    <main>
      <article>
        <h1>Enterprise CRM Platform</h1>
        <p>Acme CRM helps businesses manage customer relationships
           with AI-powered insights...</p>
        <h2>Pricing</h2>
        <p>Enterprise plan: $299/month</p>
      </article>
    </main>
  </body>
</html>

Same product, same company — but GPTBot now receives the actual content, structured data, and semantic HTML. When a user asks ChatGPT "What does Acme CRM cost?", it can accurately answer "$299/month" instead of hallucinating or saying "I don't have that information."

3. Measuring the Ghost Ratio

We define the ghost ratio as the percentage of visible page content that is absent from the initial HTML response:

Ghost Ratio = 1 − (tokens in raw HTML / tokens after JS render) × 100%

A ghost ratio of 0% means all content is present in the initial HTML (fully server-rendered). A ghost ratio of 100% means the initial HTML contains zero content tokens.

In our 1,000,111-domain crawl, we measured the ghost ratio by comparing:

  1. Raw HTML tokens: Content tokens extracted from the HTTP response without JavaScript execution
  2. Rendered tokens: Content tokens after full browser rendering (via headless Chrome)

Distribution Across the Web

Ghost Ratio Range% of All DomainsMean ACRI% in Graveyard
0–5% (fully SSR)44%6218%
5–20% (mostly SSR)16%5129%
20–50% (hybrid)11%3848%
50–80% (mostly CSR)9%2272%
80–100% (pure CSR)20%1191%
Key finding: One in five websites (20%) has a ghost ratio above 80%. These sites serve almost no content in their initial HTML. 91% of them land in the AI Graveyard.

4. Framework-by-Framework Analysis

Ghost content is a framework problem, not a developer problem. The default configuration of each framework determines whether content is server-rendered or client-rendered:

FrameworkDefault RenderingMedian Ghost RatioGraveyard RateAI-Ready?
WordPressSSR (PHP)3%22%✓ Yes
Hugo / JekyllSSG0%15%✓ Yes
Next.js (SSR)SSR/SSG8%25%✓ Yes
AstroSSG/Islands2%14%✓ Yes
Nuxt (SSR)SSR10%28%✓ Yes
SvelteKitSSR5%20%✓ Yes
GatsbySSG + hydration12%30%~ Mostly
Next.js (CSR)CSR (no SSR)85%78%✗ No
Create React AppCSR only97%93%✗ No
Angular (default)CSR only96%91%✗ No
Vue CLI (default)CSR only95%89%✗ No
The framework trap: React, Angular, and Vue are not inherently bad for AI visibility. But their default project scaffolding (Create React App, Angular CLI, Vue CLI) creates pure CSR applications with near-100% ghost ratios. Developers must explicitly opt into SSR or SSG to be AI-visible.

The WordPress Advantage

WordPress powers approximately 43% of all websites, and its PHP-based architecture means all content is server-rendered by default. This is why WordPress sites dominate the AI-Trust leaderboard — not because WordPress is a "better" framework, but because its default rendering strategy accidentally makes it perfect for AI crawlers.

The lesson: AI readiness is a deployment strategy decision, not a framework quality decision.

5. Impact on AI-Trust Score

Ghost content doesn't just affect the ghosted site — it affects the entire AI citation graph. Here's why:

When a site with meaningful content (e.g., a tech blog) links to a ghosted site, that link exists in the AI graph. But when the AI crawler follows the link, it finds an empty page. The AI-Trust calculation gives this site a low ACRI score, which means links from it also pass minimal trust to others.

This creates a ghost content cascade: one site's CSR architecture doesn't just erase itself — it weakens the trust signal for every site that links to it.

Ghost Ratio vs. AI-Trust Distribution

Ghost RatioMean AI-Trust ScoreMedian Inbound Links% with Trust Score >0
0–5%12.4368%
5–20%8.1252%
20–50%4.3131%
50–80%1.2012%
80–100%0.304%

Sites with ghost ratio above 80% have an average AI-Trust Score of just 0.3. Only 4% of them appear anywhere in the AI citation graph. They are, for all practical purposes, nonexistent in the AI era.

6. The Fix: SSR, SSG, and ISR

The solution is straightforward: ensure your server delivers real content in the initial HTML response. The three primary strategies are:

6.1 Server-Side Rendering (SSR)

The server generates the full HTML for each request. Content is immediately available to all crawlers.

Next.js

// pages/product.js — Before (CSR)
export default function Product() {
  const [data, setData] = useState(null);
  useEffect(() => { fetch('/api/product').then(r => setData(r.json())); }, []);
  return data ? <ProductView data={data} /> : <Loading />;
}

// pages/product.js — After (SSR)
export async function getServerSideProps() {
  const data = await fetch('https://api.example.com/product').then(r => r.json());
  return { props: { data } };
}
export default function Product({ data }) {
  return <ProductView data={data} />;
}

Angular Universal

// Enable Angular Universal SSR
ng add @nguniversal/express-engine

// server.ts — Express server renders Angular on the server
app.engine('html', ngExpressEngine({ bootstrap: AppServerModule }));
app.get('*', (req, res) => { res.render('index', { req }); });

Vue / Nuxt

// nuxt.config.ts — SSR is default, but ensure it's not disabled
export default defineNuxtConfig({
  ssr: true,  // This is the default — don't set it to false
})

// pages/product.vue — use useAsyncData for SSR data fetching
<script setup>
const { data } = await useAsyncData('product',
  () => $fetch('/api/product')
);
</script>

6.2 Static Site Generation (SSG)

Pages are pre-rendered at build time. Ideal for content that doesn't change per-request (blogs, docs, marketing pages).

// Next.js — SSG with getStaticProps
export async function getStaticProps() {
  const data = await fetchProductData();
  return {
    props: { data },
    revalidate: 3600, // ISR: re-generate every hour
  };
}

6.3 Incremental Static Regeneration (ISR)

Combines the performance of SSG with near-real-time content. Pages are statically generated but revalidated on a schedule. Next.js, Nuxt, and SvelteKit all support this pattern.

6.4 The Astro/Islands Approach

For content-heavy sites, Astro sends zero JavaScript by default. Interactive components ("islands") are hydrated only where needed. This produces ghost ratio ~0% while maintaining full interactivity where required.

---
// src/pages/product.astro — zero JS by default
import ProductHero from '../components/ProductHero.astro';
import PricingTable from '../components/PricingTable.astro';
import InteractiveDemo from '../components/Demo.jsx';
---

<main>
  <ProductHero />      <!-- Static: 0 JS -->
  <PricingTable />     <!-- Static: 0 JS -->
  <InteractiveDemo client:visible />  <!-- Hydrates when visible -->
</main>

7. Verification Protocol

After implementing SSR/SSG, verify that your content is actually present in the initial HTML:

Quick Test (Command Line)

# Check if your main content appears in the raw HTML
curl -s https://your-site.com | grep -c "your unique content phrase"

# If the result is 0, your content is ghost content
# If the result is ≥1, your content is server-rendered

# Count content tokens vs total tokens
curl -s https://your-site.com | wc -w
# Compare with browser-rendered word count

SEODiff Scanner

For a comprehensive analysis, run your domain through the SEODiff scanner. It measures ghost ratio, ACRI score, token bloat, and all five visibility pillars — telling you exactly what AI crawlers see and what they miss.

Interpreting Ghost Ratio

Ghost RatioInterpretationAction
0–5%Fully server-rendered. AI can read everything.No action needed.
5–20%Mostly SSR, minor JS-dependent elements.Low priority — ensure critical content is in the SSR portion.
20–50%Hybrid rendering. Significant content hidden.Audit which content is JS-only and prioritize SSR for key pages.
50–80%Mostly client-rendered. Most content invisible to AI.Implement SSR for all content pages (products, docs, pricing).
80–100%Pure CSR. Your site is a ghost to AI crawlers.Critical: migrate to SSR/SSG framework or add pre-rendering.

8. Conclusion

Ghost content is the single largest contributor to AI invisibility after explicit bot blocking. While robots.txt blocking is a policy choice (and easily reversible in minutes), ghost content is an architectural problem that requires framework-level changes to fix.

The good news: every major JavaScript framework now supports SSR or SSG. The fix is not a paradigm shift — it is a deployment configuration change. Next.js, Nuxt, SvelteKit, and Astro make SSR the default or trivially easy to enable.

The bad news: 20% of the web still runs pure CSR applications with ghost ratios above 80%. These sites are invisible to ChatGPT, Perplexity, Claude, and Google AI Overviews. They have effectively opted out of the fastest-growing search channel in history.

The bottom line: If curl your-site.com returns an empty <div id="root">, you are a ghost. Every AI-generated answer about your industry is being written without your content. The fix is one configuration change away.

👻 Is Your Site a Ghost?

Run a free scan to see your ghost ratio, ACRI score, and what AI crawlers actually see when they visit your site.

Scan for Ghost Content →

No sign-up required · Compares raw HTML vs rendered content · Results in seconds

References

  1. SEODiff Research. "The Great AI Disconnect: Why Domain Authority is Dead." February 2026. seodiff.io/research/ai-trust-2026
  2. SEODiff Research. "The Science of ACRI: How Technical Structure Predicts AI Retrieval." February 2026. seodiff.io/research/science-of-acri-2026
  3. SEODiff Research. "Hallucination Risk: How Structural Noise Causes LLMs to Invent Facts." February 2026. seodiff.io/research/hallucination-risk
  4. SEODiff Research. "Extraction Lab: How HTML Structure Determines LLM Fact Extraction." February 2026. seodiff.io/research/extraction-lab-whitepaper
  5. Web Almanac 2024. "JavaScript." HTTP Archive. almanac.httparchive.org/en/2024/javascript

Continue Reading