llms.txt is the emerging standard for AI-readable websites. Learn what it is, why it matters for GEO, and how to generate one automatically at build time.
You have a robots.txt for Google. You need an llms.txt for the AI.
llms.txt is a plain-text file at your site root that gives generative engines a curated map of your content — what each page is, what it answers, and where to find it. It is to AI crawlers what sitemap.xml is to search engines: a hint, not a guarantee, but a strong one.
The format is markdown:
# Project Name
> Short description of the project.
## Docs
- [Getting Started](https://example.com/start): Setup guide
- [API Reference](https://example.com/api): Endpoint docs
## Changelog
- [v1.0.0](https://example.com/changelog#v1): Initial release
Generative engines do not crawl every link. They prioritize sources that are easy to ingest and clearly structured. llms.txt does three things:
Without it, the model falls back to whatever it can scrape — often your terms of service or a stale blog post.
| File | Audience | Purpose |
|---|---|---|
robots.txt | Search crawlers | Allow/deny crawling |
sitemap.xml | Search engines | List all URLs + priority |
llms.txt | Generative engines | Curated, described content map |
They complement each other. You want all three.
Hand-maintaining llms.txt drifts. Generate it from the same source of truth as your sitemap — your route config.
In SpaceZero, llms.txt and llms-full.txt are generated by the llmsTxtPlugin in vite.config.ts from SITEMAP_ROUTES and CHANGELOG_ENTRIES:
// vite.config.ts — runs on every build
const llmsTxt = `# ${appName}
${appDescription}
## Documentation
${SITEMAP_ROUTES.map((r) => `- [${r.path}](${appUrl}${r.path})`).join('\n')}
## Changelog
${CHANGELOG_ENTRIES.map((e) => `- [${e.version}](${e.url}) - ${e.title}`).join('\n')}
`;
Because it is generated from the same config that builds your sitemap and RSS, it can never drift out of sync.
| File | Length | Purpose |
|---|---|---|
llms.txt | Short | Concise map for quick ingestion |
llms-full.txt | Long | Full documentation for deep context |
Ship both. The short file gets cited; the long file gets read.
The rule: if a page would not help an AI answer a user's question, it does not belong in llms.txt.
llms.txt is cheap to generate, impossible to maintain by hand at scale, and increasingly the difference between being cited and being invisible. If your build does not emit one, add it this week.