This is the Nuxt SEO v6 release article, also on nuxtseo.com. To upgrade, follow the v5 to v6 migration guide.
Nuxt SEO v6 moves every bundled module to a new major version. Two modules join the bundle: AI Ready and Skew Protection.
The release drops Nuxt 3. Every module now requires Nuxt 4.6 or Nuxt 5, and Node 22.22.3+, 24.15.0+, or 26+. That floor lets the modules use Nuxt's portable server APIs, so each module carries less code of its own.
v6 installs two more modules and still weighs less. Against 5.3.16, it ships 44% less JavaScript to the browser, and its server build is 52% smaller.
Most projects need three changes: upgrade Nuxt, install the DevTools host, and check OG Image signing. Breaking Changes below lists the rest.
🤖 AI Ready and Skew Protection, Bundled
@nuxtjs/seo now installs nine modules. AI Ready and Skew Protection install with the rest.
AI Ready makes your pages readable by AI agents. It generates llms.txt and llms-full.txt, and serves every page as Markdown at a .md URL. It publishes Agent Skills from public/skills/<name>/SKILL.md, and generates an API catalog when you configure an MCP server and a site URL.
Skew Protection keeps the assets of earlier builds available after a deploy. Open tabs and crawlers stop hitting ChunkLoadError and 404s on old chunks. Under Nuxt SEO it checks for new versions with Nuxt's hourly app manifest polling, so it opens no persistent connection. It also sets no version cookie.
Your options still go under the module keys. To turn either module off, set its key to false:
export default defineNuxtConfig({
modules: ['@nuxtjs/seo'],
aiReady: false,
skewProtection: false,
})Warning
By default, Skew Protection stores old assets in node_modules/.cache/nuxt-seo/skew-protection. If your CI discards that directory between deploys, cache it. Otherwise each deploy loses the assets of earlier builds.
⚡ Performance
We built the same app on 5.3.12 (before the August performance work), 5.3.16 (the last v5 release), and v6. Each app installs every module, Nuxt i18n with two locales, and Satori for OG images. "Over bare Nuxt" is the cost on top of the same app without Nuxt SEO.
| 5.3.12 | 5.3.16 | v6 | |
|---|---|---|---|
| Nuxt SEO JavaScript in the browser, gzip | 22.6 KB | 26.8 KB | 14.9 KB |
| Server build output, gzip | 12.5 MB | 8.7 MB | 4.2 MB |
| Install size, over bare Nuxt | 108 MB | 125 MB | 73 MB |
| Server memory after boot, over bare Nuxt | 146 MB | 148 MB | 14 MB |
| Memory allocated per page render, over bare Nuxt | 1,031 KB | 954 KB | 921 KB |
- Browser JavaScript, 44% less than 5.3.16. Schema.org's default mode and Robots' bot detection no longer ship code to the browser. Skew Protection's polling default saves 4.2 KB of the 11.9 KB.
- Server build, 52% smaller. AI Ready's Markdown converter now installs only your platform's native binary, not one for every platform (nuxt-ai-ready#171).
- Install size, 42% smaller.
drizzle-orm,zod,chrome-launcher,sharp, and mdream's binaries for other platforms are now optional or gone. The test app also installs Satori, resvg, andbetter-sqlite3. Without them, Nuxt SEO adds 15 MB to a bare app. If you render OG images, add the renderer you choose. - Boot memory, 14 MB. v5 AI Ready loaded its database code at startup, even with the database off. v6 loads it only when a feature needs it. A v5 app without AI Ready never paid this cost.
🩺 Setup Checks in Development
Missing configuration used to stay silent until a crawler found the result. In v6, the first successful home page response in nuxt dev starts a background check across every installed module.
- Required checks report once per server start. Each one names the fix, the reason, and a docs link. A missing
site.urlis one of them. - Tips suggest optional features that fit your app, such as a Sitemap or OG Image setting you have not enabled. After tips show, they stay quiet for seven days in that project. Required checks ignore this pause.
The same checks appear in the Nuxt SEO DevTools panel, with a refresh action. CI and AI agent sessions skip the terminal output. To hide tips but keep required checks, set tips to false:
export default defineNuxtConfig({
nuxtseo: { tips: false },
})🧩 DevTools on Demand
The DevTools hosting code used to install for every user, including people who never open a panel. In v6 it lives in an optional package, nuxtseo-devtools-host. The shared core now installs 7 runtime dependencies, down from 14.
If you use the SEO panels in Nuxt DevTools, add the host as a development dependency:
npx nypm add -D nuxtseo-devtools-hostIf the host is missing, each panel shows an install button.
🛡️ Version Checks That Fail the Build
Before v6, @nuxtjs/seo could run with the wrong module versions and report nothing.
- On a Nuxt version without module dependency support, no module installed.
/robots.txtand/sitemap.xmlreturned 404 and the build passed. - Nuxt checked the module copy nested inside
@nuxtjs/seo, and loaded the copy your app resolved. A pinned older module passed the check.
Now a pinned older module stops the build and names the problem:
ERROR [@nuxtjs/seo] Module `@nuxtjs/sitemap` version (`8.6.1`) does not satisfy `>=9.0.0` (requested by `@nuxtjs/seo`).
An unsupported Nuxt version also stops the build. The error names your version, the required range, and the fix:
ERROR [@nuxtjs/seo] Nuxt 4.5.2 is not supported. @nuxtjs/seo requires Nuxt `^4.6.1 || ^5.0.0`. To upgrade Nuxt, run `npx nuxt upgrade`.
nuxtseo: false also works now. Before v6 it type checked but installed every module anyway. It now installs none of the bundled modules. A module that you add to modules yourself still installs.
🖼️ OG Image v7
OG Image v7 changes how images render, cache, and sign. Read the OG Image v7 migration guide before you upgrade a project with custom templates.
- Native Satori layout. Satori 0.47 supports block, inline, and grid layout, plus
translate,rotate, andscale. Templates now behave more like regular CSS. Bare<div>elements no longer get a forceddisplay: flex. - Publish to storage. Serve generated images from a public R2 or S3 mount. Repeat requests skip the render, and builds reuse published images until their cache expires.
- Fonts from
@nuxt/fontsv1. Prerendered images keep their fonts, and Takumi loads OTF and WOFF files.
export default defineNuxtConfig({
ogImage: {
publish: { storage: 'og-image-public', baseURL: 'https://images.example.com' },
},
nitro: {
storage: {
'og-image-public': { driver: 'cloudflare-r2-binding', binding: 'OG_IMAGES' },
},
},
})🤖 Robots: Block Training Crawlers Only
Robots v7 adds blockAiBots: 'training'. It blocks crawlers that collect model training data, such as GPTBot, ClaudeBot, Google-Extended, and CCBot. AI search and answer agents can still read your site.
export default defineNuxtConfig({
robots: { blockAiBots: 'training' },
})Google-Extended also controls Gemini grounding. Blocking it removes your pages from that use too.
definePageMeta({ robots }) now matches routes through your app's own router. It respects sensitive, strict, aliases, and i18n routes, so a private page no longer stays indexable because of a path mismatch.
🧭 More Module Improvements
- Sitemap v9.
definePageMeta({ sitemap: false })also excludes prerendered dynamic pages, aliases, and case or trailing slash variants. Builds without streaming or compression drop that code. - Schema.org v7. In the default non-reactive mode,
useSchemaOrg()and thedefine*()helpers leave the client bundle again. The SSR JSON-LD output is unchanged. - SEO Utils v9. Development and build warn when an indexable page renders only on the client, with a config example to copy. Derived meta tags take about half the CPU time per call.
- Link Checker v6. A build that scans no pages now says so in its log. Reports show the real HTTP status text, and a
HEADrequest that gets 405 or 501 retries withGET. - Site Config v5.
getSiteConfig(event)now works in yourserver/middleware. A prerender withoutsite.urlnow warns, where it used to render relative URLs silently. - AI Ready v3. Markdown negotiation reads the
Acceptheader only, so caches need oneVaryheader. The AI Catalog at/.well-known/ai-catalog.jsonis also served at/.well-known/ard.json. - Skew Protection v2. Open tabs share one connection through Web Locks. Core protection works without Robots or Site Config.
🧠 Agent Skill in the Package
@nuxtjs/seo now ships an Agent Skill at skills/nuxtjs-seo/SKILL.md. It tells a coding agent which module owns each config key, how to disable a module, and which install errors to expect. Get it on skilld.dev. Every bundled module now ships its own Agent Skill too.
⚠️ Breaking Changes
Nuxt 4.6.1 and Node 22.22.3 Minimum
Nuxt SEO v6 requires Nuxt ^4.6.1 || ^5.0.0. Nuxt SEO v6 no longer supports Nuxt 3.
Node must match ^22.22.3 || ^24.15.0 || >=26.0.0.
AI Ready and Skew Protection Install by Default
Remove nuxt-ai-ready and nuxt-skew-protection from your modules array and your dependencies. @nuxtjs/seo installs them. Keep your options under aiReady and skewProtection, or set either key to false.
If you already configured Skew Protection, check these v2 changes:
- An unset
updateStrategynow means hourly polling on every platform. For instant updates, setupdateStrategy: 'sse'or'ws'. experimental.appManifest: falsenow fails setup.- The default storage driver is
fs-lite. An explicitdriver: 'fs'still works. - With
multiTab: true, tabs share one push connection. To keep one connection per tab, setmultiTab: falseorconnectionTracking: true.
If you already configured AI Ready, AI bots no longer get Markdown by User-Agent alone. Set botNegotiation: true to restore that. AI Ready drops the better-sqlite3 fallback and uses node:sqlite.
DevTools Panels Need nuxtseo-devtools-host
Install nuxtseo-devtools-host as a development dependency to keep the SEO panels. The DevTools on Demand section above shows the command.
OG Image Signing Uses NUXT_APP_SECRET
If URL signing is on, set NUXT_APP_SECRET to a value of at least 32 characters. Without it, production image and page requests return a 500 error. If security.secret holds a string, remove it from your config. Generate a secret with npx nuxt-og-image generate-secret.
NUXT_OG_IMAGE_SECRET still works with a deprecation warning. Signed URLs from OG Image v6 become invalid, so purge cached HTML that contains them.
The OG Image v7 migration guide also covers these changes:
- OG Image needs Satori 0.47. Add
flex flex-colto elements that depended on the old forced flex layout. - OG Image needs Takumi v2 (
^2.15.0). Replacetakumi.fetchedResourcesandtakumi.persistentImageswithtakumi.images. - Custom fonts need
@nuxt/fontsv1. Families used only in OG images needglobal: true.
Zod 4 for Nuxt Content Schemas
defineRobotsSchema(), defineSitemapSchema(), and defineOgImageSchema() require Zod 4. Upgrade the zod package in your app.
Server Hooks Receive a RequestEvent
The robots:* and sitemap:* hook contexts now carry a RequestEvent from nuxt/server, in place of an h3 H3Event. Read request headers with the web API:
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('sitemap:sources', (ctx) => {
// v5: ctx.event.node.req.headers.authorization
const auth = ctx.event.req.headers.get('authorization')
})
})OG Image's getOgImageUrl() also takes a RequestEvent. Import defineEventHandler from nuxt/server in handlers that call it.
Site Config Priority and Values
updateSiteConfig()without_prioritynow ranks below yoursitekey andNUXT_SITE_*variables. Pass_priority: SiteConfigPriority.runtimeto keep the old order.indexableis now always a boolean. It defaults toenv === 'production'.- Module authors: Site Config v5 drops
installNuxtSiteConfig(). Declarenuxt-site-configinmoduleDependencies.
Smaller Module Changes
- Robots: Robots v7 drops the
#internal/nuxt-robotsand#internal/nuxt-simple-robotsaliases. Import from#robots/serveror#robots/app.robots.txtfiles inassets/orpages/resolve fromsrcDir(app/in Nuxt 4). - Robots:
noaiandnoimageairoute rules no longer mark a route as not indexable. Arobots:configchange made during a request now affects only that request. - Robots: route rules now take precedence over
definePageMeta({ robots }). If both set a rule for a page, the route rule wins. - Sitemap: Sitemap v9 drops
nuxt-simple-robotssupport. Use@nuxtjs/robotsv7. - Link Checker: Link Checker v6 drops Nuxt Content v2 support. Reports show the real status text, and an unreachable link reports status
0. - SEO Utils:
sharpis an optional peer dependency. Add it to usenuxt-seo-utils icons. Runtime minification no longer rewrites inline JavaScript. - Schema.org and SEO Utils: the bare
#schema-organd#seo-utilsaliases are replaced by#schema-org/app,#schema-org/server, and#seo-utils/app. - Nuxt Content: Nuxt SEO v6 no longer supports Nuxt Content v2. Use Content v3.
✅ Upgrading
The v5 to v6 migration guide covers each change step by step. Upgrade Nuxt first, then Nuxt SEO:
npx nuxt upgrade
npx nypm add @nuxtjs/seo@^6
npx nypm add -D nuxtseo-devtools-hostIf you pinned a bundled module in your package.json, update it to the version in the Module Versions table below or remove it. An older pinned module now fails the build.
🤖 LLM upgrade prompt: paste it into your coding agent to migrate a project
# Upgrade Guide: @nuxtjs/seo v5 to v6
Help me upgrade @nuxtjs/seo from v5 to v6 in this Nuxt project.
Scan the codebase for each pattern below, then show me a diff per change.
## Requirements
- Nuxt 4.6.1 or later (Nuxt 3 is not supported). Run `npx nuxt upgrade` first.
- Node ^22.22.3 || ^24.15.0 || >=26.0.0. Check `engines`, `.nvmrc`, and CI Node versions.
## 1. Bundled modules
@nuxtjs/seo v6 installs nuxt-ai-ready and nuxt-skew-protection.
- Search: `nuxt-ai-ready`, `nuxt-skew-protection` in nuxt.config.* modules and package.json.
- Remove them from `modules` and dependencies. Keep `aiReady` / `skewProtection` options.
- If the project should not use one, set `aiReady: false` or `skewProtection: false`.
- Skew Protection stores assets in node_modules/.cache/nuxt-seo/skew-protection. Cache it in CI.
- Skew Protection v2: unset `updateStrategy` now means polling; `experimental.appManifest: false` throws.
- AI Ready v3: bots no longer get Markdown by User-Agent. Set `aiReady: { botNegotiation: true }` to keep it.
## 2. Pinned module versions
Minimums: @nuxtjs/robots 7, @nuxtjs/sitemap 9, nuxt-og-image 7, nuxt-schema-org 7,
nuxt-seo-utils 9, nuxt-link-checker 6, nuxt-site-config 5, nuxt-ai-ready 3,
nuxt-skew-protection 2, @nuxtjs/i18n 10. Update or remove older pins in package.json.
## 3. DevTools
Add `nuxtseo-devtools-host` as a dev dependency if the project uses Nuxt DevTools.
## 4. OG Image v7
- Search: `security.secret`, `NUXT_OG_IMAGE_SECRET`, `ogImage.secret`.
Remove `security.secret`; set `NUXT_APP_SECRET` (32+ chars) in the deploy environment.
- Search: `*.satori.vue` and components in `components/OgImage/`. Elements that relied on forced
flex layout need `flex flex-col` classes.
- Search: `fetchedResources`, `persistentImages`. Replace with `takumi.images`.
- Search: `"@takumi-rs/core"`, `"satori"`, `"@nuxt/fonts"`. Need ^2.15.0, ^0.47.1, >=1.0.0.
- Full guide: https://nuxtseo.com/docs/og-image/migration-guide/v7
## 5. Zod 4
Search: `defineRobotsSchema`, `defineSitemapSchema`, `defineOgImageSchema`, `"zod"`.
Upgrade zod to ^4 and fix any [Zod](https://zod.dev) 3 API usage in content.config.ts.
## 6. Server hooks and events
Search: `sitemap:`, `robots:` hook handlers, `event.node.req`, `H3Event`, `getOgImageUrl(`.
- Hook contexts now carry a `RequestEvent` from `nuxt/server`.
Before: `ctx.event.node.req.headers.authorization`
After: `ctx.event.req.headers.get('authorization')`
- Handlers that call `getOgImageUrl` import `defineEventHandler` from `nuxt/server`.
## 7. Site Config v5
- Search: `updateSiteConfig(`. Without `_priority` it now ranks below the `site` key and env vars.
Add `_priority: SiteConfigPriority.runtime` where you need the old override behaviour.
- Search: `indexable === undefined`, `indexable == null`. `indexable` is always a boolean now.
- Search: `installNuxtSiteConfig`. Replace with a `moduleDependencies` entry for nuxt-site-config.
## 8. Smaller changes
- `#internal/nuxt-robots`, `#internal/nuxt-simple-robots` -> `#robots/server` or `#robots/app`.
- Bare `#schema-org` -> `#schema-org/app`; bare `#seo-utils` -> `#seo-utils/app`.
- `nuxt-simple-robots`, `nuxt-simple-sitemap`: remove; use @nuxtjs/robots and @nuxtjs/sitemap.
- `@nuxt/content` v2: Nuxt SEO v6 no longer supports it. Upgrade to Content v3.6 or later.
- `nuxt-seo-utils icons`: add `sharp` as a dev dependency.
- `assets/robots.txt` or `pages/robots.txt` at the root: move under `srcDir` (`app/`).
## Verify
1. Install dependencies and update the lockfile.
2. `npx nuxt typecheck`
3. `npx nuxt build`. A module version mismatch fails here with a named module.
4. `npx nuxt dev`, open the home page, and read the Nuxt SEO setup checks in the terminal.
5. Check /robots.txt, /sitemap.xml, /llms.txt, and one OG image URL.
Module Versions
| Module | v5 | v6 |
|---|---|---|
nuxt-site-config
| v4 | v5 |
@nuxtjs/robots
| v6 | v7 |
@nuxtjs/sitemap
| v8 | v9 |
nuxt-og-image
| v6 | v7 |
nuxt-schema-org
| v6 | v7 |
nuxt-seo-utils
| v8 | v9 |
nuxt-link-checker
| v5 | v6 |
nuxt-ai-ready
| not bundled | v3 |
nuxt-skew-protection
| not bundled | v2 |
👉 Changelog
🚨 Breaking Changes
- Bundle AI Ready and Skew Protection by default - by @harlan-zw in #643 (5896e)
- Remove deprecated v5 content and module list APIs - by @harlan-zw in #670 (87876)
- nuxt-seo: Make nuxtseo: false skip the bundled modules - by @harlan-zw in #634 (387fc)
🚀 Features
- Ship an agent skill in the package - by @harlan-zw in #631 (f7aad)
- Add brand marks and hand-drawn module icons - by @harlan-zw in #647 (d48fe)
- Require Nuxt 4.6 and isolate optional DevTools - by @harlan-zw in #645 (2108a)
- seo:
- Report development setup checks - by @harlan-zw in #644 (34469)
- Require an app secret when OG Image signs URLs - by @harlan-zw in #669 (d652f)
- shared:
- Add a plate cut for README headings - by @harlan-zw in #648 (09760)
- Draw the Pro mark climb in a gradient - by @harlan-zw in #649 (1540c)
🐞 Bug Fixes
- Accept Nuxt 5 prereleases in the compatibility range - by @harlan-zw in #677 (11328)
- bench:
- Configure the fixture signing key - by @harlan-zw in #665 (b94c7)
- ci:
- Fail docs dispatch loudly and fire it only on main - by @harlan-zw in #630 (419c3)
- Measure runtime output with Nuxt Module Size Analyzer - by @harlan-zw in #654 (26353)
- devtools:
- Release the optional host with layer 6 - by @harlan-zw in #664 (cdbb8)
- nuxt-seo:
- Fail on unsupported Nuxt and submodule versions - by @harlan-zw in #633 (60540)
- Stop the build on an unsupported Nuxt - by @harlan-zw in #673 (c2e02)
- Require Nuxt 4.6.1 - by @harlan-zw in #674 (2c64b)
- seo:
- Inherit public AI discovery defaults - by @harlan-zw in #666 (95a6c)
- shared:
- Point standalone modules at the harlan-zw org - by @harlan-zw and Harlan GitHub Agent in #628 (381bd)
- skills:
- Align metadata with the Agent Skills spec - by @harlan-zw in #662 (33297)
View changes on GitHub
📦 Module Releases
| Module | GitHub release | Release notes |
|---|---|---|
| Nuxt Robots | Nuxt Robots v7.0.0 | Nuxt Robots v7 release notes |
| Nuxt Sitemap | Nuxt Sitemap v9.0.0 | Nuxt Sitemap v9 release notes |
| Nuxt OG Image | Nuxt OG Image v7.0.0 | Nuxt OG Image v7 release notes |
| Nuxt Schema.org | Nuxt Schema.org v7.0.0 | Nuxt Schema.org v7 release notes |
| Nuxt Link Checker | Nuxt Link Checker v6.0.0 | Nuxt Link Checker v6 release notes |
| Nuxt SEO Utils | Nuxt SEO Utils v9.0.0 | Nuxt SEO Utils v9 release notes |
| Nuxt Site Config | Nuxt Site Config v5.0.0 | Nuxt Site Config v5 release notes |
| Nuxt Skew Protection | Nuxt Skew Protection v2.0.0 | Nuxt Skew Protection v2 release notes |
| Nuxt AI Ready | Nuxt AI Ready v3.0.0 | Nuxt AI Ready v3 release notes |
❤️ Contributors
- @harlan-zw
- @danielroe
- @0xgdr
- @yves-riot
- @Cypher-Aura-19
- @rayblair06
- @nsturis
- @lprnmns
- @pengzh1
- @Noumenon-ai
🧠 Agent Skill
If you use an AI agent, install the @nuxtjs/seo Skill on skilld.dev with this command:
npx skilld install harlan-zw/nuxt-seo/nuxtjs-seo