Guide
How This Site Is Built to Get Cited by ChatGPT, Claude & Perplexity — The Full Teardown
Most advice on getting cited by AI is vibes. This is not that. This page is a teardown of the actual machinery this site runs — the same stack I ship on every build — that makes it legible to Google's crawler and to the AI assistants people now ask before they open a search box.
Everything below is true of the page you are reading right now. View the source, open the .md twin, read the robots.txt. These are receipts, not a checklist I copied from somewhere.
The problem: an assistant can't cite what it can't parse
When someone asks ChatGPT, Claude, or Perplexity "who does X well," the model answers from what it can read and trust. A site built as a pile of JavaScript-rendered <div>s, with no structured data and no clear author, gives it almost nothing: no named entity, no machine-readable summary, no signal about who published the page. So the model reaches for a competitor it can read.
The fix is not a plugin. It is a handful of deliberate, boring layers that each make the same content easier for a machine to parse, attribute, and quote. Here they are, in the order they matter.
Layer 1 — llms.txt and llms-full.txt
At the root of the domain I serve two plain-text files. llms.txt is a curated Markdown index of the site — a map that points an assistant at the cleanest version of every important page. llms-full.txt is the same pages concatenated into one file, so a model can ingest everything in a single request. The top of this site's index reads:
# sukisong.com — LLM index
Suki Song builds AI-discoverable websites — found by Google and cited by ChatGPT, Claude, and Perplexity (SEO + GEO as one system).
…
## Machine-readable pages
…
- [About](https://sukisong.com/about.md): A builder, a writer, a solo traveler. Currently thinking about how engineering teams ship at AI pace.Both files are generated at build time from the same content modules that render the visual pages, so they can never fall out of sync with what a human sees. If you want the format itself in detail — and an honest read on whether it does anything yet — I wrote a standalone explainer on llms.txt.
Layer 2 — a Markdown twin of every page
Every content page here has a plain-Markdown twin at the same path with a .md extension. This page's twin lives at /guides/how-this-site-gets-cited-by-ai.md. It is the exact same content as clean prose — no nav, no scripts, no layout noise — which is the version a model can lift and quote verbatim.
And each page's <head> points a crawler straight to its twin with a rel=alternate link:
<link rel="alternate" type="text/markdown"
href="https://sukisong.com/guides/how-this-site-gets-cited-by-ai.md" />The twin is generated from the page's structured content, not scraped back out of the rendered HTML, so the human page and the machine page are one source and cannot drift. That "one source" property is the whole game — it is what lets me promise the AI reads the same facts the buyer does.
Layer 3 — a resolvable @id graph (Schema.org)
Structured data is where most sites either do nothing or do it wrong. I ship a small, connected graph of three named entities, each with a stable @id that other nodes reference instead of re-describing:
{ "@type": "WebSite", "@id": "https://sukisong.com/#website",
"publisher": { "@id": "https://sukisong.com/#person" } }
{ "@type": "Person", "@id": "https://sukisong.com/#person",
"name": "Suki Song" }
{ "@type": "ProfessionalService", "@id": "https://sukisong.com/#org",
"founder": { "@id": "https://sukisong.com/#person" } }The @id values are the load-bearing part. Because the Person has one canonical identifier, every other node — the WebSite that publishes it, the studio it founded, an Article and its author — can point at the same entity rather than inventing a new one. A machine reading the graph learns that one person publishes this site, runs this studio, and wrote this article. That is what "named-entity markup" actually means.
And every page carries these nodes itself. A page-specific graph spreads the sitewide Person / WebSite / Org into its own @graph, so if a crawler only ever sees one page, none of the @id references dangle — the entity still resolves. Most sites that bother with schema define it once on the homepage and leave every other page pointing at nothing.
Layer 4 — an explicit AI-crawler allowlist
You can ship all of the above and still get nothing if your robots.txt quietly blocks the crawlers that feed the assistants. Plenty of sites do, by accident, on a default config. Mine names them and lets them in:
User-agent: GPTBot
User-agent: OAI-SearchBot
User-agent: ChatGPT-User
User-agent: ClaudeBot
User-agent: Claude-Web
User-agent: anthropic-ai
User-agent: PerplexityBot
User-agent: Perplexity-User
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: CCBot
Allow: /That is the allowlist for OpenAI's, Anthropic's, Perplexity's, Google's, and Apple's AI crawlers, plus Common Crawl — which a lot of retrieval and training pipelines draw from. Allowing them is a deliberate choice: you are opting into being read and cited. For a business that wants to be found, that is exactly the point, so I opt in on purpose and document it.
Layer 5 — semantic HTML and a real sitemap
Underneath the AI-specific layers is the unglamorous foundation: one <h1> per page, real headings in order, semantic landmarks (<main>, <article>, <nav>), a rel=canonical link on every page so duplicates collapse to one URL, and a generated sitemap that weights the pages that matter over the legal boilerplate. None of this is exotic. It is the stuff that is supposed to be there and usually is not — and it is the same foundation that decides whether you show up in plain Google search at all.
Why this is one system, not five plugins
SEO gets you ranked when someone searches Google. GEO — generative engine optimization, also called AEO (answer-engine optimization) — gets you cited when someone asks an assistant. They are not the same thing, but they share a spine: clean, structured, crawlable content with a clear entity behind it. Build the spine once and you serve both. Bolt one on after the other and you pay twice for half a result.
If your site is not showing up at all yet, the AI layer is premature — start with why your website doesn't show up on Google and get the indexing basics right first. Then this stack is what makes you citable once you're found — the readability and entity layer an assistant needs before it can quote you.
I ship every layer above on every site I build. If you already have a site you like, the same layers go on without a redesign — that is Get Found, from $3,000.
Frequently asked
Can you actually make ChatGPT or Claude cite my site?
I can build the layers that make your site readable, trustworthy, and easy to attribute — llms.txt, Markdown twins, a resolvable entity graph, crawler access. No one can guarantee that a specific model quotes you on a specific day; the models change constantly and it is not pay-to-play. What I can promise is that your site stops being invisible to them. Most sites give an assistant nothing to work with. Yours will not be one of them.
Isn’t llms.txt unofficial? Does it really do anything?
It is a proposed convention, not a ratified standard, and no major assistant has publicly committed to reading it. I ship it because it is cheap, honest, and a clean machine-readable index that costs nothing to maintain when it is generated from the same source as the page. The heavier lifting is done by the twins, the structured-data graph, and the crawler permissions. The llms.txt explainer has the full nuance.
Do I have to rebuild my whole site to get this?
No. Every layer here can be added to an existing site without touching the design — that is exactly what the Get Found engagement is. On platforms that will not let you serve files like llms.txt (Framer, some Squarespace setups), I route them through a small Cloudflare Worker so the site keeps its look and gains the discoverability layer.
Will any of this slow my site down?
No. The twins and llms.txt are static files generated at build time. The structured data is a few kilobytes of JSON in the head. If anything, doing this properly tends to come with the performance and semantics cleanup that helps human visitors and search ranking too.