/ llmtxt.info

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:

  1. 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.
  2. App Router Route Handler — a TypeScript file at app/llms.txt/route.ts that 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.

  1. Create the file: touch public/llms.txt
  2. Write your llms.txt content (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.
  1. 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:

  1. Visit https://yourdomain.com/llms.txt in your browser — you should see plain text.
  2. Check the HTTP headers: curl -I https://yourdomain.com/llms.txt should show Content-Type: text/plain and a 200 status code.
  3. Paste the URL into the llmtxt.info validator to check spec compliance.
  4. Check that llms.txt is not blocked in your public/robots.txt.

Continue reading

Sources