Six demos · three frameworks · before / after

# Same site.Two AI realities.

The same Coastline harbor-data site, six times. Three frameworks. Two states each: with agentsite, without.

Curl any of the six. The **before** demos are what AI crawlers see today on most SPAs and Next sites: an empty shell, or content with no JSON-LD schema, no `llms.txt`, no per-page markdown. The **after** demos run the same source code with the agentsite middleware wired in. Compare them side by side and you can see exactly what answer engines pick up from each — and why one gets quoted and the other doesn't.

[Run the assessment on your site](/score) [Or sign up to install →](/auth/sign-up)

## The gallery

Three frameworks, two states each. Same Coastline content (a harbor-data API project — home, pricing, FAQ) so the only variable is whether the agentsite middleware is installed. Each demo is a real deploy on real infrastructure — click through and curl it.

### Vue

Vue 3 + vue-router. Plain Express serving the Vite build.

Before[vue-before.agentsite.app ↗](https://vue-before.agentsite.app)

```
$ curl -A 'GPTBot' https://vue-before.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
```

-   ✕ <div id="app"></div> shell on every route
-   ✕ No /llms.txt, no /sitemap.xml
-   ✕ No JSON-LD schema
-   ✕ Empty <title> until JS runs

[Score this URL →](/score?domain=https://vue-before.agentsite.app)

After[vue-after.agentsite.app ↗](https://vue-after.agentsite.app)

```
$ curl -A 'GPTBot' https://vue-after.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <title>FAQ — Coastline</title>
    <meta name="description" content="…tide data sources…" />
    <link rel="canonical" href="https://vue-after.agentsite.app/faq" />
    <link rel="alternate" type="text/markdown" href="/faq.md" />

    <script type="application/ld+json" data-agentsite="schema"
            data-type="FAQPage">{ "@context": "https://schema.org", … }</script>
    <script type="application/ld+json" data-agentsite="schema"
            data-type="Article">{ … }</script>
  </head>
  <body>
    <div id="app"></div>
    <div id="agentsite-preboot" aria-hidden="true">
      <pre data-content-type="text/markdown" data-source="agentsite">
        # FAQ
        ## Where does your tide data come from?
        NOAA Tides & Currents (CO-OPS)…
      </pre>
    </div>
  </body>
</html>
```

-   ✓ Server-injected agent-readable markdown per route
-   ✓ /llms.txt + /llms-full.txt + /faq.md
-   ✓ Article + FAQPage + Organization JSON-LD
-   ✓ agent-card.json on /.well-known/

[Score this URL →](/score?domain=https://vue-after.agentsite.app)

### React

React 18 + react-router. Plain Express serving the Vite build.

Before[react-before.agentsite.app ↗](https://react-before.agentsite.app)

```
$ curl -A 'GPTBot' https://react-before.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
```

-   ✕ <div id="root"></div> shell on every route
-   ✕ No /llms.txt, no /sitemap.xml
-   ✕ No JSON-LD schema
-   ✕ Empty <title> until JS runs

[Score this URL →](/score?domain=https://react-before.agentsite.app)

After[react-after.agentsite.app ↗](https://react-after.agentsite.app)

```
$ curl -A 'GPTBot' https://react-after.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <title>FAQ — Coastline</title>
    <meta name="description" content="…tide data sources…" />
    <link rel="canonical" href="https://react-after.agentsite.app/faq" />
    <link rel="alternate" type="text/markdown" href="/faq.md" />

    <script type="application/ld+json" data-agentsite="schema"
            data-type="FAQPage">{ "@context": "https://schema.org", … }</script>
    <script type="application/ld+json" data-agentsite="schema"
            data-type="Article">{ … }</script>
  </head>
  <body>
    <div id="app"></div>
    <div id="agentsite-preboot" aria-hidden="true">
      <pre data-content-type="text/markdown" data-source="agentsite">
        # FAQ
        ## Where does your tide data come from?
        NOAA Tides & Currents (CO-OPS)…
      </pre>
    </div>
  </body>
</html>
```

-   ✓ Server-injected agent-readable markdown per route
-   ✓ /llms.txt + /llms-full.txt + /faq.md
-   ✓ Article + FAQPage + Organization JSON-LD
-   ✓ agent-card.json on /.well-known/

[Score this URL →](/score?domain=https://react-after.agentsite.app)

### Next.js

Next 14 App Router. SSR works — but the per-route AEO surface is bare.

Before[next-before.agentsite.app ↗](https://next-before.agentsite.app)

```
$ curl -A 'GPTBot' https://next-before.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
```

-   ✕ SSR body content (Next gives this for free)
-   ✕ Per-route <title> + meta description
-   ✕ No JSON-LD schema
-   ✕ No /llms.txt or .md mirror

[Score this URL →](/score?domain=https://next-before.agentsite.app)

After[next-after.agentsite.app ↗](https://next-after.agentsite.app)

```
$ curl -A 'GPTBot' https://next-after.agentsite.app/faq

<!doctype html>
<html lang="en">
  <head>
    <title>FAQ — Coastline</title>
    <meta name="description" content="…tide data sources…" />
    <link rel="canonical" href="https://next-after.agentsite.app/faq" />
    <link rel="alternate" type="text/markdown" href="/faq.md" />

    <script type="application/ld+json" data-agentsite="schema"
            data-type="FAQPage">{ "@context": "https://schema.org", … }</script>
    <script type="application/ld+json" data-agentsite="schema"
            data-type="Article">{ … }</script>
  </head>
  <body>
    <div id="app"></div>
    <div id="agentsite-preboot" aria-hidden="true">
      <pre data-content-type="text/markdown" data-source="agentsite">
        # FAQ
        ## Where does your tide data come from?
        NOAA Tides & Currents (CO-OPS)…
      </pre>
    </div>
  </body>
</html>
```

-   ✓ Same SSR body, plus...
-   ✓ /llms.txt + /sitemap.xml route handlers
-   ✓ Per-route JSON-LD via <AgentsiteSchemaTags />
-   ✓ .md content negotiation via middleware

[Score this URL →](/score?domain=https://next-after.agentsite.app)

## What the install adds

Seven discovery surfaces, mapped to the [five-layer AEO model](/aeo) (Layers 1-3 here; Layer 4 is page-level content quality and Layer 5 is external mention measurement — both shown in the AEO Report). The before column is what most sites ship today, including most server-rendered Next.js sites. The after column is what AgentSite adds, automatically, in one install. Want the deep theory? Read [the FAQ](/faq).

| Surface | Layer | Before | After |
| --- | --- | --- | --- |
| Server-injected agent-readable markdown | Layer 1 | ✕ Empty SPA shell | ✓ <div><pre> markdown body + enriched <title>, meta, JSON-LD per route |
| robots.txt with AI-bot allowlist | Layer 1 | ✕ Default (or missing) | ✓ GPTBot, ClaudeBot, Perplexity, Apple-Extended |
| sitemap.xml | Layer 1 | ✕ Often missing on SPAs | ✓ Auto-generated from rendered routes |
| /llms.txt + /llms-full.txt | Layer 2 | ✕ Not present | ✓ Editorial index of every public page |
| Per-page .md mirror | Layer 2 | ✕ Not available | ✓ /faq.md, /pricing.md, /.md per route |
| Agentic surfaces (.well-known) | Layer 2 | ✕ Not present | ✓ agent-card.json, mcp.json, ai-agent.json |
| JSON-LD (Article / FAQPage / Org) | Layer 3 | ✕ Not emitted | ✓ Validated, per-@type <script> blocks |

## How the after demos stay clean

The before demos are the source of truth. The after demos are generated mechanically — copy the before directory verbatim, drop in the agentsite middleware, redeploy. No hand-edits to the after, ever; otherwise it'd drift from "before plus install" and the comparison would lose its point.

terminal

```
# Edit a before demo
$EDITOR demos/react-before/src/pages/Pricing.tsx

# Wipe + regenerate the after copy from scratch
devops/scripts/regenerate-demo-after.sh react

# Commit and push — both demos redeploy
git add demos/ && git commit && git push
```

That's the whole gallery, end to end. Edit the before, regenerate the after, deploy. The comparison stays honest because the after is never anyone's hand-craft — it's the before plus the install.

Free · No signup · Emailed to your inbox

## Now run it on your site.

Sixty seconds. Paste your URL, see the side-by-side of what humans see vs. what agents see, with the dimension-by-dimension score for why answer engines won't quote you. Or sign up and install — pick the pattern that matches your stack. About five minutes start to finish.

[Take the 60-second assessment](/score) [Or sign up →](/auth/sign-up)

Cookies

We use cookies to make this site work and to understand how it's used. [Learn more](https://www.cookiesandyou.com/)

Decline Got it