Index of every page on this site: llms.txt

Set module options under aiReady in your Nuxt configuration. Defaults below describe the current module.

Nuxt SEO v6 installs AI Ready with the defaults on this page. It overrides no AI Ready option. If your app uses @nuxtjs/seo, set these options under the same aiReady key.
nuxt.config.ts
export default defineNuxtConfig({
  aiReady: {
    // options
  }
})

enabled: boolean

  • Default: true
aiReady: {
  enabled: process.env.NODE_ENV === 'production'
}

debug: boolean

  • Default: false

Enable debug logging for module operations.

contentNegotiation: boolean

  • Default: Automatic per route

Set false to keep original page URLs as HTML and disable Accept and bot negotiation. Explicit .md URLs, alternate links, llms.txt, MCP, and page indexing remain available.

Default negotiation uses Accept only. Automatic mode disables negotiation for ISR and for response caches without accept in cache.varies. This includes swr rules after Nitro normalizes them. headersOnly: true remains safe because it does not cache the response body. If you enable bot negotiation, cache variation must also include sec-fetch-dest and user-agent. To restore automatic mode, remove contentNegotiation; do not set it to 'auto'.

Set false for URL-only CDN or reverse proxy caching configured outside Nuxt. Set true to force negotiation and take responsibility for the cache key.

export default defineNuxtConfig({
  aiReady: {
    contentNegotiation: false
  }
})

botNegotiation: boolean

  • Default: false

Offer Markdown to recognized AI bots even when their Accept header prefers HTML. Bot detection does not override browser navigation or explicit Markdown rejection. contentNegotiation: false also disables bot negotiation.

This mode requires cache variation on Accept, Sec-Fetch-Dest, and User-Agent. Leave the default to avoid creating cache entries for each User-Agent value.

nuxt.config.ts
export default defineNuxtConfig({
  aiReady: { botNegotiation: true },
  routeRules: {
    '/docs/**': {
      cache: {
        maxAge: 3600,
        varies: ['accept', 'sec-fetch-dest', 'user-agent'],
      },
    },
  },
})

Merge these entries with existing cache options and variation headers. External CDN cache rules must also cover all three inputs.

apiCatalog: false | ApiCatalogConfig

  • Default: Disabled until you configure entries or an integration generates them
  • Nuxt SEO v6 keeps this default.

Publish an RFC 9727 API Catalog at /.well-known/api-catalog. Relative URLs resolve against site.url and app.baseURL once during module setup. Non-root apps redirect the origin-root request to the base-aware route.

export default defineNuxtConfig({
  site: {
    url: 'https://example.com',
  },
  aiReady: {
    apiCatalog: {
      entries: [{
        anchor: '/api',
        serviceDesc: {
          href: '/openapi.json',
          type: 'application/vnd.oai.openapi+json;version=3.1',
        },
        serviceDoc: { href: '/docs/api', type: 'text/html' },
        status: { href: '/api/health', type: 'application/json' },
      }],
    },
  },
})

Each entry needs at least one relation target. A relation accepts one target or an array. Supported typed relations are item, serviceDesc, serviceDoc, serviceMeta, status, and apiCatalog. Use relations for other RFC 8288 relation names. Set apiCatalog: false to suppress configured and integration-generated entries.

mdreamOptions: MdreamOptions

  • Default: { minimal: true, clean: true }

Configure mdream HTML-to-markdown conversion.

export default defineNuxtConfig({
  aiReady: {
    mdreamOptions: {
      minimal: true
    }
  }
})

markdownCacheHeaders: { maxAge?: number, swr?: boolean }

  • Default: { maxAge: 3600, swr: true }

Cache settings for runtime markdown endpoints.

OptionTypeDefaultDescription
maxAgenumber3600Cache duration in seconds
swrbooleantrueStale-while-revalidate

agentSkills: false | AgentSkillsConfig

  • Default: {}
  • Nuxt SEO v6 keeps this default.

Publish an Agent Skills Discovery v0.2.0 index. The module finds public/skills/<name>/SKILL.md files in your project and its layers. It honors each layer's configured public directory. Set agentSkills.dir: 'skills' to publish root skills/ directories explicitly. It serves each file at /.well-known/agent-skills/<name>/SKILL.md and /skills/<name>/SKILL.md. For one skill, or the skill selected by root, it also serves /SKILL.md.

The module lists discovered skills in llms.txt. With no skills, it publishes nothing. Use dir to change the folder or disable discovery. Use skills to add local or external entries. Set llmsTxt: false to leave llms.txt alone, or agentSkills: false to disable publication. The ai-ready:agent-skills hook sees every entry before publication.

aiReady: {
  agentSkills: {
    skills: [{
      source: 'local',
      name: 'seo-audit',
      description: 'Audit a site for critical SEO issues.',
      file: './skills/seo-audit/SKILL.md'
    }]
  }
}

llmsTxt: LlmsTxtConfig | false

  • Default: Auto-generated

Configure llms.txt generation. Set false when an application route owns the file. An existing public/llms.txt automatically disables generation.

export default defineNuxtConfig({
  aiReady: {
    llmsTxt: {
      markdownLinks: true,
      sections: [
        {
          title: 'API Reference',
          links: [
            { title: 'REST API', href: '/docs/api', description: 'API docs' }
          ]
        },
        {
          title: 'Debug Endpoints',
          optional: true,
          links: [
            { title: 'Debug Route', href: '/__ai-ready-debug', description: 'Internal debugging' }
          ]
        }
      ],
      notes: 'Built with Nuxt AI Ready'
    }
  }
})

LlmsTxtSection:

PropertyTypeDescription
titlestringSection title
descriptionstring | string[]Section context rendered in the heading-free preamble, or in each optional link note
links{ title, href, description? }[]Links in section
optionalbooleanPut the section's links in the single ## Optional file list, which LLMs may skip with shorter context windows
sitemapstring | string[]Generate a separate file from named sitemaps, including their chunks
pathstringGenerated section file at /llms/<name>.txt. Defaults to /llms/<first sitemap>.txt

LlmsTxtConfig:

PropertyTypeDescription
markdownLinksbooleanLink automatically generated page and locale entries to available Markdown representations. Defaults to true
directive{ markdown?: boolean, html?: boolean }Point each page at llms.txt. markdown adds a line after the frontmatter of every .md response, default true. html adds a visually hidden link at the top of every HTML body, default false
sectionsLlmsTxtSection[]Custom sections
notesstring | string[]Additional heading-free context rendered before file-list sections
pages'sitemap' | 'all' | falseDefault sitemap uses current sitemap admission. all includes stored pages outside the sitemap. false omits the automatic list
sitemapsstring[]Read only these sitemap names. Use sitemap for the default single sitemap. An empty array stops sitemap discovery
maxLengthnumberMaximum characters per file. Default 80000, minimum 1024. Large lists split into linked files

llmsFullTxt: boolean

  • Default: true

Set false to omit /llms-full.txt, its runtime route, and its generated discovery link. The setting also stops the streamed export during prerendering.

sitemapMd: boolean

  • Default: true

Generate a Markdown sitemap at /sitemap.md from indexed pages. The sitemap groups pages by top-level path segment under ## headings. Each link points at the page’s .md representation. When a page records a last update, it becomes the link's title text.

The same flag appends a ## Sitemap section to module-generated Markdown, linking back to /sitemap.md.

export default defineNuxtConfig({
  aiReady: {
    sitemapMd: false
  }
})

describedby: boolean

  • Default: true

Advertise llms.txt with rel="describedby" on HTML and Markdown responses. HTML pages get a <link rel="describedby" href="/llms.txt"> tag, and both variants get a Link header entry.

export default defineNuxtConfig({
  aiReady: {
    describedby: false
  }
})

contentSignal: false | { aiTrain?: boolean, contentUsage?: boolean, search?: boolean, aiInput?: boolean }

  • Default: undefined, which sends Content-Signal: search=yes, ai-input=yes

Content Signal directives for robots.txt. See Content Signals guide. Without this option, robots.txt allows search and AI input and states no AI training preference. An object states the whole policy: the module sends no for each permission you leave out. Set false to send no Content-Signal line.

export default defineNuxtConfig({
  aiReady: {
    contentSignal: {
      aiTrain: false, // Block training
      contentUsage: false, // Omit Content-Usage from robots.txt
      search: true, // Allow search indexing
      aiInput: true, // Allow RAG/grounding
    }
  }
})

tools: SiteToolsConfig

Configure the three built-in tools once, then attach each one to MCP, WebMCP or both.

ToolShared optionsmcp optionswebmcp options
listPagesdefaultLimitenabledenabled, maxOutputChars, exposedTo
searchPagesdefaultLimitenabledenabled, maxOutputChars, exposedTo
getPageMarkdownNoneenabledenabled, maxOutputChars, exposedTo

defaultLimit defaults to 20 for listPages and 10 for searchPages. Values are clamped to 50. WebMCP output defaults to 1,500 characters per tool.

export default defineNuxtConfig({
  aiReady: {
    tools: {
      listPages: {
        defaultLimit: 10,
        webmcp: { enabled: false },
      },
      searchPages: {
        defaultLimit: 5,
        webmcp: { maxOutputChars: 3000 },
      },
    },
  },
})

The module enables omitted attachment objects when their transport is active. Set mcp.enabled or webmcp.enabled to false on one tool to leave it off that transport.

mcp: { tools?: boolean, resources?: boolean }

  • Default: { tools: true, resources: true }

Control MCP features when @nuxtjs/mcp-toolkit installed.

export default defineNuxtConfig({
  aiReady: {
    mcp: {
      tools: true, // list_pages, search_pages, get_page_markdown
      resources: true, // pages resource
    }
  }
})

See MCP guide for tool/resource details.

mcpServerCard: false | McpServerCardConfig

  • Default: { cacheMaxAge: 3600 }

Publish experimental SEP-2127 discovery metadata at <mcp-route>/server-card when MCP Toolkit runs on the server. For the default Toolkit route, the card is available at /mcp/server-card. The same card is also served at /.well-known/mcp/server-card.json and /.well-known/mcp.json, and llms.txt links it. Set this option to false to disable these routes and the llms.txt entry.

OptionTypeDefaultDescription
namestringDerived from site host and MCP routeReverse-DNS/server identity
titlestringExisting Toolkit or site nameHuman-readable server title
descriptionstringToolkit or site descriptionServer description, up to 100 characters
websiteUrlstringNoneAbsolute HTTP or HTTPS project or documentation URL
cacheMaxAgenumber3600Browser and shared cache lifetime in seconds

Toolkit icons are copied into the card. The card route is omitted when Toolkit is absent, disabled or unavailable in a static deployment.

webmcp: boolean | WebMcpConfig

  • Default: false

Register WebMCP tools for browser agents through document.modelContext.

OptionTypeDefaultDescription
toolsbooleantrueAttach tools enabled under aiReady.tools
exposedTostring[]NoneDefault trusted origins for built-in and composable tools. Same-origin only by default
export default defineNuxtConfig({
  aiReady: {
    tools: {
      listPages: {
        webmcp: { enabled: false },
      },
      searchPages: {
        defaultLimit: 20,
        webmcp: { maxOutputChars: 3000 },
      },
    },
    webmcp: {
      exposedTo: ['https://agent.example.com'],
    },
  },
})

Nuxt auto-imports useWebMcpTool() and useWebMcpSupported() when you enable WebMCP. Set webmcp.tools to false to register your own tools without the built-in definitions or /__ai-ready/pages endpoint.

llmsTxtCacheSeconds: number

  • Default: 600 (10 minutes)

Cache duration for llms.txt route handlers. Uses stale-while-revalidate.

export default defineNuxtConfig({
  aiReady: {
    llmsTxtCacheSeconds: 3600 // 1 hour
  }
})

database: false | { type?: string, filename?: string, bindingName?: string, url?: string, authToken?: string }

  • Default: Disabled until a requested feature needs stored pages.

Configure the database for page storage. The module auto-detects the best driver based on the deployment platform.

The database needs drizzle-orm, an optional peer dependency: npx nypm add drizzle-orm@1.0.0-rc.4. If the database is on and drizzle-orm is missing, the build fails. The error names the feature that turned on the database.

OptionTypeDefaultDescription
type'none' | 'sqlite' | 'bun' | 'd1' | 'libsql' | 'neon' | 'postgres''sqlite'Database type. 'none' disables the database
filenamestring'.data/ai-ready/pages.db'SQLite file path
bindingNamestring'DB'D1 binding name
urlstring-LibSQL, Neon, or PostgreSQL URL
authTokenstring-LibSQL/Turso auth token
export default defineNuxtConfig({
  aiReady: {
    database: {
      filename: '.data/ai-ready/pages.db'
    }
  }
})

Driver auto-detection:

Every driver needs drizzle-orm. Some drivers also need a client package:

PlatformDriverExtra dependency
Node.jsnode:sqliteNone
Bunbun:sqliteNone
CloudflareD1None
Vercel (with POSTGRES_URL)Neon Postgres@neondatabase/serverless
database.type: 'libsql'LibSQL@libsql/client
database.type: 'postgres'PostgreSQLpostgres

Each extra dependency is an optional peer dependency. Install it in the same command as drizzle-orm. For Neon: npx nypm add drizzle-orm@1.0.0-rc.4 @neondatabase/serverless. The Neon and PostgreSQL drivers read database.url, POSTGRES_URL, then DATABASE_URL.

Prerendering creates a compressed dump. Before its first database query, each server process restores the dump into empty storage or checks it for build changes.

No Database

The database stays off when no requested feature needs stored pages. Set database: false (or database: { type: 'none' }) to force it off. No driver and no drizzle-orm code enter the server bundle, so the app does not need drizzle-orm.

Runtime indexing, MCP page tools or resources, and WebMCP page tools enable storage automatically. An explicit database config also enables storage.

Build-time generation still works. You keep:

  • llms.txt and llms-full.txt, written during prerender.
  • .md twins for every prerendered page.
  • The Link headers, content signals, API Catalog and Agent Skills.

Runtime Markdown conversion remains available without a database when the deployment retains a server. A fully static deployment can only serve its generated files.

The following features need stored pages:

  • list_pages, search_pages and get_page_markdown, for both MCP and WebMCP.
  • The MCP pages resource.
  • Runtime llms-full.txt needs stored pages to include page bodies. Prerender the route for static output.

A disabled database conflicts with runtimeSync and cron. If you set any of them, the build fails with a message naming the option.

Table naming:

The module uses these reserved table names:

  • ai_ready_pages : Main pages table
  • ai_ready_pages_fts : FTS5 full-text search index
  • _ai_ready_info : Schema version tracking

The prefixes separate these tables from unrelated application tables. Do not reuse the same table names for other data.

cron: boolean

  • Default: false

Enable the scheduled task that runs every 5 minutes. It automatically enables runtimeSync for background indexing.

export default defineNuxtConfig({
  aiReady: {
    cron: true
  }
})

Runtime sync authentication

Set Nuxt's private runtimeConfig.appSecret through NUXT_APP_SECRET, with at least 32 characters. No module-specific secret configuration is needed. The legacy runtimeSyncSecret option and environment keys remain supported with deprecation warnings.

AI Ready uses Nuxt's deriveSecret('nuxt-ai-ready:runtime-sync') to produce its bearer token. OG Image uses the same root secret with its own purpose. The tokens are distinct. Cloudflare requests derive the same token from their NUXT_APP_SECRET binding when available.

pnpm exec nuxt-ai-ready token

Send this output in the Authorization: Bearer <token> header. Never send the root secret. Status requests also authenticate; prune dry runs are the exception. Without a root or legacy token, protected endpoints return 500. Invalid application secrets also return 500. Missing or incorrect bearer tokens return 401. Legacy ?secret= authentication remains supported with a deprecation warning. Prefer the Authorization header. Nuxt generates a development root secret. Production builds do not generate one.

runtimeSyncSecret: string

Deprecated. Use NUXT_APP_SECRET for new deployments.

Existing aiReady.runtimeSyncSecret values and NUXT_AI_READY_RUNTIME_SYNC_SECRET remain supported as raw bearer tokens. Cloudflare also accepts the legacy NUXT_NUXT_AI_READY_RUNTIME_SYNC_SECRET binding. The module logs a deprecation warning when you configure or use a legacy token.

A non-empty appSecret always takes precedence. An invalid application secret fails without using the legacy token. If you keep the legacy configuration, existing scheduler tokens work unchanged until you configure an application secret.

runtimeSync: boolean | { ttl?: number, batchSize?: number, pruneTtl?: number }

  • Default: false

Enable runtime controls and sitemap seeding for content that changes between deployments. Set true for defaults, or use an object to change them.

Poll and cron process pending pages. TTL expiry alone does not mark an already indexed page pending. When a published page changes between builds, call the authenticated reindex endpoint or a manual indexing utility.

OptionTypeDefaultDescription
ttlnumber3600Freshness window for manual indexing and sitemap refresh interval (seconds)
batchSizenumber50Pages per batch (max: 50)
pruneTtlnumber0Prune routes not seen in the sitemap for this many seconds (0 = disabled)
export default defineNuxtConfig({
  aiReady: {
    runtimeSync: {
      ttl: 3600,
      batchSize: 20,
      pruneTtl: 604800 // prune after 7 days
    },
    cron: true // enable scheduled indexing
  }
})

When enabled:

  • GET /__ai-ready/status : Check indexing progress
  • POST /__ai-ready/poll : Trigger batch indexing (requires Authorization: Bearer <token> header)
  • POST /__ai-ready/prune : Prune stale routes (requires Authorization: Bearer <token> header)
  • POST /__ai-ready/reindex?route=/about - Reindex a single route (requires Authorization: Bearer <token> header)

See Runtime Sync guide for details.

autoI18n: boolean

  • Default: true

Auto-detect @nuxtjs/i18n (or nuxt-i18n-micro) at build time and integrate locale data into:

  • llms.txt: adds an ## Available Languages on Website file-list section linking to every locale root
  • Link headers: emits Link: <…>; rel="alternate"; hreflang="…" per locale on .md and HTML responses (RFC 8288)
  • Frontmatter: runtime HTML-to-Markdown responses include a locale field
  • Database: each indexed page persists its locale for filtered queries
  • FTS5 tokenizer: auto-switches to trigram for CJK locales (zh / ja / ko)

Disable to skip the integration even with an i18n module present:

export default defineNuxtConfig({
  aiReady: {
    autoI18n: false
  }
})

See i18n guide for details.

contentSource: boolean

  • Default: true

Read Markdown directly from page collections in @nuxt/content v3 or @harlan-zw/comark-content when available. Set false to convert rendered HTML instead. Use that when a page’s meaning depends on its rendered components. See Markdown Conversion for source lookup behavior.

prerender: { concurrency?: number }

  • Default concurrency: 10

Control how many pages the module processes concurrently during prerendering. Set 1 to process one page at a time.

nuxt.config.ts
export default defineNuxtConfig({
  aiReady: {
    prerender: { concurrency: 5 },
  },
})

debugCron: boolean

  • Default: false

Record cron runs in the database for diagnostics. Enable it when investigating scheduled indexing. This option does not enable cron itself.

Was this page helpful?