Writing the files is the easy part. Getting them served correctly from your
domain root, with the right Content-Type, is where implementations quietly
fail — a perfectly valid file served as the wrong type is an unreadable file.
Check what you are actually serving
Before anything else, publish one file and look at the response. The
specifications require llms.txt to be served as
text/plain; charset=utf-8, reachable without authentication,
returning 200 over HTTPS.
You want HTTP/2 200 and content-type: text/plain;
charset=utf-8. If you see application/octet-stream, a
missing charset, or a 404 that returns your styled error page with a 200
status, fix that before writing another file.
Lighthouse checks this too
Chrome DevTools' Lighthouse includes an llms.txt audit
under its Agentic browsing category, so you can verify from the
browser as well as the command line. Note how it grades: a 404 is reported as
Not Applicable, because publishing the file is optional at
present — but a server error when fetching it is flagged. A
passing audit therefore means the file was retrievable, not that its contents
are right.
The soft-404 trap
Many hosts serve a friendly “page not found” HTML page with a
200 status rather than a 404. To a consumer, that looks like
a valid llms.txt containing your error page. Always check the
status code, not just whether something came back.
Per-platform
Every file goes at the domain root — https://example.com/llms.txt,
not in a subdirectory. What differs is how your platform gets it there.
Cloudflare Pages
Static host
Put the files in your output directory (or in public/ if your framework copies it through).
The trailing ! forces the redirect even when a file exists at the source path — useful if you previously published a literal llm.txt and want to retire it cleanly.
For a static build the redirect is emitted only if your adapter supports it. On Cloudflare Pages or Netlify, use that host’s _redirects file instead — it is more reliable.
Next.js
Framework
public/ at the project root. Do not create app/llms.txt/route.ts unless you need the content to be dynamic.
Shopify does not let you write arbitrary files to the domain root. robots.txt is editable via robots.txt.liquid, but llms.txt is not.
Practical options: serve the files from a subdomain you do control and point to them from robots.txt, or put them behind a reverse proxy in front of the store. A Shopify app or a custom page at /pages/llms is not equivalent — the files must be at the domain root, and a consumer fetching /llms.txt will get your 404 page.
WordPress
Hosted platform
Upload to the web root via SFTP or your host’s file manager.
Upload the files to the web root over SFTP, or use any plugin that lets you serve arbitrary static files from the root. Avoid plugins that render the files as WordPress pages — a consumer fetching /llms.txt needs the raw file, not a themed page.
When your host cannot redirect at all
The specifications prefer /llm.txt to be a 301 to
/llms.txt. Where that is impossible, publish a byte-identical
copy instead — and treat the two as one file forever after. Two files that
drift apart send conflicting identity signals, which is worse than publishing
neither.
If you keep a copy, add a build step that fails when the two differ. A single
line in CI is enough:
ci
cmp -s public/llms.txt public/llm.txt || { echo "llm.txt has drifted from llms.txt"; exit 1; }
Platform behaviour changes without notice. These snippets reflect each
platform’s documented configuration format at the time of writing — verify
with curl -I after deploying, which is the only check that
actually proves anything.
Something here out of date or wrong for your host? Email [email protected].