---
title: "llms.txt Generation"
description: "Configure llms.txt and llms-full.txt output for AI discovery."
canonical_url: "https://nuxtseo.com/docs/ai-ready/guides/llms-txt"
last_updated: "2026-05-06T18:46:56.124Z"
---

Nuxt AI Ready generates `/llms.txt` and `/llms-full.txt` during prerender following the [llms.txt standard](https://llmstxt.org/).

## `/llms.txt`

Site overview with page links. Built from page metadata collected during prerender.

Live example: [nuxtseo.com/llms.txt](https://nuxtseo.com/llms.txt)

```txt
# <Site Title>

> <Site Description>

## Pages

- [Page Title](/page-link): Meta Description
  ...

## <Section Title>

- [Link Title](/link): Description
  ...

<Notes>
```

### Configuration

Add custom sections:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    llmsTxt: {
      sections: [
        {
          title: 'API Reference',
          links: [
            { title: 'REST API', href: '/docs/api', description: 'API documentation' }
          ]
        }
      ],
      notes: 'Built with Nuxt AI Ready'
    }
  }
})
```

Full config: [Configuration](/docs/ai-ready/api/config)

### Hook

Modify sections before generation:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    'ai-ready:llms-txt': (payload) => {
      payload.sections.push({
        title: 'Custom APIs',
        links: [{ title: 'Search', href: '/api/search', description: 'Search endpoint' }]
      })
      payload.notes.push('Custom note')
    }
  }
})
```

Hook details: [Nuxt Hooks](/docs/ai-ready/api/nuxt-hooks#ai-ready-llms-txt)

## `/llms-full.txt`

Full markdown content for all pages. Streamed during prerender - each page appended as processed, no memory accumulation.

Auto-generated from prerendered pages. Hook `ai-ready:page:markdown` fires per page if you need to modify content:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    'ai-ready:page:markdown': (ctx) => {
      // ctx: { route, markdown, title, description }
      ctx.markdown = `# ${ctx.title}\n\n${ctx.markdown}`
    }
  }
})
```

## Page Discovery

Page discovery uses a two-phase approach combining prerendering and sitemap crawling.

### Phase 1: Prerender Crawl

During `nuxi generate`, the module intercepts each prerendered page:

1. Nuxt plugin queues `.md` route for each rendered page
2. Middleware converts HTML → markdown with metadata extraction
3. `ai-ready:page:markdown` hook fires for each page
4. Data appended to `page-data.jsonl` + streamed to `llms-full.txt`

Prerendered pages have full metadata (title, description, headings).

### Phase 2: Sitemap Crawl

After prerendering completes, the module crawls `/sitemap.xml` for any pages not already processed:

- Uses `sitemap:prerender:done` hook if `@nuxtjs/sitemap` exists
- Falls back to `prerender:done` hook otherwise
- Fetches `.md` for each sitemap URL not in prerender set
- Adds to `page-data.jsonl` but **skips** `llms-full.txt` (prevents duplicates)

This catches SSR-only pages that weren't prerendered.

### Runtime Fallback

In SSR-only mode (no prerendering), llms.txt dynamically fetches `/sitemap.xml` and lists URLs without titles.

```text
Phase 1 (Prerender)     Phase 2 (Sitemap)       Runtime
─────────────────────   ─────────────────────   ─────────────────────
app:rendered            sitemap:prerender:done  GET /llms.txt
    ↓                       ↓                       ↓
Queue .md routes        Parse sitemap.xml       fetchSitemapUrls()
    ↓                       ↓                       ↓
HTML → Markdown         Fetch .md for SSR       Combine prerendered
    ↓                   pages                   + sitemap URLs
Write JSONL +               ↓                       ↓
llms-full.txt           Add to JSONL only       Generate llms.txt
```

## Customizing Page Processing

### Filter or Modify Pages

Use the `ai-ready:page:markdown` hook to modify or filter pages during prerender:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    'ai-ready:page:markdown': (ctx) => {
      // Skip draft pages
      if (ctx.route.startsWith('/drafts/')) {
        ctx.markdown = '' // Empty markdown = excluded from llms-full.txt
        return
      }

      // Add frontmatter
      ctx.markdown = `---
route: ${ctx.route}
title: ${ctx.title}
---

${ctx.markdown}`
    }
  }
})
```

Context properties:

- `route`: Page path (e.g., `/about`)
- `markdown`: Converted content (mutable)
- `title`: Extracted `<title>`
- `description`: Extracted meta description
- `headings`: Array of `{ level, text }` objects

### Modify Markdown Conversion

Use the `ai-ready:mdreamConfig` Nitro hook to customize HTML → markdown:

```ts [server/plugins/mdream.ts]
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('ai-ready:mdreamConfig', (config) => {
    // Skip navigation elements
    config.ignoreSelectors = ['nav', '.sidebar', '.footer']

    // Preserve code blocks
    config.preserveCodeBlocks = true
  })
})
```

### Post-Process Markdown at Runtime

Use the `ai-ready:page:markdown` Nitro hook for runtime `.md` requests:

```ts [server/plugins/markdown.ts]
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('ai-ready:page:markdown', (ctx) => {
    // Add source link
    ctx.markdown += `\n\n---\nSource: ${ctx.route}`
  })
})
```

## Sitemap Requirements

The module requires `@nuxtjs/sitemap` for page discovery:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@nuxtjs/sitemap', 'nuxt-ai-ready']
})
```

If sitemap is missing or empty, llms.txt will have an empty pages section with a warning logged.

### Excluding Pages

Pages excluded from sitemap are automatically excluded from llms.txt. Use sitemap's `exclude` option:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  sitemap: {
    exclude: ['/admin/**', '/api/**', '/drafts/**']
  }
})
```

## Dev Mode

In development, llms.txt returns a notice about missing data. Page data is only available after `nuxi generate` or `nuxi build --prerender`.

Runtime `.md` routes still work in dev for testing markdown conversion.
