Index of every page on this site: llms.txt

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, OG image requests return a 500 error. Pages still render.
  • 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

Coding-agent upgrade prompt

Copy this prompt into your coding agent. Every module also ships an Agent Skill. Get the Nuxt SEO Skill.

Copy the upgrade prompt
# Upgrade Guide: @nuxtjs/seo v5 to v6

Upgrade @nuxtjs/seo from v5 to v6 in this Nuxt project.
Scan each pattern below; show 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 their `modules` entries and dependencies; keep `aiReady` / `skewProtection` options.
- To disable either, set `aiReady: false` or `skewProtection: false`.
- Cache node_modules/.cache/nuxt-seo/skew-protection in CI; Skew Protection stores assets there.
- 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
If the project uses Nuxt DevTools, add `nuxtseo-devtools-host` as a dev dependency.

## 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/`.
  If an element relied on forced flex layout, add `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; fix [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')`{lang="ts"}
- 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.
  If you need its old overrides, add `_priority: SiteConfigPriority.runtime`.
- 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.

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.

With future.compatibilityVersion: 5

If you set future.compatibilityVersion: 5 and app.config.ts calls defineAppConfig(), you need @nuxtjs/sitemap 9.0.3 or later and nuxt-seo-utils 9.0.1 or later. Earlier v6 releases fail with this error:

ERROR  defineAppConfig is not defined

Sitemap fails the build. SEO Utils with redirectToCanonicalSiteUrl builds, but the server fails when it starts. Refresh your lockfile so it resolves the fixed versions.

If you cannot upgrade yet, turn Nitro auto-imports back on:

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    nitroAutoImports: true,
  },
})

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.1` (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.1"
  }
}

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 OG image requests return a 500 error. Pages still render.

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?