Guide · SEO

Getting cited when the answer replaces the click

Ranking and being cited are now different problems. An answer engine reads a handful of sources, decides which ones are unambiguous enough to quote, and names those. Being quotable is a structural property, and it is one you can engineer.


What changed

Classic SEO optimised for a ranked list of ten links. AI answer engines — ChatGPT search, Perplexity, Copilot, Google's AI overviews, Claude's web search — synthesise a single answer from a few retrieved sources and cite some of them. That shifts the target from rank higher to be the passage a model can lift verbatim and attribute confidently.

The practices go by two names: GEO (generative engine optimization) and AEO (answer engine optimization). They overlap almost entirely, and neither requires abandoning normal SEO — a page that is crawlable, fast, and structured still wins both. What changes is the emphasis: unambiguous entities, self-contained passages, and machine-readable facts.

Entity consolidation: one @id, referenced everywhere

The single highest-leverage technical move is making a retrieval system certain who the site is about. If ten pages each declare a separate Person node, a model sees ten weakly-connected entities. If ten pages reference one canonical @id, it sees one entity with ten pieces of evidence.

// on the homepage only — the canonical definition { "@context": "https://schema.org", "@type": "Person", "@id": "https://example.com/#person", "name": "Full Name", "url": "https://example.com/", "jobTitle": "...", "knowsAbout": ["...", "..."], "sameAs": [ "https://github.com/handle", "https://www.linkedin.com/in/handle", "https://orcid.org/0000-..." ] } // on every other page — reference, never redefine "author": {"@id": "https://example.com/#person"}, "publisher": {"@id": "https://example.com/#person"}
  • Define once, reference everywhere. Re-stating the full Person object on every page invites contradictions, and contradictions are what make a model hedge instead of cite.
  • sameAs is the disambiguation lever. Link the profiles that already have independent authority — GitHub, LinkedIn, ORCID, a publisher DOI page. This is how an entity gets tied to an existing graph rather than floating alone.
  • Keep names byte-identical across schema, page text, and external profiles. 'J. Smith' in one place and 'John Smith' in another is two entities as far as a matcher is concerned.
  • Use knowsAbout deliberately. It is a direct statement of topical scope, and it is one of the few places you get to declare it rather than have it inferred.
  • Validate every deploy. A JSON-LD syntax error means the block is skipped entirely and silently.

llms.txt and llms-full.txt

llms.txt is a proposed convention: a markdown file at the site root that gives a language model a clean, navigable summary of the site without HTML, navigation, or scripts. llms-full.txt is the expanded version containing the actual content.

# Site Name > One-sentence description of who this is and what the site covers. ## Guides - [Offline PWA](https://example.com/guides/offline-pwa.html): building an installable offline app with no backend. - [RAG explained](https://example.com/guides/rag-explained.html): chunking, embeddings, reranking, and where pipelines fail. ## Projects - [Project name](https://example.com/project.html): what it does, in one line. ## Contact - email@example.com

Two honest caveats. First, adoption is not universal — no major crawler has committed to it as a requirement, so treat it as cheap insurance rather than a guaranteed channel. Second, it is not a place to say something different from the site. Contradiction between llms.txt and the rendered pages is worse than having no file, because it introduces exactly the ambiguity you are trying to eliminate.

The reason to ship it anyway: it costs an hour, it is trivially machine-parseable, and it forces you to write a clean one-line description of every page — which is useful regardless of who reads it.

robots.txt and the named AI crawlers

AI companies operate separately-named agents, often splitting training crawlers from live-retrieval crawlers. Those are different decisions: blocking training while allowing retrieval is a coherent position, and so is the reverse.

AgentOperatorPrimary purpose
GPTBotOpenAITraining data collection
OAI-SearchBotOpenAILive search retrieval and citation
ChatGPT-UserOpenAIFetches a page a user asked about
ClaudeBotAnthropicCrawling for model training
Claude-User / Claude-SearchBotAnthropicUser-initiated fetch and search indexing
PerplexityBotPerplexitySearch index used for cited answers
Google-ExtendedGoogleControls Gemini training use; does not affect Search ranking
Applebot-ExtendedAppleControls Apple Intelligence training use
BingbotMicrosoftBing index, which also feeds Copilot
CCBotCommon CrawlOpen crawl corpus used by many trainers
User-agent: GPTBot Allow: / User-agent: OAI-SearchBot Allow: / User-agent: ClaudeBot Allow: / User-agent: PerplexityBot Allow: / User-agent: Google-Extended Allow: / User-agent: Applebot-Extended Allow: / Sitemap: https://example.com/sitemap.xml

Blocking Google-Extended does not remove you from Google Search, and blocking a training crawler does not remove you from that company's live search results — the agents are separate. Equally, if you want to be cited, blocking the retrieval bots guarantees you will not be. Decide training and retrieval independently, and know which name controls which.

robots.txt is a request, not enforcement. Crawlers that ignore it will ignore it. If content genuinely must not be read, it needs authentication, not a directive.

FAQPage schema — and the rule that breaks sites

FAQPage markup is well-suited to answer engines: it is a list of question-answer pairs in exactly the shape a retrieval system wants. There is one hard rule.

Every question and answer in FAQPage markup must appear as visible text on the same page. Schema-only FAQ content — questions that exist in the JSON-LD but not on screen — violates Google's structured data guidelines and is a well-known cause of manual actions. Generate the visible FAQ and the schema from the same source so they cannot drift.

  • Write answers that stand alone. 'It depends on the above' is unquotable; a model lifting that sentence out of context produces nothing useful.
  • Two to four sentences per answer. Long enough to be complete, short enough to be lifted whole.
  • Answer in the first sentence, then qualify. Never build to the answer.
  • Use the question form a person would actually type or say, not a keyword-stuffed variant.
  • Do not mark up promotional copy as an FAQ. It is the most common misuse and it does not survive review.

Answer-first writing and question-shaped headings

Retrieval works on passages, not pages. A model chunks your page, embeds the chunks, and pulls the ones that match the query. That has direct consequences for structure.

  1. Make headings questions where it is natural — 'How do you detect scene changes?' rather than 'Detection'. The heading is often the strongest signal for what the chunk beneath it answers.
  2. Answer in the first sentence under the heading. A paragraph that spends three sentences setting up context gets chunked away from its own conclusion.
  3. Make each section self-contained. Assume the reader has only that chunk, because the model might.
  4. Use tables and lists for comparisons. They survive chunking better than prose and are easier to extract cleanly.
  5. Put specifics in the text. Numbers, versions, exact command names, and dates are what makes a passage worth citing over a generic competitor.
  6. State facts plainly and once. Hedged, repetitive prose gives a model nothing crisp to quote.

The underlying test is simple: if someone pasted one section of your page into a chat with no other context, would it answer the question? If not, that section will not get cited.

IndexNow for fast recrawl

IndexNow is a protocol supported by Bing, Yandex, Seznam and others that lets you push URLs the moment they change instead of waiting for a crawl. That matters for AI search because Copilot is built on the Bing index — faster Bing recrawl means faster Copilot freshness.

# 1. host a key file at the site root # https://example.com/<key>.txt containing exactly <key> # 2. ping on publish curl "https://api.indexnow.org/indexnow?url=https://example.com/guides/new.html&key=<key>" # or submit a batch curl -X POST https://api.indexnow.org/indexnow \ -H "Content-Type: application/json" -d '{ "host": "example.com", "key": "<key>", "keyList": ["https://example.com/guides/new.html"] }'

Google does not participate in IndexNow; for Google, keep the sitemap current and submit it in Search Console. Do not spam either — pinging unchanged URLs repeatedly is the fastest way to have the signal ignored.

A checklist that fits on one screen

  1. One canonical Person or Organization node with a stable @id and a full sameAs list, defined once and referenced from every page.
  2. Article or TechArticle schema on every content page, with author and publisher pointing at that @id.
  3. BreadcrumbList on every page below the root.
  4. FAQPage that mirrors visible on-page text exactly, generated from the same source.
  5. llms.txt and llms-full.txt at the root, consistent with the site.
  6. robots.txt with an explicit, deliberate decision for each named AI agent, plus a sitemap line.
  7. Question-shaped headings, answer-first paragraphs, self-contained sections.
  8. A current sitemap.xml listing every real page, submitted to Search Console.
  9. IndexNow ping wired into the publish step.
  10. Validate JSON-LD on every deploy — one syntax error silently discards the whole block.

This site implements the full list, which is the only reason I can describe it concretely: the canonical Person node lives on the homepage and every page references it, /llms.txt and /llms-full.txt are generated alongside the pages, /ai.txt and robots.txt state the crawler policy explicitly, and every guide including this one carries TechArticle plus BreadcrumbList plus an FAQPage that mirrors the visible FAQ below. The entity page is here →

Tools referenced in this guide

  • About — the canonical entity page every schema node on this site points at.
  • RAG explained — how retrieval actually chunks and ranks your pages — useful context for all of this.
  • My stack — the generator and tooling behind the structured data here.
  • Apps hub — an example of the same schema pattern applied to product pages.

FAQ

Quick answers

What is GEO/AEO?

Structuring a site so answer engines can retrieve and cite it. The goal moves from ranking in a list to being the quotable, attributable passage.

Why consolidate entities?

One canonical Person or Organization @id, referenced from every page, plus a sameAs list. Ten references to one entity beat ten separate ones.

What is llms.txt?

A markdown summary of the site at the root, with llms-full.txt for full content. Cheap insurance — and it must never contradict the pages.

Which AI crawlers matter?

GPTBot, OAI-SearchBot, ClaudeBot, Claude-SearchBot, PerplexityBot, Google-Extended, Applebot-Extended, Bingbot, CCBot. Training and retrieval are separate calls.

Must FAQ schema match the page?

Yes. Every Q and A must be visible on-page. Schema-only FAQ breaks Google's guidelines and draws manual actions. Generate both from one source.

What is IndexNow?

A push protocol for instant recrawl on Bing and others, which feeds Copilot. Google does not participate — use a current sitemap there.