Introduction
Nuxt AI Ready v3 supports Nuxt 4.6 and Nuxt 5. It ships in Nuxt SEO v6.
Nuxt SEO v6 installs AI Ready by default. It uses AI Ready's own defaults and overrides no option (nuxt-seo#666).
To turn the module off inside Nuxt SEO, set aiReady: false.
Markdown negotiation now varies only on the Accept header by default.
Root skills/ directories are no longer published by default.
drizzle-orm is now an optional peer dependency, so a default install is about 16 MB smaller.
Check the breaking changes before upgrading.
For a guided migration, use the LLM upgrade prompt with Claude or ChatGPT.
Accept-Only Negotiation
A request that prefers text/markdown still receives the Markdown version of a page. (#160)
AI bot User-Agents no longer select Markdown by default.
Your caches now need only the Accept header in their key.
In v2, User-Agent variation split identical HTML responses into many cache entries.
export default defineNuxtConfig({
routeRules: {
'/docs/**': {
cache: { maxAge: 3600, varies: ['accept'] },
},
},
})To keep bot detection, set aiReady: { botNegotiation: true }. See Accept-Only Negotiation below.
After a negotiated redirect, the Markdown version also sends Vary: Accept. This applies to runtime and static pages. (#159)
Configuration Warnings
The module checks your configuration in development and at build time. Each warning names its fix. (#160)
- A missing or local
site.url. - An ISR route rule, which turns off negotiation.
- A cache rule with no
acceptentry incache.varies. - Static output that cannot run negotiation middleware.
contentNegotiation: truethat overrides cache protection.
Typed Runtime Imports
Import app functions from #ai-ready/app and server functions from #ai-ready/server. (#148)
The module keeps its auto-imports and the #ai-ready alias.
import { searchPages } from '#ai-ready/server'
export default defineEventHandler(event => searchPages(event, 'nuxt seo', { limit: 5 }))Named Discovery Entries
Generated discovery catalogs now include display names. (#158)
The module also serves the catalog at the ARD path, /.well-known/ard.json.
The MCP handshake and llms.txt carry default guidance for the page tools.
If you set mcp.instructions, the module keeps your text.
Lighter Requests
The module selects its storage implementation at build time. (#153) With the database disabled, matched production requests loaded 73 Drizzle files (247,518 source bytes) before this change. They now load none. Negotiation runs once per request. For 100 SSR requests, header parsing and route lookups fell from 200 to 100.
Link header construction also repeats less work.
With i18n, the module builds the common Link URLs once per request. (#154)
Site Config resolves once per header build. (#155)
Since v2.0
These features shipped in v2 minor releases. They are new to you if you upgrade from v2.0 or enable AI Ready through Nuxt SEO v6.
- PostgreSQL support for runtime indexing, v2.1 (#91).
/sitemap.md, canonical links, anddescribedbylinks, v2.2 (#101).- A single-route reindex endpoint and CLI command, v2.2 (#104).
- Agent Skills discovery and a root
/SKILL.mdalias, v2.3 (#113, #111). - Sitemap
lastmoddates from detected content changes, v2.4 (#131). - One Markdown pipeline for prerender, runtime, and indexing, v2.5 (#138).
- An Agent Skill inside the package, v2.5 (#134).
Breaking Changes
Nuxt 4.6 and Node 22.22.3
AI Ready v3 requires Nuxt ^4.6.0 || ^5.0.0. (#148)
It also requires Node ^22.22.3 || ^24.15.0 || >=26.0.0.
v2 declared Nuxt >=4.0.0.
better-sqlite3 Removed
On Node, SQLite now uses the built-in node:sqlite module only. (#148)
The better-sqlite3 fallback and its optional peer dependency are gone.
Bun uses bun:sqlite. Cloudflare uses D1.
# Before: Node versions without node:sqlite needed the fallback
pnpm add better-sqlite3
# After: remove it if only AI Ready used it
pnpm remove better-sqlite3Accept-Only Negotiation Default
AI bot User-Agents no longer get Markdown when their Accept header prefers HTML. (#160)
Negotiated responses send Vary: Accept. v2 sent Vary: Accept, Sec-Fetch-Dest, User-Agent.
A cached route keeps negotiation when its cache.varies includes accept.
// Before: v2 needed all three inputs in the cache key
export default defineNuxtConfig({
routeRules: {
'/docs/**': { cache: { maxAge: 3600, varies: ['accept', 'sec-fetch-dest', 'user-agent'] } },
},
})
// After: v3 needs only Accept
export default defineNuxtConfig({
routeRules: {
'/docs/**': { cache: { maxAge: 3600, varies: ['accept'] } },
},
})To keep bot detection, set botNegotiation: true. Your Nitro and CDN caches must then vary on all three inputs.
export default defineNuxtConfig({
aiReady: { botNegotiation: true },
routeRules: {
'/docs/**': { cache: { maxAge: 3600, varies: ['accept', 'sec-fetch-dest', 'user-agent'] } },
},
})If your CDN cannot vary on Accept, set aiReady: { contentNegotiation: false } and link explicit .md URLs.
Markdown URLs Skip Response Caching on Nitro 3
On Nitro 3, the module adds a /**.md route rule with cache: false. (#160)
Nitro 3 response caches call the page handler without global middleware.
With this rule, Markdown conversion still runs. Nitro 2 builds do not change.
Root skills/ No Longer Published
By default, discovery now scans public directories only. (#163)
Root skills/ folders can hold private instructions for coding agents.
v2 published them by default.
# Before: published by default
skills/seo-audit/SKILL.md
# After: published by default
public/skills/seo-audit/SKILL.mdTo keep publishing root skills, set the directory explicitly:
export default defineNuxtConfig({
aiReady: {
agentSkills: { dir: 'skills' },
},
})Module Dependency Versions
AI Ready installs these modules as dependencies. The minimum versions changed. (#148, #162)
- @nuxtjs/robots v7: release notes
- @nuxtjs/sitemap v9: release notes
- nuxt-site-config v5: breaking changes
- nuxtseo-shared v6
drizzle-orm Is an Optional Peer Dependency
AI Ready no longer installs Drizzle ORM. (#172)
A default install is about 16 MB smaller, unpacked.
Only the runtime database uses drizzle-orm. These features turn on the database:
runtimeSyncorcron- MCP site tools, when the app installs
@nuxtjs/mcp-toolkit - WebMCP site tools, with
webmcp: true - An explicit
databaseoption
If one of them is on and drizzle-orm is missing, the build fails. The error names the feature and the install command.
# Before: every install included drizzle-orm
pnpm add nuxt-ai-ready
# After: add drizzle-orm when a feature uses the database
pnpm add nuxt-ai-ready drizzle-orm@1.0.0-rc.4If you use MCP Toolkit only for your own tools, set aiReady: { database: false } instead. The site tools then stay off, and the app does not need drizzle-orm.
DevTools Needs nuxtseo-devtools-host
The DevTools panel now loads from a separate package. To keep the AI Ready tab, install it as a dev dependency.
pnpm add -D nuxtseo-devtools-hostWithout it, the AI Ready tab shows an install button for the package. Production builds do not change.
LLM Upgrade Prompt
Paste this into Claude, ChatGPT, or any LLM to migrate your codebase.
# Upgrade Guide: nuxt-ai-ready v2 to v3.0.0
You are helping me upgrade nuxt-ai-ready from v2 to v3.0.0 in my Nuxt project.
If the project uses @nuxtjs/seo, upgrade @nuxtjs/seo to v6 instead. It includes nuxt-ai-ready v3.
## Requirements
- Nuxt `^4.6.0 || ^5.0.0`
- Node `^22.22.3 || ^24.15.0 || >=26.0.0`
## Breaking Changes
### 1. better-sqlite3 Removed
**What changed:** [SQLite](https://sqlite.org) uses `node:sqlite` only. The `better-sqlite3` fallback is gone.
**Search my codebase for:** `better-sqlite3`
**Action:** Remove `better-sqlite3` from package.json if nothing else uses it.
### 2. Accept-Only Negotiation
**What changed:** AI bot User-Agents no longer get Markdown by default. Responses vary only on `Accept`.
**Search my codebase for:** `varies`, `sec-fetch-dest`, `user-agent`, `contentNegotiation`
**Regex pattern:** `varies:\s*\[[^\]]*['"]user-agent['"]`
**Before:**
```ts
routeRules: { '/docs/**': { cache: { maxAge: 3600, varies: ['accept', 'sec-fetch-dest', 'user-agent'] } } }
```
**After:**
```ts
routeRules: { '/docs/**': { cache: { maxAge: 3600, varies: ['accept'] } } }
```
**Action:** Ask me whether to keep bot detection. If yes, set `aiReady: { botNegotiation: true }` and keep all three `varies` entries.
### 3. Root skills/ No Longer Published
**What changed:** Agent skill discovery scans `public/skills/<name>/SKILL.md` only.
**Search my codebase for:** files matching `skills/*/SKILL.md` outside `public/`
**Action:** Ask me which skills are public. Move public skills to `public/skills/<name>/SKILL.md`. Or set `aiReady: { agentSkills: { dir: 'skills' } }` to keep the old folder.
### 4. Module Dependency Versions
**What changed:** AI Ready requires @nuxtjs/robots v7, @nuxtjs/sitemap v9, nuxt-site-config v5, and nuxtseo-shared v6.
**Search my codebase for:** `@nuxtjs/robots`, `@nuxtjs/sitemap`, `nuxt-site-config` in package.json
**Action:** Upgrade any direct dependency on these packages to the listed major.
### 5. DevTools Host Package
**What changed:** The DevTools panel needs `nuxtseo-devtools-host`.
**Action:** If I use Nuxt DevTools, add `nuxtseo-devtools-host` as a dev dependency.
### 6. drizzle-orm Optional Peer
**What changed:** nuxt-ai-ready no longer installs `drizzle-orm`. The build fails when a feature needs the database and `drizzle-orm` is missing.
**Search my codebase for:** `runtimeSync`, `cron`, `webmcp`, `database` inside `aiReady`, and `@nuxtjs/mcp-toolkit` in package.json
**Action:** If any of them is on, add `drizzle-orm@1.0.0-rc.4` to dependencies. If I use MCP Toolkit only for my own tools, ask me whether to set `aiReady: { database: false }` instead.
## Optional
Replace server imports from `#ai-ready` with `#ai-ready/server`, and app imports with `#ai-ready/app`.
**Regex pattern:** `from ['"]#ai-ready['"]`
## Verification Checklist
1. `pnpm install` (update lockfile)
2. `npx nuxt typecheck` (catch type errors)
3. `pnpm build` (read the AI Ready configuration warnings)
4. `curl -H 'Accept: text/markdown' -D - -o /dev/null <url>` returns a redirect to the `.md` URL
5. `/llms.txt` and one `.md` page load on the preview server
---
Please scan my codebase for all affected patterns listed above and generate a complete migration plan. For each file that needs changes, show me the exact diff.Upgrading
If you use @nuxtjs/seo, upgrade it to v6. It includes AI Ready v3.
# pnpm
pnpm add nuxt-ai-ready@^3
# npm
npm install nuxt-ai-ready@^3
# yarn
yarn add nuxt-ai-ready@^3Changelog
Compare changes
Enhancements
- ⚠️ Prepare AI Ready 3 for Nuxt 4.6 (#148)
- ⚠️ Default to Accept-only negotiation with cache warnings (#160)
Performance
- Prune disabled storage and reuse request negotiation (#153)
- i18n: Reuse common status-aware Link header work (#154)
- Resolve site URLs once per header build (#155)
- ⚠️ deps: Make drizzle-orm an optional peer (#172)
Fixes
- ⚠️ skills: Discover public artifacts by default (#163)
- discovery: Publish named ARD entries and agent guidance (#158)
- markdown: Preserve Accept variation after negotiation (#159)
- skills: Align metadata with the Agent Skills spec (#161)
Refactors
- Use native module dependencies for Site Config (#162)
Documentation
- Add the module icon and unify the README badges (#149)