Next.js tutorial · App Router · 6 minutes

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

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.