Introduction

Nuxt SEO v6 moves every bundled module to a new major version. AI Ready and Skew Protection join the bundle. For the full list of changes, see the v6 release notes.

Key takeaways
  • First upgrade to Nuxt 4.6.1 or later, and Node 22.22.3+, 24.15.0+, or 26+. Nuxt 3 sites stay on Nuxt SEO v5.
  • Remove nuxt-ai-ready and nuxt-skew-protection from modules. @nuxtjs/seo installs them.
  • If OG Image signs URLs, set NUXT_APP_SECRET in production. Without it, production pages return a 500 error.
  • Update or remove each bundled module that you pinned. An older pinned module now fails the build.
  • Add nuxtseo-devtools-host as a development dependency to keep the SEO DevTools panels.
Modulev5v6
nuxt-site-configv4v5
@nuxtjs/robotsv6v7
@nuxtjs/sitemapv8v9
nuxt-og-imagev6v7
nuxt-schema-orgv6v7
nuxt-seo-utilsv8v9
nuxt-link-checkerv5v6
nuxt-ai-readynot bundledv3
nuxt-skew-protectionnot bundledv2
Using an AI agent? The release notes include an upgrade prompt for your coding agent. Every module now ships an Agent Skill. Get the @nuxtjs/seo Skill on skilld.dev/gh/harlan-zw/nuxt-seo.

Support

If you get stuck with the migration or have post-migration bugs, please get in touch.

Step 1: Update Nuxt and Node

Nuxt 4.6.1 or later

Nuxt SEO v6 requires Nuxt ^4.6.1 || ^5.0.0. Nuxt SEO v6 does not support Nuxt 3. If your site runs Nuxt 3, stay on Nuxt SEO v5.

Upgrade Nuxt before you upgrade Nuxt SEO:

npx nuxt upgrade

Node 22.22.3+, 24.15.0+, or 26+

Node must match ^22.22.3 || ^24.15.0 || >=26.0.0. Check engines in your package.json, your .nvmrc, and the Node versions in CI and in your deployment.

Step 2: Update Nuxt SEO

npx nypm add @nuxtjs/seo@^6

Remove AI Ready and Skew Protection from modules

@nuxtjs/seo now installs AI Ready and Skew Protection. Remove both from your modules array and from your dependencies. Keep your options under the aiReady and skewProtection keys.

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

To turn either module off, set its key to false:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/seo'],
  aiReady: false,
  skewProtection: false,
})

If you keep both modules, your site gets new public output:

  • AI Ready serves /llms.txt and a Markdown version of every page. A prerender also writes /llms-full.txt. AI Ready publishes Agent Skills from public/skills/<name>/SKILL.md. It generates an API catalog when you configure an MCP server and a site URL.
  • Skew Protection keeps the assets of earlier builds after a deploy. Nuxt SEO sets updateStrategy: 'polling' and cookie: false, so it polls Nuxt's app manifest and sets no version cookie.
Skew Protection stores old assets in node_modules/.cache/nuxt-seo/skew-protection by default. If your CI starts from a clean checkout, cache that directory between builds, or set skewProtection.storage. Otherwise each deploy loses the assets of earlier builds.

If a server handler calls isClientOutdated(), set skewProtection.cookie to a cookie config object.

If you already used Skew Protection

Skew Protection v2 changes these defaults:

  • An unset updateStrategy now means hourly polling on every platform. For instant updates, set updateStrategy: 'sse' or 'ws'.
  • experimental.appManifest: false now fails setup.
  • The default storage driver is fs-lite. An explicit driver: 'fs' still works.
  • With multiTab: true, tabs share one push connection. To keep one connection per tab, set multiTab: false or connectionTracking: true.

If you already used AI Ready

AI Ready v3 negotiates Markdown from the Accept header only. AI bots no longer get Markdown from their User-Agent alone. To restore that, set botNegotiation:

nuxt.config.ts
export default defineNuxtConfig({
  aiReady: {
    botNegotiation: true,
  },
})

AI Ready v3 also drops the better-sqlite3 fallback and uses node:sqlite.

Update pinned module versions

If your package.json pins a bundled module, the pinned copy replaces the bundled one. An older pinned copy now fails the build and names the module:

ERROR  [@nuxtjs/seo] Module `@nuxtjs/sitemap` version (`8.6.1`) does not satisfy `>=9.0.0` (requested by `@nuxtjs/seo`).

Update each pin to the version in the table above, or remove the pin and let @nuxtjs/seo install the module:

package.json
{
  "dependencies": {
    "@nuxtjs/seo": "^6.0.0",
-   "@nuxtjs/sitemap": "^8.6.1"
+   "@nuxtjs/sitemap": "^9.0.0"
  }
}

If you cannot find the pin, run pnpm why <package>. If you use @nuxtjs/i18n, it must be v10 or later.

Install the DevTools host

The SEO DevTools panels now live in an optional package. If you use them, add the host as a development dependency, then restart Nuxt:

npx nypm add -D nuxtseo-devtools-host

If the host is missing, each panel shows an install button.

Check nuxtseo: false

In v5, nuxtseo: false type checked but installed every module anyway. In v6, it installs none of the bundled modules. If your config sets it, remove it to keep the modules. A module that you add to modules yourself still installs.

Step 3: Set NUXT_APP_SECRET for OG Image

OG Image v7 signs image URLs with Nuxt's application 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.

Generate a secret:

npx nuxt-og-image generate-secret

Set it in your deployment environment, and in .env for local runs:

.env
NUXT_APP_SECRET=<your-secret>

Remove the OG Image secret from your config:

nuxt.config.ts
export default defineNuxtConfig({
  ogImage: {
-   security: {
-     secret: process.env.NUXT_OG_IMAGE_SECRET,
-   },
  },
})

NUXT_OG_IMAGE_SECRET still works with a deprecation warning. Signed URLs from OG Image v6 become invalid, so rebuild prerendered pages and purge cached HTML that contains them. Fully static sites do not need a secret.

In development, the setup checks report a missing secret as required.

Other OG Image v7 changes

The OG Image v7 migration guide covers each of these changes:

  • OG Image needs Satori 0.47. Add flex flex-col to elements that depended on the old forced flex layout.
  • OG Image needs Takumi v2 (^2.15.0). Replace takumi.fetchedResources and takumi.persistentImages with takumi.images.
  • Custom fonts need @nuxt/fonts v1. Families used only in OG images need global: true.

Step 4: Update Nuxt Content

Use Nuxt Content v3

Nuxt SEO v6 no longer supports Nuxt Content v2. Upgrade to Nuxt Content v3. See the Nuxt Content guide for the collection setup.

Upgrade to Zod 4

defineRobotsSchema(), defineSitemapSchema(), and defineOgImageSchema() require Zod 4. Upgrade the zod package in your app:

npx nypm add zod@^4

Replace asSeoCollection()

v5 deprecated asSeoCollection(). v6 removes it. Compose the schema helpers in your collection schema:

content.config.ts
import { defineCollection, defineContentConfig } from '@nuxt/content'
- import { asSeoCollection } from '@nuxtjs/seo/content'
+ import { defineOgImageSchema, defineRobotsSchema, defineSchemaOrgSchema, defineSitemapSchema } from '@nuxtjs/seo/content'
+ import { z } from 'zod'

export default defineContentConfig({
  collections: {
    content: defineCollection(
-     asSeoCollection({
-       type: 'page',
-       source: '**/*.md',
-     }),
+     {
+       type: 'page',
+       source: '**/*.md',
+       schema: z.object({
+         robots: defineRobotsSchema(),
+         sitemap: defineSitemapSchema(),
+         ogImage: defineOgImageSchema(),
+         schemaOrg: defineSchemaOrgSchema(),
+       }),
+     },
    ),
  },
})

Step 5: Update Server Code

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:

server/plugins/sitemap.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('sitemap:sources', (ctx) => {
-   const auth = 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.

Update runtime imports

Auto imports do not change. If you import a module's runtime by hand, use the new aliases:

OldNew
#internal/nuxt-robots, #internal/nuxt-simple-robots#robots/server or #robots/app
#schema-org#schema-org/app or #schema-org/server
#seo-utils#seo-utils/app

Step 6: Update Site Config

Site Config v5 changes priority and values:

  • updateSiteConfig() without _priority now ranks below your site key and NUXT_SITE_* variables. Pass _priority: SiteConfigPriority.runtime to keep the old order.
  • indexable is now always a boolean. It defaults to env === 'production'.
  • Module authors: Site Config v5 drops installNuxtSiteConfig(). Declare nuxt-site-config in moduleDependencies.
modules/site.ts
- import { updateSiteConfig } from 'nuxt-site-config-kit'
+ import { SiteConfigPriority, updateSiteConfig } from 'nuxt-site-config-kit'

updateSiteConfig({
  url: 'https://example.com',
+ _priority: SiteConfigPriority.runtime,
})

Step 7: Check Smaller Module Changes

  • Robots: robots.txt files in assets/ or pages/ resolve from srcDir (app/ in Nuxt 4). Move a root assets/robots.txt or pages/robots.txt under app/.
  • Robots: noai and noimageai route rules no longer mark a route as not indexable. A robots:config change 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. Check pages that set both.
  • Sitemap: Sitemap v9 drops nuxt-simple-robots support. Use @nuxtjs/robots v7.
  • Link Checker: Reports show the real status text, and an unreachable link reports status 0.
  • SEO Utils: sharp is an optional peer dependency. Add it as a development dependency to use nuxt-seo-utils icons. Runtime minification no longer rewrites inline JavaScript.

Step 8: Verify

  1. Install dependencies and update the lockfile.
  2. Run npx nuxt typecheck.
  3. Run npx nuxt build. A module version mismatch fails here and names the module.
  4. Run 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.
Was this page helpful?