Nuxt SEO Utils v9.0.0

Introduction

Nuxt SEO Utils v9 supports Nuxt 4.6 and Nuxt 5. It ships in Nuxt SEO v6.

This release removes support for Nuxt 3, Nuxt 4 before 4.6, and Unhead v2. Sharp is now an optional install. The module also warns when indexable pages render only on the client. The new seo.redirects option serves redirects and 410 responses for old URLs.

Check the breaking changes before you upgrade. Then follow the migration steps.

Some features shipped in 8.x minor releases: Nuxt config head validation and automaticTwitterTags in 8.5.0, then route rule meta priority and the Agent Skill in 8.6.0. This page lists only the changes after v8.6.1.

Client Rendering Warnings

If SSR is off for a page, crawlers and agents that skip JavaScript can miss its content. v9 warns about these pages during nuxt dev and nuxt build. (#170)

The check reads the global ssr option and the final route rules. It skips API, proxy, redirect, and non-HTML routes. It also skips routes with robots: false and sites with site.indexable: false.

Each warning names the route and shows two fixes. For public pages, turn SSR back on:

nuxt.config.ts
export default defineNuxtConfig({
  ssr: true,
  routeRules: { '/app/**': { ssr: true } },
})

For private app pages, keep client rendering and stop indexing with Nuxt Robots:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/robots'],
  routeRules: { '/app/**': { robots: false } },
})

Redirects and Gone URLs

List the URLs you moved or deleted in seo.redirects. Each entry records the date you added it. (#176)

nuxt.config.ts
export default defineNuxtConfig({
  seo: {
    redirects: {
      '/blog/old-post': { to: '/blog/new-post', addedAt: '2026-10-13' },
      '/spring-sale': { statusCode: 410, addedAt: '2026-10-13' },
    },
  },
})

A moved URL gets a 301, or a 308. A gone URL gets your error page with a 410 or 404 status. The build flattens redirect chains and stops on loops.

No entry expires on its own. By default, nuxt dev and nuxt build list an entry for review after 365 days. See Redirects and Gone URLs.

Typed Runtime Entry

Import the composables and their option types from #seo-utils/app. (#161)

import type { BreadcrumbItemProps, ShareLinksOptions } from '#seo-utils/app'
import { useBreadcrumbItems, useFallbackTitle, useShareLinks } from '#seo-utils/app'

The composables stay auto-imported. You need the explicit import only in files that skip auto-imports.

Performance

  • Sharp is optional. Only the nuxt-seo-utils icons CLI uses Sharp, so the module no longer installs it. A clean Linux x64 install has 571 unique packages instead of 575. (#168)
  • Fewer allocations for derived tags. The module now syncs derived og:image, twitter:image, and og:url tags without a temporary array per tag. In a local 31-tag helper benchmark, median CPU fell from 2.08 to 1.09 µs per call. Sampled allocation fell from 3,042 to 890 bytes per call. These figures measure the helper alone. They exclude the rest of the SSR request. (#169)

Bug Fixes

  • Disabled Nuxt Schema.org: v8 read schemaOrg.enable, so it missed schemaOrg: { enabled: false }. v9 reads schemaOrg.enabled and loads the no-op Schema.org fallback. (#161)
  • Regex corruption: the handwritten JavaScript minifier could break a regex with an escaped slash. v9 removes that minifier. (#168)

Breaking Changes

Nuxt 4.6, Node 22.22.3, and Unhead 3.4.2

v9 requires Nuxt ^4.6.0 || ^5.0.0. v8 accepted Nuxt 3.16 or later. (#161)

v9 also requires Node ^22.22.3 || ^24.15.0 || >=26.0.0 and Unhead ^3.4.2. Nuxt 4.6 already depends on Unhead ^3.4.2.

package.json
// Before
{ "devDependencies": { "nuxt": "^3.16.0" } }

// After
{ "devDependencies": { "nuxt": "^4.6.0" } }

Unhead v2 Removed

v8 supported Unhead v2 and Unhead v3. On Unhead v2, treeShakeUseSeoMeta logged a warning and skipped the transform. v9 removes the Unhead v2 code path and its warning. (#161)

If your lockfile still resolves @unhead/vue 2, upgrade Nuxt to 4.6. Then remove any @unhead/vue override or pin.

Site Config v5

v9 requires nuxt-site-config 5.0.0 or later. v8 accepted version 3.2 or later. (#161)

Nuxt now loads Site Config as a native module dependency. (#173) If your package.json pins nuxt-site-config, upgrade it.

package.json
// Before
{ "dependencies": { "nuxt-site-config": "^3.2.0" } }

// After
{ "dependencies": { "nuxt-site-config": "^5.0.0" } }

Sharp Is an Optional Peer

v8 installed Sharp as an optional dependency. v9 lists sharp@^0.35.5 as an optional peer, so your package manager does not install it. (#168)

If you use the nuxt-seo-utils icons CLI, install Sharp yourself:

pnpm add -D sharp

Runtime Minification Keeps Dynamic JavaScript

v8 minified inline JavaScript during SSR and in prerendered HTML with a handwritten minifier. v9 leaves that JavaScript unchanged. (#168)

  • Static app.head scripts still get parser-based minification at build time.
  • JSON scripts and inline CSS still get minified.
  • The minify option keeps its shape and its default, { build: true, runtime: false }.

If you need smaller inline JavaScript, move it into app.head or into a bundled file.

#seo-utils Alias Narrowed

v8 mapped #seo-utils to the whole runtime directory. v9 maps only #seo-utils/app. (#161)

Deep paths under #seo-utils/app/ still resolve. Imports from #seo-utils/types, #seo-utils/server/, and #seo-utils/shared/ fail.

// Before
import type { BreadcrumbItemProps } from '#seo-utils/app/composables/useBreadcrumbItems'

// After
import type { BreadcrumbItemProps } from '#seo-utils/app'

DevTools Host Package

The SEO Utils DevTools panel now loads through the optional nuxtseo-devtools-host package. Without it, the tab shows an install button. (#161)

pnpm add -D nuxtseo-devtools-host@^1

Restart your development server after installation. The module loads the host automatically. You do not need to add it to modules. Production builds do not need it.

Migration Steps

  1. Upgrade Node to 22.22.3+, 24.15.0+, or 26+.
  2. Upgrade Nuxt to 4.6 or later: npx nuxt upgrade --force.
  3. If you pin nuxt-site-config, change the range to ^5.0.0.
  4. If you use the nuxt-seo-utils icons CLI, run pnpm add -D sharp.
  5. Replace imports from #seo-utils/types, #seo-utils/server/, or #seo-utils/shared/. Import public composables and types from #seo-utils/app.
  6. If you use the DevTools panel, run pnpm add -D nuxtseo-devtools-host@^1.
  7. Run nuxt dev and read the client rendering and head warnings.

If you use @nuxtjs/seo, upgrade to Nuxt SEO v6 instead. It installs Nuxt SEO Utils v9 for you.

Was this page helpful?