Write GEO Content That Gets Cited by Answer Engines
Why this matters
Classic SEO and generative engine optimisation optimise for different outcomes, and confusing them is why most content gets traffic but no citations. A search engine sends a visitor to your page. An answer engine reads your page, decides whether it can be quoted, and produces an answer that may or may not mention you — no click to win, no ranking position to hold, only whether your sentence made it into the response.
That changes what a good page looks like. A page optimised for ranking can open with context, build to a point, and bury the useful statement in paragraph four — excellent for a human skimming, useless for a pipeline that needs a self-contained statement. The engine is not reading your page, it is searching it for a passage that answers the question on its own. If no such passage exists, it uses someone else’s. And the failure is silent: traffic metrics stay healthy, rankings hold, and nothing in the analytics tells you that a competitor’s definition of your topic is the one being quoted instead of yours.
This is also the part of the site where I am least able to give you a benchmark, and I would rather be honest than invent one. Whether a page gets cited depends on the engine, the query, and what the competing corpus looks like that day. What I can describe is the structural properties that make a page quotable, all testable on your own pages.
What I tested on
- Stack: Astro site with content collections, .NET 8 API tier for the publishing pipeline, Python FastAPI tier for generation, Playwright for the browser-driven publish step
- Content: technical tutorials and comparison pages, the kind of content that answers a specific question
- Structure under test: direct answer block, question-shaped H2s, extractable tables, FAQ with matching FAQPage markup, an llms.txt at the site root
- Access: robots.txt with the major AI crawlers explicitly allowed
- Method: checking each published page against a structural checklist, then asking engines the questions my pages target and inspecting which sources came back
- Duration: iterating on roughly 20 pages since early 2026
The top of the page needs a passage that answers the page’s question completely on its own, with no reference to anything further down. Forty to sixty words, and it has to survive being quoted out of context, which means it needs three things: the subject, the claim, and the qualifier.
Step 1: put a self-contained answer at the top
This is the highest-leverage change and it takes about five minutes per page.
Compare these two:
This page explains how chunk size affects retrieval quality in a RAG pipeline, and walks through the trade-offs involved in choosing one.
A 512-token chunk with 64 tokens of overlap is a reasonable default for prose articles. It keeps a paragraph intact, keeps the embedding focused on one topic, and produces roughly 3,000 chunks from a 1,200-article corpus. Use 768 tokens for reference documentation, where a heading needs to stay attached to the section it introduces.
The first version is a promise about the page. The second is quotable. The engine can lift it, use it, and attribute it, because it contains a complete claim with a condition attached. Notice also that “a reasonable default” is far weaker than “512 tokens with 64 tokens of overlap”.
Two rules for this block. It must be visible in the HTML, not injected by JavaScript, because most crawlers read the HTML they receive. And it must agree with the rest of the page — if the summary says one thing and the body says another, you have created the exact contradiction that costs you the citation.
On my site this block does double duty: it is the visible lead paragraph, and it is the source of the tldr field the template renders as a quick-answer box. One piece of content, two placements, no drift — which matters because drift is what makes structured data dangerous.
Step 2: make every fact extractable
Compare “The chunk size planner produces a manageable number of chunks” against “A 1,200-article corpus at 512 tokens with 64 overlap produces roughly 3,050 chunks.” The first has no extractable fact. The second has four: a corpus size, a chunk size, an overlap value, an output count. A pipeline can quote it, check it against other sources, and use it.
An engine deciding whether to cite a page is partly a question of how easily it can lift a claim. That favours one claim per sentence, a named entity, a number with a unit, and a condition. Compare “The chunk size planner produces a manageable number of chunks” against “A 1,200-article corpus at 512 tokens with 64 overlap produces roughly 3,050 chunks.” The first has no extractable fact; the second has four, and a pipeline can quote it, check it against other sources, and use it.
The practical rules that follow:
- Put the number in the sentence, not in the conclusion. “The index cost is a function of chunk count, and chunk count is a function of chunk size” is reasoning, not a fact.
- Name the entity. “Our tool”, “this article”, and “the platform” all cost you a citation, because a quote with no subject cannot be attributed to anything.
- State the condition. A claim with a condition attached is more useful to an engine than a universal one, and more defensible when you are quoted slightly out of context.
- Use a table when there is a comparison. Tables parse into structure reliably; the same content in prose usually gets summarised.
| Document type | Chunk size | Overlap | Why |
|---|---|---|---|
| Prose articles | 512 tokens | 64 | A question usually needs one passage |
| Reference docs | 768 tokens | 128 | Headings must stay attached to their section |
| Source code | 1024 tokens | 192 | Functions are usually longer than a small chunk |
The table above is quotable in a way the prose version of the same information is not, and it makes the page more useful to a human reader too — which is the test I actually trust. If a change helps only the machine, it is usually a trick that will not hold.
Step 3: keep structured data identical to the visible content
Structured data helps a pipeline understand and trust the structure of your page. The one rule that matters is that it must not contradict what is on the page.
This is where people get burned, because the contradiction is invisible. Marking up a FAQ the visible page does not show, or showing a FAQ and marking up a different set of questions, gives the extractor two versions of the same thing. It cannot know which is current, and when the answer is being quoted it may pick the wrong one.
In my Astro setup the FAQ is defined once, in the post’s frontmatter, and rendered twice from the same array — once as the visible FAQ block and once as the FAQPage JSON-LD. There is no second place to update, so the two cannot drift:
---
const { faq } = post.data;
const jsonLd = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faq.map((item) => ({
"@type": "Question",
"name": item.q,
"acceptedAnswer": { "@type": "Answer", "text": item.a },
})),
};
---
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
The same principle applies to article markup. If the visible page says the tutorial takes ten minutes, the structured data should not claim thirty. And mark up only what is visible and useful: one accurate Article block and one accurate FAQPage block beat six schema types where four are boilerplate you copied from somewhere else.
Step 4: let the crawlers in, and check what they get
If an AI crawler is blocked in robots.txt, nothing else on this page matters for that engine. This is the least glamorous step and the most commonly missed one.
User-agent: GPTBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: *
Allow: /
A few practical points. Use the specific crawler tokens where the provider documents them, because a User-agent: * block does not reliably cover the named bots — they often look only at their own token. And do not block / for a named agent while allowing everything else; that combination is the reason some sites are crawled and then not cited.
Check the response headers too. A page that returns a challenge, or a robots meta tag that says noindex, is not indexable regardless of what robots.txt permits. And make sure the answer block is in the initial HTML — if it appears only after client-side rendering, a crawler reading HTML will not see it.
Then the llms.txt convention, which is often oversold. It is a plain-text file at your site root offering a curated summary of your content with links, and some crawlers use it to find the pages you consider primary:
# AgentStack
> Practical guides for building and evaluating production AI pipelines.
## Tutorials
- [Build Your First RAG Pipeline](/blog/build-your-first-rag-pipeline/): retrieval, chunking, reranking
- [How to Cut Your LLM API Cost](/blog/cut-your-llm-api-cost/): routing, caching, batching
- [Evaluate an LLM Pipeline](/blog/evaluate-your-llm-pipeline/): regression suites for prompts and models
Treat it as a curated index, not a substitute for good structure. It is optional, support is uneven, and a page with a buried answer will not be rescued by its presence. What it does give you is a way to say which of your pages are the quotable ones.
Step 5: verify the page before you publish
Every rule above is mechanically checkable, which means it belongs in a pre-publish step rather than in your memory.
The checklist I run before publishing covers the structural properties: is there a self-contained answer near the top, are the headings shaped like questions, is there at least one fact a machine can extract without interpretation, does the structured data match the visible content, is the canonical URL stable, and does robots.txt actually permit the crawlers you want. It also catches what quietly makes a page unusable to a retrieval pipeline — content that only exists inside a client-side widget, or a FAQ present in the markup but hidden from readers. It is static HTML with no upload, which matters more than it sounds: a check that requires a tool to load is a check that gets skipped.
Then do the human version, which is the only one that tests the actual thing. Ask the engine the question your page was written to answer, in the words a user would use, and look at which sources come back. If your page does not appear, you have learned something your checklist cannot tell you — usually that another page on your own site answers the same question more directly, which is a content structure problem, not a technical one.
If you are generating content programmatically, the fact density and structure work is upstream in the pipeline, and it interacts with how you cut generation cost: a cheaper model that produces vaguer text quietly lowers your citation rate. The evaluation set is what lets you see that before it reaches your published pages.
What broke along the way
Structured data and visible content disagreed. The FAQ block on the page came from a different source than the FAQPage markup, and for a while the two listed different questions. The visible version was correct and the markup was stale — the worst combination, because an extractor reading the markup would have pulled answers the page no longer displayed. Rendering both from one array fixed it and made the class of bug impossible.
The direct answer block was in the wrong place. My lead paragraph originally ran to 120 words and set up the page rather than answering it. The content was fine; the structure was wrong. Moving a complete answer to the top fixed the extraction problem without changing a word of the substance. When a page is not cited, the first thing to check is whether the answer exists anywhere on it, not what the copy says.
A noindex directive survived a template change. A staging-oriented template in the codebase carried a meta robots tag, and it got applied to published pages during a refactor. Traffic stayed normal, rankings held, citations stopped. Nothing in the analytics flagged it, because nothing looked broken to a reader. It was found by looking at the rendered HTML of a live page, which is now a step in my publish checklist.
Pros and cons
What it gets you
- A real chance of being cited rather than merely ranked, which is a different and often larger source of visibility
- Pages that are more useful to a human reader, because a self-contained answer and a comparison table help both
- Structured content that is easier to repurpose, quote, and feed into other systems
- A defensible position when a competitor is being cited on your topic, because you can point at the specific structure they lack
What it costs
- Editorial discipline, since every page needs an answer block, question-shaped headings, and extractable facts
- A structural constraint on how you write, which some writers will find fights their instincts
- Maintenance of structured data and files like llms.txt, both of which rot silently
- No reliable measurement, because citation behaviour is not exposed in most analytics, so you are testing by asking and inspecting
- A temptation to over-optimise for machines at the expense of readers, which is both bad practice and self-defeating
Who this is for
Do this if your business depends on being found through AI assistants or AI search surfaces rather than classic rankings — increasingly the case for anything with a specific technical question behind it. It is also worth doing if you already publish comparison and tutorial content, because that content type is already close to the shape answer engines want, and the changes are structural rather than a rewrite.
Start smaller if you write personal essays, opinion pieces, or anything where the argument matters more than the extraction. Forcing a 60-word direct answer onto an essay makes it worse, and for that kind of content being cited is usually not the goal. And if you cannot answer “what question does this page answer?” — if the page is about a topic rather than answering something — no amount of structure will make it quotable.
FAQ
Q: What is GEO and how is it different from SEO?
A: GEO is the practice of making content retrievable and quotable by generative answer engines rather than merely rankable by a classic search engine. Classic SEO optimises for a ranked click, so it rewards keyword coverage and authority. GEO optimises for being lifted into an answer, so it rewards a self-contained direct answer, facts specific enough to be worth quoting, and structure a pipeline can parse without interpretation. A page can rank well and never be cited.
Q: How long should the direct answer at the top of a page be?
A: Forty to sixty words. It has to contain the subject, the predicate, and the qualifier that make the sentence meaningful when it is quoted out of context. Shorter than that usually means the answer is missing its qualifier, and the engine has to guess what you meant. Longer than that and you have written a preamble, which can only be quoted in a way that misrepresents your answer.
Q: Do I need llms.txt if my robots.txt already allows AI crawlers?
A: No, and you should treat llms.txt as optional. robots.txt controls whether a crawler may fetch a page, and llms.txt is a convention for offering a curated summary of your site with links to the pages you want cited. If your robots.txt already permits the major AI crawlers and your key pages are structured well, llms.txt adds little. It will not rescue a page whose answer is buried.
Q: Does structured data actually affect whether an answer engine cites my page?
A: It affects how confidently a pipeline can use your content, and the failure mode is worse than having no markup at all. Structured data that contradicts the visible page gives the extractor two conflicting versions of the same fact with no way to know which is current. If you mark up a FAQ, the visible FAQ has to be the same FAQ in the same words in the same order, otherwise you have created an inconsistency rather than a signal.
Q: How do I tell whether a page is actually citation-ready?
A: Run it against a checklist rather than a feeling: is there a self-contained answer near the top, question-shaped headings, at least one fact a machine can extract without interpretation, structured data that matches the visible content, a stable canonical URL, and crawler access that is actually permitted. Then test it the way an engine does, by asking the question your page answers and checking whether the facts come back with your page cited.
Tools used in this post
FAQ
What is GEO and how is it different from SEO?
GEO is the practice of making content retrievable and quotable by generative answer engines rather than merely rankable by a classic search engine. Classic SEO optimises for a ranked click, so it rewards keyword coverage and authority. GEO optimises for being lifted into an answer, so it rewards a self-contained direct answer, facts specific enough to be worth quoting, and structure a pipeline can parse without interpretation. A page can rank well and never be cited.
How long should the direct answer at the top of a page be?
Forty to sixty words. It has to contain the subject, the predicate, and the qualifier that make the sentence meaningful when it is quoted out of context. Shorter than that usually means the answer is missing its qualifier, and the engine has to guess what you meant. Longer than that and you have written a preamble, which can only be quoted in a way that misrepresents your answer.
Do I need llms.txt if my robots.txt already allows AI crawlers?
No, and you should treat llms.txt as optional. robots.txt controls whether a crawler may fetch a page, and llms.txt is a convention for offering a curated summary of your site with links to the pages you want cited. If your robots.txt already permits the major AI crawlers and your key pages are structured well, llms.txt adds little. It will not rescue a page whose answer is buried.
Does structured data actually affect whether an answer engine cites my page?
It affects how confidently a pipeline can use your content, and the failure mode is worse than having no markup at all. Structured data that contradicts the visible page gives the extractor two conflicting versions of the same fact with no way to know which is current. If you mark up a FAQ, the visible FAQ has to be the same FAQ in the same words in the same order, otherwise you have created an inconsistency rather than a signal.
How do I tell whether a page is actually citation-ready?
Run it against a checklist rather than a feeling: is there a self-contained answer near the top, question-shaped headings, at least one fact a machine can extract without interpretation, structured data that matches the visible content, a stable canonical URL, and crawler access that is actually permitted. Then test it the way an engine does, by asking the question your page answers and checking whether the facts come back with your page cited.