How to Add llms.txt to Next.js
Next.js still has no built-in llms.txt file convention — but shipping one takes minutes. Here are the three ways to do it, from a 30-second static file to a fully dynamic, ISR-cached route handler.
Why Next.js Sites Are the #1 llms.txt Use Case
The llms.txt convention exists mainly for software documentation, where coding agents follow the file to find API references and tutorials. That is exactly the content Next.js is most often used to build. The early adopters read like a who's who of the Next.js ecosystem: Vercel publishes vercel.com/docs/llms.txt, the Next.js docs themselves serve nextjs.org/docs/llms.txt, and Strapi, Vultr, Langbase, Checkly and CircleCI all publish one at their docs roots.
If your Next.js project is a SaaS site, a docs portal, or a dev-tool marketing page,
your audience is literally the people asking ChatGPT and Claude how your product works.
An llms.txt is the cheapest way to make sure the answer they get links back
to your canonical pages — this is core
GEO (generative engine optimization)
for framework-built sites.
Method 1: Static File in public/ (30 Seconds)
The fastest option works on both App Router and Pages Router projects. Create a file at
public/llms.txt (or src/../public/llms.txt with the standard
src/ layout — Next.js copies the whole public/ folder to the
root of the build output):
# Example SaaS Docs
> Example SaaS is a hosted API platform. This file maps the pages
> coding agents should read first: quickstart, API reference, guides.
## Quickstart
- [Quickstart](https://example.com/docs/quickstart): 5-minute setup with your first API call
- [Authentication](https://example.com/docs/auth): API keys and token scopes
## API Reference
- [REST API Reference](https://example.com/api-reference): all endpoints, params and errors
- [Webhooks](https://example.com/docs/webhooks): events your server can subscribe to
Deploy and the file is live at https://your-domain.com/llms.txt. One caveat:
a static public/ file always wins over a route handler with the same path —
delete the static file if you later switch to Method 2.
Method 2: Dynamic Route Handler (App Router)
For a file that should reflect live data — your CMS, your database, your sitemap —
use a route handler. A folder named llms.txt works fine in the App Router
(no rewrites needed):
// app/llms.txt/route.ts
import { siteName, siteDescription, sections } from '@/lib/llms-config';
export const dynamic = 'force-static'; // optional: pre-render at build time
export async function GET() {
const lines = [
'# ' + siteName,
'',
'> ' + siteDescription,
'',
];
for (const section of sections) {
lines.push('## ' + section.title, '');
for (const link of section.links) {
lines.push('- ' + link.name + ': ' + link.description + ' (' + link.url + ')');
}
lines.push('');
}
return new Response(lines.join('\n'), {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
Two details matter. First, the Content-Type must be
text/plain — agents and validators expect plain text, not HTML. Second,
with export const dynamic = 'force-static' the file is generated once at
build time and served from the edge, so it costs nothing at request time.
Method 3: ISR — Keep It Fresh Without Rebuilding
Static is fast but goes stale. If your docs change hourly (release notes, changelogs,
pricing), swap force-static for an ISR interval:
// app/llms.txt/route.ts
export const revalidate = 3600; // regenerate at most once per hour
The route handler then rebuilds lazily on the next request after the interval expires,
so your llms.txt never describes pages that no longer exist. You can even
fetch your sitemap.xml inside the handler and filter it down to the
genuinely important pages — a good way to avoid hand-maintaining the file. If you prefer
a ready-made solution, the community
next-llms-txt
plugin adds this as a build-time step.
What Next.js Doesn't Ship (Yet)
In July 2025 a feature request
(vercel/next.js discussion #81182)
asked for an llms.txt file convention in the app directory, mirroring
sitemap.ts and robots.ts. A community PR (#90580) is in
progress, but native support has not shipped. The good news: the file convention only
matters for ergonomics. The public/ file and route-handler approaches above
produce exactly the same result at /llms.txt, so there is no reason to wait.
Verify Your File
After deploying, check that the route serves plain text with a 200 status:
curl -s -o /dev/null -w "%{http_code} %{content_type}\n" https://your-domain.com/llms.txt
# Expect: 200 text/plain Then paste the URL into our free llms.txt checker to validate the H1, the blockquote summary, absolute URLs, and section structure before AI engines start reading it.
Best Practices Checklist for Next.js
- Absolute URLs only —
https://example.com/docs/start, never/docs/start. Agents resolve links from the file's location. - Curate, don't dump — 10–50 links beats 500. Point agents at canonical docs pages, not marketing landing pages.
- Watch for interceptors — make sure no middleware, redirect, or
next.configrewrite catches/llms.txtbefore your route does. - Treat it like a README — update the file whenever the underlying page changes; stale files erode agent trust over time.
- Add llms-full.txt for deep docs — for large reference sections, link a generated llms-full.txt companion so agents can fetch the full content on demand.
Once it's live, run your sitemap through the
free llms.txt generator to
build the initial curated file in seconds, then validate it with the
checker before you deploy.
A correct, current llms.txt is the single highest-leverage AI visibility
change most Next.js sites can make this week.