How to Add llms.txt to Your Site (Astro, Next.js, WordPress)

llms.txt is a plain Markdown file served at your domain root that gives AI systems a curated index of your site: what it is, which pages matter, and how to interpret them. ChatGPT, Claude, and Perplexity all parse it when present. Deployment takes ten minutes on any stack; this guide covers the format once, then the exact steps for Astro, Next.js, and WordPress.

The format (90 seconds)

A valid llms.txt needs exactly three structural elements, in this order:

# Your Site Name

> One sentence describing what the site is and who it serves.

https://yourdomain.com/

## Main Sections
- [Page Title](https://yourdomain.com/page): one-line description of the page
- [Another Page](https://yourdomain.com/another): what an AI should know it covers

## Docs
- [Getting Started](https://yourdomain.com/docs/start): installation and first run
  • The # H1 site name must be the first content line.
  • The > blockquote is your one-sentence elevator description — models quote it.
  • Sections (##) group - [Title](URL): description entries. Absolute https URLs only.
  • List pages you'd want an AI to cite — not every URL. Quality beats coverage; ~10-150 entries is the useful range.

Don't hand-roll it if you have a sitemap: the free generator builds a spec-valid file from your own sitemap, so every URL is verified to exist.

How do I add llms.txt in Astro?

Astro serves anything in public/ verbatim from the site root. Create public/llms.txt, paste your content, deploy. That's the whole implementation:

your-project/
├── public/
│   ├── llms.txt        ← here
│   └── robots.txt
└── src/…

Astro won't process or rename it; it ships byte-for-byte at /llms.txt with a sensible text/plain content type. If you generate pages from a content collection, you can also render it dynamically with an endpoint at src/pages/llms.txt.ts that walks your collection and returns the Markdown — useful when your page list changes weekly.

How do I add llms.txt in Next.js?

Static (App or Pages router): identical idea — drop the file in public/llms.txt. Next serves public/ from the root.

Dynamic (App router): create a route handler so the file always reflects current content:

// app/llms.txt/route.ts
export async function GET() {
  const body = [
    '# Acme',
    '',
    '> Acme makes billing infrastructure for veterinary clinics.',
    '',
    'https://acme.com/',
    '',
    '## Product',
    '- [Pricing](https://acme.com/pricing): plans and per-seat pricing',
    // …generate entries from your CMS or route manifest
  ].join('\n');
  return new Response(body, {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
}

Avoid middleware rewrites that might intercept /llms.txt — check it returns 200 in production, not your SPA shell.

How do I add llms.txt in WordPress?

Three options, best first:

  1. Upload to the web root. Via SFTP or your host's file manager, place llms.txt next to wp-config.php. Survives theme changes; bypasses WordPress entirely.
  2. Plugin. Several maintained plugins (search the directory for "llms.txt") generate the file from your published pages and keep it updated on publish — the right choice if you don't have file access.
  3. functions.php rewrite for the comfortable: register a rewrite for llms.txt and emit the Markdown from a template. More moving parts; only worth it for heavily dynamic sites.

Watch for caching/security plugins and CDN rules that block unknown root files — after deploying, fetch https://yoursite.com/llms.txt from an incognito window and confirm a 200 with your content.

The four mistakes that suppress citations

  1. Wrong location. It must be at the root. /about/llms.txt doesn't exist to anyone.
  2. Listing dead or noindexed URLs. Models treat inconsistency between llms.txt, sitemap, and live pages as unreliability. Our audit cross-checks every entry against your sitemap for exactly this reason.
  3. Serving HTML. A 404 page returning 200, or a pretty "viewer" — content-type must be plain text/Markdown.
  4. Set-and-forget. A file describing your 2024 site map misleads about your 2026 one. Regenerate when your information architecture changes (the $49/mo re-audit alerts on drift).

Validate, then verify live

Paste your file into the validator (11 spec checks, instant), deploy, then run the full audit — it fetches the live file, scores structure, and verifies every URL against your sitemap. Green on checks 07 and 08 means the index layer of your GEO stack is done.

Frequently asked questions

Where exactly must llms.txt live?

At the domain root: https://yourdomain.com/llms.txt. Subdirectory placements (e.g. /docs/llms.txt) are not where AI systems look. Subdomains are treated as separate sites and get their own file.

Do I need llms-full.txt too?

Optional. llms-full.txt carries expanded content (full page text) for systems that want depth. Start with llms.txt; add the full variant when you have substantial documentation. Keep llms.txt itself under ~50KB.

How do I know it’s working?

Validate the format with the free validator, confirm it returns HTTP 200 with content-type text/plain, and re-run a full audit — the llms.txt checks verify presence, structure, and sitemap consistency live.

Generate yours in 40 seconds

Paste your domain — get a spec-valid llms.txt built from your own sitemap.

Open the generator →