---
title: "llms.txt Generation · Nuxt AI Ready · Nuxt SEO"
canonical_url: "https://nuxtseo.com/docs/ai-ready/guides/llms-txt"
last_updated: "2026-08-16T09:50:30.703Z"
meta:
  description: "Configure llms.txt and llms-full.txt output for AI discovery."
  "og:description": "Configure llms.txt and llms-full.txt output for AI discovery."
  "og:title": "llms.txt Generation · Nuxt AI Ready · Nuxt SEO"
---

Nuxt SEO on GitHub

Switch to AI ReadySwitch to Nuxt SEOSwitch to RobotsSwitch to SitemapSwitch to OG ImageSwitch to Schema.orgSwitch to Link CheckerSwitch to SEO UtilsSwitch to Site ConfigSwitch to Skew Protection

**Core Concepts**

# **llms.txt Generation**

Nuxt AI Ready generates `**/llms.txt**` during prerender following the [**~~llms.txt proposal~~**](https://llmstxt.org/). It also generates `**/llms-full.txt**`, a companion context export whose format is not defined by the proposal.

## `**/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>

Canonical Origin: https://example.com

**Notes:**

<Notes>

## <Section Title>

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

## Pages

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

### Configuration

Add custom sections:

nuxt.config.ts

```ts
export default defineNuxtConfig({
  aiReady: {
    llmsTxt: {
      // Opt in to .md links when that representation is deployable
      markdownLinks: true,
      sections: [
        {
          title: 'API Reference',
          links: [
            { title: 'REST API', href: '/docs/api', description: 'API documentation' }
          ]
        }
      ],
      notes: 'Built with Nuxt AI Ready'
    }
  }
})
```

Full config: [**~~Configuration~~**](https://nuxtseo.com/docs/ai-ready/api/config)

The formatter places link descriptions after the link on the same line. It puts required section descriptions and `**notes**` in the heading-free preamble before the first H2. Links from every section marked `**optional**` are flattened into the proposal's single special `**## Optional**` file list, with their section description included in each link note.

Automatically generated page links use canonical page URLs by default. Set `**markdownLinks: true**` to link to available `**.md**` representations: generated or copied Markdown files in static output, or eligible page routes handled by the runtime Markdown endpoint. File-like, internal, ignored, or skipped routes keep their canonical URLs.

### Hook

Modify sections before generation:

nuxt.config.ts

```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~~**](https://nuxtseo.com/docs/ai-ready/api/nuxt-hooks#ai-ready-llms-txt)

## `**/llms-full.txt**`

Full Markdown content for all pages. Streamed during prerender - each page is appended as an independent document, with no memory accumulation.

`**llms-full.txt**` is not part of the llms.txt proposal. Nuxt AI Ready uses a thematic break and a compact metadata list to identify each source page, then preserves that page's original Markdown headings and fenced content:

llms-full.txt

```md
# Example Site

> Example description.

Canonical Origin: https://example.com

---

- **Page:** Borrow
- **Source:** https://example.com/borrow
- **Description:** Borrower information.

# Keep your crypto. Buy a home.

## How it works
```

Repeated H1 headings are intentional: each block is an independent source document rather than a subsection in one artificial global heading hierarchy.

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

nuxt.config.ts

```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:

nuxt.config.ts

```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:

server/plugins/mdream.ts

```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:

server/plugins/markdown.ts

```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:

nuxt.config.ts

```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:

nuxt.config.ts

```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.

**Was this page helpful?**

### **Related **

[**Content Signals**](https://nuxtseo.com/docs/ai-ready/guides/content-signals)

[**Nuxt Hooks**](https://nuxtseo.com/docs/ai-ready/api/nuxt-hooks)

[**Configuration**](https://nuxtseo.com/docs/ai-ready/api/config)

[**Agent Skills Discovery** Publish local and externally hosted Agent Skills through the v0.2.0 well-known index.](https://nuxtseo.com/docs/ai-ready/guides/agent-skills) [**Model Context Protocol (MCP)** Connect AI agents like Claude to your Nuxt site via MCP servers with built-in tools and resources.](https://nuxtseo.com/docs/ai-ready/guides/mcp)