llms.txt in Next.js
Add an llms.txt file to your Next.js project in minutes — either as a static asset or a dynamic Route Handler.
Last updated:
Two approaches
Next.js gives you two clean ways to serve llms.txt at /llms.txt:
- Static file in
/public/— the simplest approach. Write the file by hand or generate it at build time. Works with both App Router and Pages Router. Zero runtime overhead. - App Router Route Handler — a TypeScript file at
app/llms.txt/route.tsthat generates the content dynamically from your data sources (MDX files, CMS, database). Best if your content changes frequently.
For most sites, the static file in /public/ is the right choice. Use the Route Handler
only if you want to auto-generate the content from your site\'s data at build or request time.
Method 1: Static file in /public/
Next.js serves every file in the /public/ directory at the root of your domain. A file
at /public/llms.txt is available at https://yourdomain.com/llms.txt
with no additional configuration.
-
Create the file:
touch public/llms.txt -
Write your
llms.txtcontent (see the how-to guide and generator for the correct format):
# Your Site Name
> One-sentence description of your site for LLM context.
## Core pages
- [Page title](https://yourdomain.com/page/): brief description.
- [Another page](https://yourdomain.com/other/): brief description.
## Optional
- [About](https://yourdomain.com/about/): who maintains this site.
- Commit the file and deploy. Done.
Method 2: App Router Route Handler
If you want to generate llms.txt programmatically — for example, by reading all MDX files
in your content directory — use a Route Handler.
Create the file app/llms.txt/route.ts:
import { NextResponse } from 'next/server';
export const dynamic = 'force-static'; // generate at build time
export async function GET() {
// Build your content. Here: hardcoded; in practice: read from MDX, CMS, etc.
const content = `# Your Site Name
> Description of your site.
## Core pages
- [Getting started](https://yourdomain.com/docs/getting-started/): installation and first steps.
- [API reference](https://yourdomain.com/docs/api/): full endpoint reference.
`;
return new NextResponse(content, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
// Optional: cache for 1 hour in production
'Cache-Control': 'public, max-age=3600, stale-while-revalidate=86400',
},
});
}
Setting dynamic = 'force-static' tells Next.js to render this route at build time rather
than on every request. Remove this line if you need truly dynamic content (fetched from a live database
at request time).
Pages Router alternative
If you are using the Next.js Pages Router (pre-App Router), the easiest path is still the static
file in /public/. The Route Handler file convention only exists in App Router.
For dynamic generation with Pages Router, you can use a custom server (Express or Fastify) or a getServerSideProps-backed page with a custom content type — but that adds significant complexity compared to the
static file. Stick with /public/llms.txt
for Pages Router projects.
Adding llms-full.txt
llms-full.txt inlines the full content of your key pages
into a single file. In Next.js App Router:
// app/llms-full.txt/route.ts
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
export const dynamic = 'force-static';
export async function GET() {
// Example: read MDX files from content/docs and concatenate them
const docsDir = path.join(process.cwd(), 'content/docs');
const files = fs.readdirSync(docsDir).filter(f => f.endsWith('.mdx'));
const sections = files.map(file => {
const content = fs.readFileSync(path.join(docsDir, file), 'utf8');
const slug = file.replace('.mdx', '');
return `## https://yourdomain.com/docs/${slug}/\n\n${content}`;
});
const body = `# yourdomain.com — full content\n\n${sections.join('\n\n---\n\n')}`;
return new NextResponse(body, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
Verifying the setup
After deploying, verify that your file is accessible and well-formed:
-
Visit
https://yourdomain.com/llms.txtin your browser — you should see plain text. -
Check the HTTP headers:
curl -I https://yourdomain.com/llms.txtshould showContent-Type: text/plainand a 200 status code. - Paste the URL into the llmtxt.info validator to check spec compliance.
- Check that
llms.txtis not blocked in yourpublic/robots.txt.
Continue reading
- How to create llms.txt — general guide with templates for all frameworks.
- What is llms-full.txt? — the full-corpus companion file.
- Validator — check your file against the spec.
- Best practices — what to include and what to avoid.