AEO is the new SEO

# Your next customer may never visit your website.

Get more AI user traffic and agent visibility.

**AgentSite is a magic pill for your AEO.** One simple injection fixes your site's AEO and agent-visibility problems — we generate and inject high-quality AEO + agent content (titles, meta, OpenGraph, JSON-LD, markdown twins, WebMCP tools) into your existing site, **without modifying any site code**.

agentsiteagentsite

Diagnose my site — free

Free · no signup · live on screen in under 3 minutes · snippet stays in your codebase

Asked the best reasoning model in the world

## Even Claude Opus won’t read your site.

Typical websites built with React, Vue, or Angular show empty pages to agents. While agents stop reading advanced server-side rendering sites that render the kitchen sink for old SEO.

**Modern AEO is about clean direct content readable by agents.** Not browsers and humans.

[Get your score — free](/score)

![Software professional with a skeptical expression](/portraits/c1.png "AI rendering of a product manager thinking about AEO")

Appears to be a marine biology research portal focused on lobster habitats in the North Atlantic.

— Claude Opus 4.7, asked about lobster.app

Claude Opus 4.7 — what can you tell me about lobster.appClaude Opus 4.7 — what can you tell me about workspot.ioClaude Opus 4.7 — what can you tell me about ridesell.appClaude Opus 4.7 — what is paperflow.io

## AEO has many angles. Here's where AgentSite sits.

Everyone has a different view of AEO — many products call themselves AEO, and they mostly do different things. Three categories you've probably seen, and where AgentSite is positioned against each one.

AEO graders

HubSpot grader, isitagentready.com, "ask GPT what it sees"

**They ask ChatGPT things you could've asked yourself. We actually crawl your site too.**

Most graders just pass your URL to a chat model and surface its answer — a question you can ask yourself, packaged as a lead-magnet for their actual product.

We crawl the assets a chat model never touches — meta, JSON-LD, generated markdown, `/llms.txt`, sitemap, `/.well-known/*` — and run a multi-pass problem assessment across eight citability dimensions. _Then_ we ask the chat models too. Then we install the middleware that moves the score.

Mention monitoring

Profound, Scrunch, Otterly

**Tracks how you're viewed externally. Doesn't move the needle.**

Useful information — but knowing you're not mentioned doesn't make you mentioned. AgentSite makes sure the models have something worth quoting in the first place.

Framework migration / dev work

Next.js, Nuxt, SvelteKit SSR rewrites

**Real work, real complexity added to your stack.**

Manual SSR migrations take weeks and bring permanent build-time overhead. AgentSite gives you robust, continuously improving AEO without complicating your build — install once, snippet handles drift.

### AgentSite works alongside:

Content improvement

Humans still write better than us. We ship automated basics and guidance; great pages still win.

External signals

Backlinks, getting featured, brand authority — still matters, still needed. AgentSite doesn't replace it.

Anatomy of an injection

## Before vs after AgentSite — same URL, real HTML.

Two fetches against the same live SPA. On the left, the raw shell agents see without us. On the right, the same URL with AgentSite's one-injection splice — **highlighted lines are what we added**. No code changes to your site; the snippet does it at response time.

Target`https://agentsite.app/features`

static snapshot

\+ Title & meta tags\+ JSON-LD schema\+ Markdown body\+ WebMCP tools

curl -H 'X-Agentsite: none' 'https://agentsite.app/features'

```
1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="UTF-8"/>
5  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6  <title>agentsite — ready for the agent era.</title>
7  <meta name="description" content="Make your site agent-readable. Yours by default — we watch the agents, ship the best practices, and level your site up. ChatGPT, Claude, Gemini, and Perplexity see your SPA as an empty &lt;div id=&quot;app&quot;&gt;. We fix that with a snippet that stays in your codebase.">
8
9  <link rel="icon" type="image/x-icon" href="/favicon.ico"/>
10  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png"/>
11  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png"/>
12  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
13
14  <meta property="og:type" content="website">
15  <meta property="og:site_name" content="AgentSite">
16  <meta property="og:url" content="https://agentsite.app/">
17  <meta property="og:title" content="agentsite — ready for the agent era.">
18  <meta property="og:description" content="Make your site agent-readable. Yours by default — we watch the agents, ship the best practices, level your site up. Snippet stays in your codebase.">
19  <meta property="og:image" content="https://agentsite.app/brand/og-card.png">
20  <meta property="og:image:width" content="1200">
21  <meta property="og:image:height" content="630">
22  <meta property="og:image:alt" content="Claude can't read your SPA. AgentSite is middleware that fixes that — get your score, free.">
23  <!-- Square variant for clients that prefer 1:1 (WhatsApp, iMessage). -->
24  <meta property="og:image" content="https://agentsite.app/brand/og-square.png">
25  <meta property="og:image:width" content="1200">
26  <meta property="og:image:height" content="1200">
27  <meta property="og:image:alt" content="Claude can't read your SPA. AgentSite is middleware that fixes that — get your score, free.">
28  <meta name="twitter:card" content="summary_large_image">
29  <meta name="twitter:title" content="agentsite — ready for the agent era.">
30  <meta name="twitter:description" content="Make your site agent-readable. Yours by default — we watch the agents, ship the best practices, level your site up. Snippet stays in your codebase.">
31  <meta name="twitter:image" content="https://agentsite.app/brand/og-card.png">
32
33  <!-- env dynamically generated by container -->
34  <script src="/env.js"></script>
35
36  <!-- Google tag (gtag.js) -->
37  <script>
38    function loadScript(src, async) {var script = document.createElement("script");script.setAttribute('src', src);if (async) script.setAttribute('async', "");document.head.appendChild(script);}
39    if (window.env.GOOGLE_ID) {
40      loadScript("https://www.googletagmanager.com/gtag/js?id=" + window.env.GOOGLE_ID, true);
41    }
42  </script>
43  <script>
44    window.dataLayer = window.dataLayer || [];
45
46    function gtag() {
47      dataLayer.push(arguments);
48    }
49
50    if (window.env.GOOGLE_ID) {
51      gtag('js', new Date());
52      gtag('config', window.env.GOOGLE_ID);
53    }
54
55    // todo: uncomment consent when analytics tests complete
56    // const consent = localStorage.getItem('consentParams');
57    // gtag('consent', 'default', consent ? JSON.parse(consent) : {ad_storage: 'denied', analytics_storage: 'denied'});
58  </script>
59  <script type="module" crossorigin src="/assets/index-Wz56DZf_.js"></script>
60  <link rel="modulepreload" crossorigin href="/assets/naive-ui-bij2l7m4.js">
61  <link rel="modulepreload" crossorigin href="/assets/markdown-CBjZTZqh.js">
62  <link rel="stylesheet" crossorigin href="/assets/index-CLD4np5n.css">
63</head>
64
65<body>
66<div id="app"></div>
67</body>
68</html>
69
```

curl 'https://agentsite.app/features'

```
1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="UTF-8"/>
5  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6  <title>Features — install patterns — agentsite</title>
7  <meta name="description" content="AgentSite ships nginx, Express, Express-sidecar, Edge, and streaming-SSR SDK installs. Per-page markdown mirrors, /llms.txt, FAQPage schema, and request cache.">
8
9  <link rel="icon" type="image/x-icon" href="/favicon.ico"/>
10  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png"/>
11  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png"/>
12  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
13
14  <meta property="og:type" content="website">
15  <meta property="og:site_name" content="AgentSite">
16  <meta property="og:url" content="https://agentsite.app/">
17  <meta property="og:title" content="Features — install patterns — agentsite">
18  <meta property="og:description" content="AgentSite ships nginx, Express, Express-sidecar, Edge, and streaming-SSR SDK installs. Per-page markdown mirrors, /llms.txt, FAQPage schema, and request cache.">
19  <meta property="og:image" content="https://agentsite.app/brand/og-card.png">
20  <meta property="og:image:width" content="1200">
21  <meta property="og:image:height" content="630">
22  <meta property="og:image:alt" content="Claude can't read your SPA. AgentSite is middleware that fixes that — get your score, free.">
23  <!-- Square variant for clients that prefer 1:1 (WhatsApp, iMessage). -->
24  <meta property="og:image" content="https://agentsite.app/brand/og-square.png">
25  <meta property="og:image:width" content="1200">
26  <meta property="og:image:height" content="1200">
27  <meta property="og:image:alt" content="Claude can't read your SPA. AgentSite is middleware that fixes that — get your score, free.">
28  <meta name="twitter:card" content="summary_large_image">
29  <meta name="twitter:title" content="Features — install patterns — agentsite">
30  <meta name="twitter:description" content="AgentSite ships nginx, Express, Express-sidecar, Edge, and streaming-SSR SDK installs. Per-page markdown mirrors, /llms.txt, FAQPage schema, and request cache.">
31  <meta name="twitter:image" content="https://agentsite.app/brand/og-card.png">
32
33  <!-- env dynamically generated by container -->
34  <script src="/env.js"></script>
35
36  <!-- Google tag (gtag.js) -->
37  <script>
38    function loadScript(src, async) {var script = document.createElement("script");script.setAttribute('src', src);if (async) script.setAttribute('async', "");document.head.appendChild(script);}
39    if (window.env.GOOGLE_ID) {
40      loadScript("https://www.googletagmanager.com/gtag/js?id=" + window.env.GOOGLE_ID, true);
41    }
42  </script>
43  <script>
44    window.dataLayer = window.dataLayer || [];
45
46    function gtag() {
47      dataLayer.push(arguments);
48    }
49
50    if (window.env.GOOGLE_ID) {
51      gtag('js', new Date());
52      gtag('config', window.env.GOOGLE_ID);
53    }
54
55    // todo: uncomment consent when analytics tests complete
56    // const consent = localStorage.getItem('consentParams');
57    // gtag('consent', 'default', consent ? JSON.parse(consent) : {ad_storage: 'denied', analytics_storage: 'denied'});
58  </script>
59  <script type="module" crossorigin src="/assets/index-Wz56DZf_.js"></script>
60  <link rel="modulepreload" crossorigin href="/assets/naive-ui-bij2l7m4.js">
61  <link rel="modulepreload" crossorigin href="/assets/markdown-CBjZTZqh.js">
62  <link rel="stylesheet" crossorigin href="/assets/index-CLD4np5n.css">
63  <link rel="canonical" href="https://agentsite.app/features">
64  <script type="application/ld+json" data-agentsite="bundle" data-agentsite-version="0.3.0">{"source":"agentsite","engine":"playwright","cacheStatus":"hit","url":"https://agentsite.app/features","renderedAt":"2026-06-16T20:50:56.101Z","expiresAt":"2026-06-17T20:50:56.101Z"}</script>
65  <script type="application/ld+json" data-agentsite="schema" data-type="Organization">{"@id":"https://agentsite.app/#organization","url":"https://agentsite.app","name":"agentsite","@type":"Organization","sameAs":["https://www.linkedin.com/in/dathan-guiley/"],"@context":"https://schema.org"}</script>
66  <script type="application/ld+json" data-agentsite="schema" data-type="WebPage">{"@id":"https://agentsite.app/features#webpage","url":"https://agentsite.app/features","name":"Features — install patterns — agentsite","@type":"WebPage","@context":"https://schema.org","isPartOf":{"@id":"https://agentsite.app/#website"},"description":"AgentSite's features ship across install patterns: nginx, Express, Express-sidecar, Edge, and streaming-SSR SDK. Each install gets the same render bundle — markdown body, schema graph, OpenGraph meta — plus per-page .md mirrors, an authoritative /llms.txt index, FAQPage schema synthesis from question headings, and a request cache. Pick the install pattern that matches your stack.","primaryImageOfPage":{"url":"https://agentsite.app/brand/og-card.png","@type":"ImageObject"}}</script>
67  <script type="application/ld+json" data-agentsite="schema" data-type="WebSite">{"@id":"https://agentsite.app/#website","url":"https://agentsite.app/","name":"agentsite","@type":"WebSite","@context":"https://schema.org","publisher":{"@id":"https://agentsite.app/#organization"}}</script>
68  <script data-agentsite="preboot-toggle">document.documentElement.setAttribute('data-agentsite-js','1')</script>
69  <style data-agentsite="preboot-style">html[data-agentsite-js="1"] #agentsite-preboot{display:none}</style>
70</head>
71
72<body>
73<div id="agentsite-preboot" aria-hidden="true">
74<pre data-content-type="text/markdown" data-source="agentsite">
75Features
76
77# What you get when you install AgentSite.
78
79AgentSite's features ship across install patterns: nginx, Express, Express-sidecar, Edge, and streaming-SSR SDK. Each install gets the same render bundle — markdown body, schema graph, OpenGraph meta — plus per-page `.md` mirrors, an authoritative `/llms.txt` index, FAQPage schema synthesis from question headings, and a request cache. Pick the install pattern that matches your stack.
80
81More organic traffic from AI search
82
83Agents that can read your site cite your site. Citations send users back. SPAs that ship an empty shell don't get cited — they get skipped.
84
85Trust with agent-first users
86
87People navigating with ChatGPT, Claude, Perplexity notice which sites their agents handle cleanly. Those are the sites they remember — and prefer.
88
89Stop worrying about AEO.
90
91We take what your site naturally produces and make every agent contact point better through our generated agent version — llms.txt, schema, markdown, the lot. You install once; we keep up with the drift.
92
93Three things you get out of the box: agent-readable content generated on demand, standards-compliant docs that stay current as the standards drift, and intelligent merging with the meta and schema you already wrote. Pick the install pattern that matches your deploy — Nginx, Express, Express-Sidecar, Edge, or a streaming-SSR SDK — and the same render bundle lands in your response.
94
95## 1 · Dynamic generation of content for agents
96
97Every page on your SPA gets agent-readable content rendered when it's first asked for — not authored by you, not stale, not frozen at build time. Headless Chromium runs your shell, waits for content, and captures the title, description, og:image, JSON-LD graph, and markdown body that an actual user would see. On cold miss the snippet serves your unmodified shell immediately and renders in the background; first agent to hit a path warms the cache for everyone after.
98
99![Clean markdown body served at agentsite.app/install.md — the exact bytes an agent extracts.](/brand/features/feature-1-markdown.png)
100
101`agentsite.app/install.md` — the same markdown body an agent reads when it fetches your page. Add `.md` to any path; same content, no HTML chrome.
102
103-   **Preboot hidden-div default.** The markdown body lands inside `&lt;div id="agentsite-preboot" aria-hidden="true"&gt;&lt;pre data-content-type="text/markdown"&gt;` just before `&lt;/body&gt;`. A toggle script + style in `&lt;head&gt;` hides it the moment JS boots, so humans never see it; agents and extractors that strip `&lt;noscript&gt;` (Claude.ai's web tool, most readability libs) read it cleanly. Per-site override switches to legacy `&lt;noscript&gt;` mode for tools that honor that (Claude Code's WebFetch).
104-   **Wait-for-generation: `robots-only` by default.** Bots are usually the first requester of a page; they don't retry. So bots block on the first render and get real content. Humans get the unmodified shell + an async render — they never pay the scan-and-generate latency. Switchable per-site to `always` or `never`.
105-   **TL;DR extraction per page.** 40–60-word direct answer drives meta descriptions + article descriptions when your static defaults are too generic.
106-   **Content-hash dedupe.** When nothing on the page changed, we extend the cache expiry without re-running the renderer — `dateModified` stays truthful instead of refreshing to "now" on every request.
107-   **Per-page markdown.** Same content as the preboot body, in a denser format. Reachable via `Accept: text/markdown` or by adding `.md` to any path.
108
109## 2 · Best-practice documents that stay current
110
111Every standards-compliant doc an AI crawler expects on your domain — generated, served, kept current as the standards drift. You ship zero static files; the snippet serves them all dynamically from your live cached bundles.
112
113![agentsite.app/llms.txt rendering — site overview with page list and TL;DRs.](/brand/features/feature-2-llms-txt.png)![agentsite.app/robots.txt rendering — granular AI-bot allow-list with comments.](/brand/features/feature-2-robots-txt.png)![agentsite.app/sitemap.xml rendering — walked from cached routes, standard urlset.](/brand/features/feature-2-sitemap-xml.png)
114
115Live on `agentsite.app`: `/llms.txt` · `/robots.txt` · `/sitemap.xml`. Generated, not authored. Customer files in `dist/` win.
116
117-   **`/llms.txt` + `/llms-full.txt`** per Jeremy Howard's spec — a pointer overview at `/llms.txt`, with detail in `/install.md` and `/docs.md` for agents arriving with no prior context.
118-   **`/sitemap.xml`** walks your cached routes, drops auth/admin paths, emits standard sitemaps.org `&lt;urlset&gt;`.
119-   **`/robots.txt`** with a granular AI-bot allow-list: citation bots allowed, training bots policy explicit, heavily commented so you can audit.
120-   **Per-page `.md` mirrors.** Mintlify-style content negotiation: `Accept: text/markdown` or `.md` path suffix returns the markdown body without HTML chrome.
121-   **Customer overrides win.** Ship `dist/llms.txt` and your file beats ours via static-route precedence. We're the default, not the ceiling.
122-   **Schema.org drift handled.** Our generator updates as standards evolve; customer-shipped JSON-LD freezes on the day it's written. Install-stays-fresh is the live argument here.
123
124## 3 · Intelligent merging with what you already have
125
126Your existing meta, schema, and per-page overrides are preserved verbatim — we fill gaps, we don't overwrite. The page reads as "yours plus ours," not "ours instead of yours."
127
128![JSON-LD blocks pulled from agentsite.app/pricing — Article, Organization, WebPage, FAQPage emitted via @id-linked nodes.](/brand/features/feature-3-jsonld.png)
129
130Real JSON-LD blocks from `agentsite.app/pricing` — multiple `@type`s cross-linked via `@id`. Customer-shipped schema wins; ours fills the gaps.
131
132-   **Meta refreshed in place.** Your indentation, comments, and per-page overrides survive. Hand-rolled `og:type=article`, custom canonicals, alternate languages — pass through untouched.
133-   **JSON-LD only-if-absent.** Existing `&lt;script type="application/ld+json"&gt;` blocks are parsed; we emit ONLY the `@type`s not already present. Per-page hand-rolled JSON-LD always wins; we cross-link new nodes to your existing ones via `@id` so the graph resolves into one coherent description.
134-   **LLM-assisted FAQ extraction** refines `FAQPage` schema from prose that doesn't follow the `## Question?` heading convention. We won't name a specific model — we iterate on what scores best on our own renders.
135-   **Customer files in `dist/` win** over our generated versions of the same path (llms.txt, robots.txt, sitemap.xml). Our default is the floor; you can always go higher.
136
137## 4 · Drops into your stack
138
139Same render bundle, different injection point — pick the shape your deploy already supports.
140
141![Terminal showing the Express install pattern — curl the snippet, three lines of glue code, set the token, ship.](/brand/features/feature-4-install.png)
142
143Express install pattern end-to-end: curl the snippet, three lines of glue, set `AGENTSITE_TOKEN`, ship. About five minutes start to finish.
144
145Nginx
146
147Our favorite
148
149Thin nginx in front of a static SPA. Add a handful of `location` + `proxy_pass` directives; agentsite owns the HTML byte stream. No Node sidecar, no edge function, no code in your deploy.
150
151Express
152
153Static SPA in a Node container. The snippet runs in your Express middleware, splices the render bundle into your `index.html` before responding. One CJS file, audit-able line by line.
154
155Express-Sidecar
156
157Non-streaming SSR framework (Next.js pages router, Nuxt 2, Rails, Django, PHP-FPM, etc.). Snippet runs as a reverse-proxy sidecar in front of your framework's existing server.
158
159Edge
160
161Cloudflare Pages, Vercel edge, Netlify, or any platform that runs Fetch-API edge functions instead of arbitrary Node. Drop in `agentsite-edge.mjs` + the platform's edge-middleware shell.
162
163SDK — streaming SSR
164
165Framework SDK for streaming SSR — Next.js App Router (RSC), Nuxt 3 streaming, SvelteKit streaming, Suspense streaming. In-process render hooks instead of a proxy in front of your framework.
166
167**Latency-sensitive.** Cold miss responds with your unmodified shell in milliseconds and renders in the background. Warm hits read the cached bundle from Postgres + edge cache. Sites that need first-render freshness on bot traffic flip wait-for-generation to `always`; sites that prioritize human TTFB above all keep the default. `Cache-Control: no-cache` forces a fresh render on any request.
168
169**Further out.** Native nginx-njs port, CloudFront Lambda@Edge, Python (Django/Flask/FastAPI), PHP (PHP-FPM / WordPress). No build-time pre-render CLI — SPAs are runtime-rendered by design.
170
171## 5 · Tunable from the dashboard
172
173Per-site controls for the behaviors that matter, plus the AEO Report — the same scan we use to grade our own renders, run against any URL.
174
175![AgentSite dashboard per-site overview — snippet health, hit rate, generated files (llms.txt, llms-full.txt, sitemap.xml, robots.txt) with per-file re-crawl, and the AI-bot citation + training allow toggles.](/brand/features/feature-5-dashboard.png)
176
177Per-site overview at [/dashboard](/dashboard) — snippet health, hit rate, the four generated files with per-file re-crawl, and the AI-bot citation + training allow toggles. Settings tab adds wait-for-generation, render-mode, and skip patterns covered in the bullets below.
178
179-   **Wait-for-generation policy.**`robots-only` (default) · `always` · `never`. Decides who blocks for the first render on a cold path.
180-   **Render-mode override.** Preboot hidden-div (default) or legacy `&lt;noscript&gt;`. Switch per-site for tools that honor one but not the other.
181-   **Skip patterns.** Glob-match paths you don't want rendered (admin, search, attack probes). Copy-paste textarea; common probes auto-add as they're detected.
182-   **AEO Report.** Run an 8-dimension citability scan on any URL at [/score](/score). Free, no signup. The same yardstick we grade our own output on.
183-   **Per-site API tokens.** `asit_…` opaque strings, hashed with SHA-256. Pinned to one registered domain — leaked tokens are useless off-domain. Rotate any time.
184-   **Usage tracking.** One row per `(site, day_utc)` with cache-hit / cache-miss / forced-sync / auth-failure counters. 30 days of history per site in the dashboard.
185
186## 6 · What you didn't have to build yourself
187
188Each row below is something AgentSite replaces. The alternative imposes the cost in the left column; the feature is that you don't pay it.
189
190Second parallel deployment (Chromium fleet on your infra)
191
192Render fleet runs on ours. Your container is just Node + your SPA + a small snippet.
193
194Build-time pre-rendering of every route
195
196We render on demand and cache. First agent to hit a path warms the cache for everyone after.
197
198Periodic snapshot drift between rebuilds
199
200Content-hash dedupe + 24h TTL with `Cache-Control: no-cache` bypass. Snapshots stay current without nightly rebuilds.
201
202UA-switching / cloaking-adjacent config
203
204Same bytes to humans and bots. The agent-readable layer lives in a preboot div + JSON-LD blocks — a real user never sees a different DOM than a crawler does.
205
206Framework migration to SSR
207
208Snippet drops into your existing nginx, Express server, or sidecar. Streaming-SSR shops drop in the framework SDK without rewriting. Your component tree, routing, and build pipeline are untouched.
209
210Maintaining your own LLM pipeline for content gen
211
212TL;DR extraction, FAQ refinement, schema detection — we run the LLM hops; you pay per render at our rate, not per token at theirs.
213
214Tracking schema.org standard drift
215
216Our generator updates; customer-shipped frozen JSON-LD decays silently. Install-stays-fresh is the live argument.
217
218An npm SDK / opaque library
219
220Snippet is plain CJS or Fetch-API, audit-able, lives in your codebase. Curl + drop.
221
222## What we deliberately don't do
223
224-   **No User-Agent switching.** If two visitors get different bytes for the same URL, that's cloaking. We don't. The snippet is UA-blind; bot identification is telemetry only.
225-   **No mailbox / mirror site.** AgentSite never becomes the public destination — your domain stays canonical.
226-   **No retry storms.** If our API errors, the middleware serves your unchanged HTML and moves on. Fail-open is non-negotiable.
227-   **No tracking pixels in the bundle.** The injected payload is meta tags, markdown, and standards-compliant schema.org JSON-LD. Nothing else.
228-   **No build-time pre-render CLI.** SPAs are runtime-rendered by design. A "build and walk every route" step is against the grain of why you shipped a SPA.
229-   **No LLM-brand promise.** We iterate on which model scores best for FAQ extraction and TL;DR generation; we won't name one in marketing because we'll swap it the moment a better one ships.
230
231[Pick your install pattern →](/getting-started)
232
233Cookies
234
235We use cookies to make this site work and to understand how it's used. [Learn more](https://www.cookiesandyou.com/)
236
237Decline Got it
238</pre>
239</div>
240
241<div id="app"></div>
242<script data-agentsite="webmcp">(function(){try{if(typeof navigator==="undefined"||!navigator.modelContext||typeof navigator.modelContext.registerTool!=="function")return;var R=navigator.modelContext.registerTool.bind(navigator.modelContext);R({name:"agentsite_site_info",description:"List the AgentSite-managed agent-readable resources for this site (llms.txt index, sitemap, per-page Markdown mirrors).",inputSchema:{type:"object",properties:{},additionalProperties:false},execute:async function(){return{site:"https://agentsite.app",llmsTxt:"https://agentsite.app/llms.txt",llmsFullTxt:"https://agentsite.app/llms-full.txt",sitemap:"https://agentsite.app/sitemap.xml",markdownMirrorHint:"Append .md to any page URL (e.g. /pricing.md) to fetch the Markdown body."};}});R({name:"agentsite_open_page",description:"Fetch the clean Markdown body of a page on this site by path (e.g. \"/pricing\"). Returns the same agent-readable rendering server-side agents see.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Page path, with or without leading slash (e.g. \"/pricing\" or \"pricing\")."}},required:["path"],additionalProperties:false},execute:async function(input){var p=String((input&&input.path)||"/");if(p.charAt(0)!=="/")p="/"+p;var u="https://agentsite.app"+p+".md";var r=await fetch(u,{headers:{accept:"text/markdown"}});if(!r.ok)return{error:"HTTP "+r.status,url:u};return{url:u,markdown:await r.text()};}});R({name:"agentsite_list_pages",description:"List every public page on this site with title and short description, parsed from llms.txt.",inputSchema:{type:"object",properties:{},additionalProperties:false},execute:async function(){var r=await fetch("https://agentsite.app/llms.txt");if(!r.ok)return{error:"HTTP "+r.status};var t=await r.text();var re=/^\s*-\s+\[([^\]]+)\]\(([^)]+)\)(?:\s*[:\u2014-]\s*(.+))?$/gm;var out=[],m;while((m=re.exec(t))!==null){out.push({title:m[1],url:m[2],description:(m[3]||"").trim()});}return{pages:out};}});}catch(_){}})();</script>
243</body>
244</html>
245
```

**Highlighted lines** are what AgentSite injected — same URL, same SPA, no code changes. The injection also unlocks `/features.md` — a clean Markdown twin at the same path, which is the shape AI engines actually quote.

You're spending hundreds to thousands a month on Claude and OpenAI tokens to make your product smart. Your landing page is invisible to the agents recommending tools.

569M

GPTBot fetches measured by Vercel. **Zero ran JavaScript.**

100/100

agentsite.app on Cloudflare's [isitagentready.com](https://isitagentready.com/agentsite.app). **Run the same check on yours.**

## Easy install. Optimized to not impact your performance.

Five minutes start to finish. Cold misses respond with your unmodified shell in milliseconds while we render in the background — humans never pay scan-and-generate latency, bots get the enriched response on the next fetch. Warm hits read the cached bundle.

### Sign up and get a token.

[Sign up](/auth/sign-up), pick a plan, register your domain. The kickoff allowance lets you try without a card.

### Tell Claude to set it up.

Paste this into Claude Code (or Cursor, Copilot, any coding agent). One prompt informs, instructs, and configures:

promptcopy

```
Set up agentsite on my server. My token is asit_xxxxxxxx. Read https://api.agentsite.app/llms.txt and follow the install instructions for an Express app serving a static SPA from `./dist`.
```

### Deploy and enjoy.™

Push your branch. The token usually needs to land in your CI/CD secrets or deploy environment (Claude will do this when it sets you up). The dashboard flips to live on the first agent fetch.

**Done.** Your SPA now serves real content to agents and share-card scrapers — in the same response real users get.

**No UA tricks. No bot routing.** Every visitor — human, GPTBot, ClaudeBot, Perplexity, share-card scraper — gets the same bytes.

Need more information? [Ask your agent if agentsite.app is cool.](https://claude.ai/new?q=Is%20agentsite.app%20cool%3F)

## Ways to get started, depending on your role.

Three doors into the same product — pick the one that matches who you are today.

[

Building it yourself?

Sign up and let an agent install it.

Get a token. Paste one line into Claude Code, Cursor, or Copilot. Pick the install pattern that matches your stack — Nginx, Express, Sidecar, Edge, or a streaming-SSR SDK — about five minutes start to finish.

Sign up →

](/auth/sign-up)[

Built it with Lovable, v0, or Bolt?

Your shipped SPA can still be agent-readable.

The AI tool generated a single-page app and called it done. We add the layer that makes ChatGPT, Claude, and Gemini able to read it — no rebuild, no second tool. Lovable's default Cloudflare deploy works out of the box via our Edge install.

Sign up →

](/auth/sign-up)

Running marketing or growth?

Run the report, bring it to your dev team.

Same scan, framed for hand-off. We'll show you exactly where to point them — or talk it through with the founder before you do.

[Run the report →](/score?audience=marketer)[Talk to the founder →](mailto:[email protected]?subject=agentsite%20chat)

## Common questions

**Do AI engines actually run JavaScript when they crawl?**

Overwhelmingly no. Vercel's analysis of half a billion GPTBot fetches found zero JavaScript execution. ChatGPT, Claude, Perplexity, Bing Chat, AI Overviews — they all read the raw HTML response. If your site is a SPA, all of them see `<div id="app"></div>` where your content was supposed to be.

**How is AgentSite different from AEO graders and mention-monitoring tools?**

Those tools diagnose. AgentSite diagnoses AND fixes — measures the same way they do, then installs the actual middleware that makes your content citable. The whole loop in one product.

**Why can't I just do this myself?**

You can. v1 is a weekend. What burns is the ongoing tail — bot UAs shift quarterly, `llms.txt` schema is still moving, attack-probes mutate, freshness scans need cluster-scheduling. Citation rates regress invisibly when any of it drifts, and you can't tell without scanning from outside. We treat that tail as the product — server-injected agent-readable markdown that LLMs read directly.

**Will this break my site?**

No. The snippet is fail-open — if our cloud is unreachable, it falls back to your unmodified `index.html`. No exception bubbles up to visitors. Removing the snippet is one line of code; everything goes back to before.

[Read the full FAQ →](/faq)

## Make your SPA legible to the agents that matter.

Free to try. Per-site tokens, usage in the dashboard, no UA tricks, no second deploy.

[Get your score — free](/score) [Sign up — free to start →](/auth/sign-up)

Free to start — kickoff allowance lets you try without a card. [See pricing →](/pricing)

Snippet stays in your deploy. Fail-open: if our cloud hiccups, you serve your unmodified `index.html`. Removing the snippet is one line.

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