---
title: "v4 to v5"
description: "Migrate from Nuxt SEO v4 to v5."
canonical_url: "https://nuxtseo.com/docs/nuxt-seo/migration-guide/v4-to-v5"
last_updated: "2026-05-06T18:48:10.616Z"
---

## Introduction

Nuxt SEO v5 bumps every sub-module to a new major version (except OG Image, which stays on v6). For the full list of changes, see the [v5 release notes](/docs/nuxt-seo/releases/v5).

<table>
<thead>
  <tr>
    <th>
      Module
    </th>
    
    <th>
      v4
    </th>
    
    <th>
      v5
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        nuxt-site-config
      </code>
    </td>
    
    <td>
      v3
    </td>
    
    <td>
      <a href="https://github.com/harlan-zw/nuxt-site-config/releases/tag/v4.0.0" rel="nofollow">
        <strong>
          v4
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        nuxt-seo-utils
      </code>
    </td>
    
    <td>
      v7
    </td>
    
    <td>
      <a href="https://github.com/harlan-zw/nuxt-seo-utils/releases/tag/v8.0.0" rel="nofollow">
        <strong>
          v8
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @nuxtjs/sitemap
      </code>
    </td>
    
    <td>
      v7
    </td>
    
    <td>
      <a href="https://github.com/nuxt-modules/sitemap/releases/tag/v8.0.0" rel="nofollow">
        <strong>
          v8
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @nuxtjs/robots
      </code>
    </td>
    
    <td>
      v5
    </td>
    
    <td>
      <a href="https://github.com/nuxt-modules/robots/releases/tag/v6.0.0" rel="nofollow">
        <strong>
          v6
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        nuxt-schema-org
      </code>
    </td>
    
    <td>
      v5
    </td>
    
    <td>
      <a href="https://github.com/harlan-zw/nuxt-schema-org/releases/tag/v6.0.0" rel="nofollow">
        <strong>
          v6
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        nuxt-link-checker
      </code>
    </td>
    
    <td>
      v4
    </td>
    
    <td>
      <a href="https://github.com/harlan-zw/nuxt-link-checker/releases/tag/v5.0.0" rel="nofollow">
        <strong>
          v5
        </strong>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        nuxt-og-image
      </code>
    </td>
    
    <td>
      v6
    </td>
    
    <td>
      <a href="https://github.com/nuxt-modules/og-image/releases/tag/v6.2.0" rel="nofollow">
        v6.2.0
      </a>
    </td>
  </tr>
</tbody>
</table>

## Support

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

- [Jump in the Discord](https://discord.com/invite/5jDAMswWwX)
- [Make a GitHub issue](https://github.com/harlan-zw/nuxt-seo/issues)

## Step 1: Update Site Config

Site Config v4 is the most impactful change because every module depends on it.

### Set `site.name` explicitly

Site name is no longer inferred from `package.json` or the directory name. Add it to your `nuxt.config`:

```ts
export default defineNuxtConfig({
  site: {
    name: 'My Site',
  },
})
```

### Remove legacy runtime config keys

The `siteUrl`, `siteName`, and `siteDescription` runtime config keys are no longer supported. Migrate to the `site` object:

```diff
export default defineNuxtConfig({
- runtimeConfig: {
-   public: {
-     siteUrl: 'https://example.com',
-     siteName: 'My Site',
-   }
- },
+ site: {
+   url: 'https://example.com',
+   name: 'My Site',
+ },
})
```

### Update server-side APIs

- `useSiteConfig()` → `getSiteConfig(event)`
- `getSiteIndexable()` → `getSiteConfig(event).indexable`
- `SiteConfig` type → `SiteConfigResolved`
- `#internal/nuxt-site-config` import → use named imports from `nuxt-site-config`

## Step 2: Update Content v3 Collections

If you use `@nuxt/content` v3, the collection API has changed significantly.

### Replace `asSeoCollection()`

The `asSeoCollection()` wrapper from `@nuxtjs/seo/content` is deprecated. Instead, import each module's `defineXxxSchema()` function and compose them in your collection schema directly.

```diff [content.config.ts]
- import { asSeoCollection } from '@nuxtjs/seo/content'
+ import { defineRobotsSchema } from '@nuxtjs/robots/content'
+ import { defineSitemapSchema } from '@nuxtjs/sitemap/content'
+ import { defineOgImageSchema } from 'nuxt-og-image/content'
+ import { defineSchemaOrgSchema } from 'nuxt-schema-org/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(),
+       }),
+     },
    ),
  },
})
```

You only need to include schemas for the modules you use. For example, if you only use sitemap and robots:

```ts [content.config.ts]
import { defineCollection, defineContentConfig } from '@nuxt/content'
import { defineRobotsSchema } from '@nuxtjs/robots/content'
import { defineSitemapSchema } from '@nuxtjs/sitemap/content'
import { z } from 'zod'

export default defineContentConfig({
  collections: {
    content: defineCollection({
      type: 'page',
      source: '**/*.md',
      schema: z.object({
        robots: defineRobotsSchema(),
        sitemap: defineSitemapSchema(),
      }),
    }),
  },
})
```

### Replace individual `asXxxCollection()` functions

The individual module collection wrappers are also deprecated:

<table>
<thead>
  <tr>
    <th>
      Old
    </th>
    
    <th>
      New
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          asSeoCollection
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      Compose individual schemas (see above)
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          asRobotsCollection
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          defineRobotsSchema
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          asSitemapCollection
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          defineSitemapSchema
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          asOgImageCollection
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          defineOgImageSchema
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          asSchemaOrgCollection
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="s0YkB">
          defineSchemaOrgSchema
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
</tbody>
</table>

### Ensure correct module order

`@nuxtjs/seo` must be loaded before `@nuxt/content` in your modules array:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/seo',
    '@nuxt/content', // Must be after @nuxtjs/seo
  ],
})
```

## Step 3: Update Sitemap Config

### `definePageMeta` sitemap options

Sitemap v8 lets you configure sitemap options directly in `definePageMeta`. If you were using route rules or other workarounds for per-page sitemap config, you can simplify:

```vue
<script setup lang="ts">
definePageMeta({
  sitemap: {
    changefreq: 'daily',
    priority: 0.8,
  },
})
</script>
```

### i18n multi-sitemap auto-expansion

Custom sitemaps with `includeAppSources: true` are now automatically expanded per locale. You no longer need to manually define a sitemap per locale:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  sitemap: {
    sitemaps: {
      // Automatically expanded to "en-pages", "fr-pages", etc.
      pages: { includeAppSources: true },
    },
  },
})
```

## Step 4: Verify

Run your dev server and check for any warnings or errors. The debug production endpoints can help verify configuration:

- Robots: `/__robots__/debug-production.json`
- Sitemap: `/__sitemap__/debug-production.json`
- SEO Utils: `/__nuxt-seo-utils`
