v4 to v5
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.
| Module | v4 | v5 |
|---|---|---|
nuxt-site-config | v3 | v4 |
nuxt-seo-utils | v7 | v8 |
@nuxtjs/sitemap | v7 | v8 |
@nuxtjs/robots | v5 | v6 |
nuxt-schema-org | v5 | v6 |
nuxt-link-checker | v4 | v5 |
nuxt-og-image | v6 | v6.2.0 |
Support
If you get stuck with the migration or have post-migration bugs, please get in touch.
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:
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:
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).indexableSiteConfigtype →SiteConfigResolved#internal/nuxt-site-configimport → use named imports fromnuxt-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.
- 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(),
+ }),
+ },
),
},
})If you installed only @nuxtjs/seo, import all four defineXxxSchema() functions from @nuxtjs/seo/content. Under pnpm, the individual module paths do not resolve from your app:
import { defineOgImageSchema, defineRobotsSchema, defineSchemaOrgSchema, defineSitemapSchema } from '@nuxtjs/seo/content'You only need to include schemas for the modules you use. For example, if you only use sitemap and robots:
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:
| Old | New |
|---|---|
asSeoCollection() | Compose individual schemas (see above) |
asRobotsCollection() | defineRobotsSchema() |
asSitemapCollection() | defineSitemapSchema() |
asOgImageCollection() | defineOgImageSchema() |
asSchemaOrgCollection() | defineSchemaOrgSchema() |
Install zod
The schema functions need zod as a direct dependency of your app. If your content.config.ts fails with Cannot find package 'zod', install it:
npx nypm add zodStep 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:
<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:
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