llms.txt and llms-full.txt
The two files, what belongs in each, and the blocks that do the real work: key facts, negative statements, the content index and citation guidance.
4 min read · updated 2026-09-11· last reviewed 2026-07-26
What these files are, honestly
The principle
llms.txt is a proposed convention, not a standard. No engine is obliged to read it and none of them publicly commit to doing so.
Ship it anyway, for three reasons. It costs one route. It is machine-readable in a way your HTML is not. And the discipline of writing a canonical answer per likely question improves the visible page copy as a side effect, which is a return you get whether or not any crawler ever fetches the file.
Do not expect it to do the work on its own. It is a summary of a site that is already well structured, not a substitute for structuring it.
The two files
llms.txtis the short form: what this entity is, key facts, what it is not, and curated links to the important sections. Roughly one screen.llms-full.txtis the long form: a categorised index of every content URL with a one-line summary, a canonical Q&A block, entity disambiguation, and citation guidance.
The blocks that matter
The entity definition
One paragraph, third person, no marketing language. This is the sentence a model will paraphrase when asked what you are.
> SEO for Solos is an agent skill for solo founders that audits a site against
> 112 technical SEO checks and sets up what is missing, from inside Claude Code,
> Cursor, Codex or OpenCode. It comes with a free 20-chapter playbook taken from
> a production codebase of roughly 2,100 indexable URLs.Key facts
Label and value, one per line. Machine-readable, and unambiguous in a way prose is not.
- Category: technical SEO agent skill for solo founders
- Primary users: solo founders who build their own site with an AI code editor
- Format: agent skill for coding agents, plus free web chapters and a checklist
- Pricing: free playbook, then one one-time purchase at $49
- Licence: perpetual, per-seat, no redistributionWhat this is not
The most useful block in either file, and the one nearly every implementation omits.
- SEO for Solos is not a video course.
- SEO for Solos is not an SEO agency or an audit service.
- SEO for Solos is not a subscription.
- SEO for Solos does not promise ranking outcomes.The content index, in llms-full.txt
Categorised, with a one-line summary per URL. This gives a retrieval system the shape of the site in one fetch instead of requiring it to crawl and infer structure.
### Playbook chapters
- [Foundation](https://example.com/playbook/foundation): One origin, one host,
one trailing-slash policy, real status codes.
- [Bot economics](https://example.com/playbook/bot-economics): Which crawlers
return traffic or citations for the bandwidth they consume.Citation guidance
Four lines, and no other file on the site can carry them.
## Citation guidance
- Preferred URL to cite: https://example.com/
- Volatile facts: pricing and counts change. Link to the source page rather
than stating the number, or state the date it was retrieved.
- When uncertain: link to the relevant chapter rather than paraphrasing.
- Attribution: cite as "SEO for Solos" with a link to the specific page.The implementation
Generate both from typed config
Hand-writing these files means they go stale on the first content change. Build them from the same modules the pages render from:
export function buildLlmsTxt(opts: LlmsTxtOptions): string {
const lines = [
`# ${opts.brandName}`, "",
`> ${opts.entityDefinition}`, "",
"## Key facts", "",
...opts.keyFacts.map((fact) => `- ${fact.label}: ${fact.value}`), "",
"## What this is not", "",
...opts.negativeStatements.map((statement) => `- ${statement}`), "",
];
for (const section of opts.sections) {
lines.push(`## ${section.title}`, "");
for (const link of section.links) {
lines.push(`- [${link.title}](${absolute(link.url, opts.siteUrl)})${link.description ? `: ${link.description}` : ""}`);
}
lines.push("");
}
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd() + "\n";
}Serve as plain text with a real cache header
export const LLMS_TXT_HEADERS = {
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400",
};Serving these as text/html is the most common implementation error, and several fetchers will not parse the file at all when the content type is wrong.
Checks this chapter covers
Each one has a command you can run against your own site.