---
title: "v5 to v6"
description: "Migrate Nuxt OG Image v5 to Nuxt OG Image v6."
canonical_url: "https://nuxtseo.com/docs/og-image/migration-guide/v6"
last_updated: "2026-05-06T18:44:59.912Z"
---

## Quick Migration

Run the migration CLI to automate most changes:

```bash
# Rename components and migrate API calls
npx nuxt-og-image migrate v6

# Preview changes without applying (dry run)
npx nuxt-og-image migrate v6 --dry-run
```

This will:

- Rename `components/OgImage/*.vue` to include renderer suffix (defaults to `.takumi.vue`)
- Migrate `defineOgImageComponent()` calls to `defineOgImage()`

## What's New

- **Takumi as recommended renderer** - [Takumi](https://takumi.kane.tw) is 2-10x faster than Satori with the same feature set
- **First-class CSS support** - Tailwind v4, [UnoCSS](https://unocss.dev), CSS variables, and Nuxt UI v3 colors all work
- **Redesigned DevTools** - better debugging, Bluesky social card support, more accessible interface
- **Multiple OG images per page** - different dimensions for different platforms
- **@nuxt/fonts integration** - custom fonts work if you install `@nuxt/fonts`
- **Smarter caching** - CDN-friendly Cloudinary-style URLs, cleaner cache keys

## High Impact Changes

Changes that affect most users upgrading to v6.

### Install Renderer Dependencies

Renderer dependencies (satori, resvg, takumi, playwright) are no longer bundled. You must install them explicitly based on your renderer and runtime.

See [PR #415](https://github.com/nuxt-modules/og-image/pull/415).

**Takumi (recommended):**

```bash
# Node.js
npm i @takumi-rs/core

# Edge runtimes
npm i @takumi-rs/wasm
```

**Satori:**

```bash
# Node.js
npm i satori @resvg/resvg-js

# Edge runtimes (Cloudflare, Vercel Edge, etc.)
npm i satori @resvg/resvg-wasm
```

**Browser:**

```bash
npm i playwright-core
```

Running `nuxi dev` will prompt you to install missing dependencies automatically.

### Component Renderer Suffix Required

OG Image components must now include a renderer suffix in their filename.

See [PR #433](https://github.com/nuxt-modules/og-image/pull/433).

```bash
# Before (no longer works)
components/OgImage/MyTemplate.vue

# After
components/OgImage/MyTemplate.satori.vue   # for Satori renderer
components/OgImage/MyTemplate.takumi.vue   # for Takumi renderer
components/OgImage/MyTemplate.browser.vue  # for Browser renderer
```

This change enables:

- Automatic renderer detection from filename
- Multiple renderer variants of the same component
- Tree-shaking of unused renderer code

The CLI migration command will rename your components automatically:

```bash
npx nuxt-og-image migrate v6
```

#### Multiple Renderers Per Component

You can now create renderer-specific variants of the same component:

```bash
components/OgImage/
  MyTemplate.satori.vue    # Satori version
  MyTemplate.takumi.vue    # Takumi version (faster)
```

When calling `defineOgImage('MyTemplate')`, the module uses the first registered variant. To select a specific renderer, use dot notation (`'MyTemplate.takumi'`) or PascalCase (`'MyTemplateTakumi'`).

<note>

The module removed the `defaults.renderer` config option and `renderer` option on `defineOgImage()`. The component filename suffix always determines the renderer.

</note>

### Community Templates Must Be Ejected

Community templates (like `NuxtSeo`, `Brutalist`, `SimpleBlog`, etc.) are no longer bundled with production builds. If you're using a community template, you must eject it before building.

See [PR #426](https://github.com/nuxt-modules/og-image/pull/426).

```bash
# List available templates
npx nuxt-og-image list

# Eject a specific template
npx nuxt-og-image eject NuxtSeo
```

This copies the template to your `components/OgImage/` directory where it will be included in your build.

**In development**, community templates continue to work without ejecting - they're loaded directly from the module.

**In production**, only ejected templates are available. If you reference a community template that hasn't been ejected, you'll get an error.

After ejecting, you can customize the template as needed. The ejected components are yours to modify.

## Medium Impact Changes

Changes that affect users with specific configurations.

### Fonts: @nuxt/fonts Integration

The module removed the `ogImage.fonts` config. `@nuxt/fonts` now handles fonts - install the module and your fonts work in OG images with no extra configuration.

See [PR #432](https://github.com/nuxt-modules/og-image/pull/432).

The module bundles Inter (400 and 700) as a zero-config fallback, so if you were only using Inter you can delete your font configuration entirely.

```diff
// Before
export default defineNuxtConfig({
  ogImage: {
-   fonts: ['Inter:400', 'Inter:700']
  }
})

// After (Inter only) — remove the config, it works by default

// After (custom fonts) — just install @nuxt/fonts
export default defineNuxtConfig({
+ modules: ['@nuxt/fonts', 'nuxt-og-image'],
+ fonts: {
+   families: [
+     { name: 'Roboto', weights: [400, 700], global: true }
+   ]
+ }
})
```

Install @nuxt/fonts:

```bash
npx nuxi module add @nuxt/fonts
```

### `<OgImage>` and `<OgImageScreenshot>` Components Removed

The module removed the `<OgImage>` and `<OgImageScreenshot>` Vue components. Use the equivalent composables instead:

```diff
- <template>
-   <OgImage />
- </template>

+ <script setup>
+ defineOgImage()
+ </script>
```

```diff
- <template>
-   <OgImageScreenshot />
- </template>

+ <script setup>
+ defineOgImageScreenshot()
+ </script>
```

The migration CLI handles this automatically.

### `componentOptions` Config Removed

The module removed the `ogImage.componentOptions` config option since there are no longer any components to configure.

```diff
export default defineNuxtConfig({
  ogImage: {
-   componentOptions: { global: true },
  }
})
```

### Object Syntax with `url` Replaced by `useSeoMeta`

The `defineOgImage()` object syntax for pre-prepared images is no longer needed. Use `useSeoMeta()` directly instead - it works without any interference from the module.

```diff
- defineOgImage({ url: '/my-image.png', width: 1200, height: 600, alt: 'My Image' })
+ useSeoMeta({ ogImage: '/my-image.png', ogImageWidth: 1200, ogImageHeight: 600, ogImageAlt: 'My Image' })
```

The migration CLI handles this automatically.

### `defineOgImageComponent` Deprecated

The `defineOgImageComponent()` composable is deprecated. Use `defineOgImage()` with the component name as the first argument.

See [PR #433](https://github.com/nuxt-modules/og-image/pull/433).

```diff
- defineOgImageComponent('NuxtSeo', { title: 'Hello' })
+ defineOgImage('NuxtSeo', { title: 'Hello' })
```

The API is identical - remove "Component" from the function name. The migration CLI handles this automatically.

### First-Class CSS Support

Build-time CSS processing replaces the UnoCSS runtime transformer. Tailwind v4, UnoCSS, CSS variables, and Nuxt UI v3 colors all work by default with zero configuration.

See [PR #430](https://github.com/nuxt-modules/og-image/pull/430).

**What this means:**

- **Tailwind v4** - build-time class extraction with Tailwind's CSS engine, `@theme` values work
- **UnoCSS** - full UnoCSS support
- **CSS Variables** - use your app's CSS custom properties directly in OG image templates
- **Nuxt UI v3** - the module automatically resolves semantic colors (`primary`, `secondary`, etc.)

#### Native Tailwind v4 Support

Nuxt OG Image has native Tailwind v4 support. The module extracts classes from your OG components at build time and compiles them with Tailwind's CSS engine. Zero-config - the module auto-detects your Tailwind setup whether you're using `@nuxtjs/tailwindcss` or Tailwind v4 with the [Vite](https://vite.dev) plugin.

#### Theme Customizations

The module automatically resolves custom theme values defined in `@theme`:

```css [assets/css/main.css]
@import "tailwindcss";

@theme {
  --color-brand: #ff6600;
  --font-heading: "Inter", sans-serif;
}
```

```vue [components/OgImage/MyTemplate.satori.vue]
<template>
  <div class="bg-brand font-heading">
    Works!
  </div>
</template>
```

#### Nuxt UI v3 Color Support

When using `@nuxt/ui` v3, the module automatically resolves semantic colors (`primary`, `secondary`, etc.) from your `app.config.ts`:

```ts [app.config.ts]
export default defineAppConfig({
  ui: {
    colors: {
      primary: 'indigo',
      secondary: 'violet'
    }
  }
})
```

```vue [components/OgImage/MyTemplate.satori.vue]
<template>
  <div class="bg-primary-500 text-secondary-200">
    Nuxt UI colors!
  </div>
</template>
```

## Low Impact Changes

Changes that affect users with specific edge cases or deprecated configurations.

### Cache Key Changes

Query parameters are no longer included in cache keys. Previously, `/page?foo=bar` and `/page?baz=qux` would generate separate cached images. Now they share the same cache.

See [PR #427](https://github.com/nuxt-modules/og-image/pull/427).

All image options are encoded in the URL path, so query parameters on the OG image URL have no effect. In v5, query parameter overrides (e.g. `?title=Override`) worked in production when URL signing was disabled. In v6, query param overrides are only available in dev and prerender modes. Use `defineOgImage` props to pass dynamic values instead.

#### Cache Version Control

New `cacheVersion` option controls cache key namespacing:

```ts
export default defineNuxtConfig({
  ogImage: {
    // Default: module version (cache invalidates on upgrade)
    cacheVersion: false // disable versioning entirely
  }
})
```

### URL Path Changes

OG Image URLs have been shortened and restructured. This only affects you if you have hardcoded OG image URLs.

See [PR #305](https://github.com/nuxt-modules/og-image/pull/305).

<table>
<thead>
  <tr>
    <th>
      v5
    </th>
    
    <th>
      v6
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        /__og-image__/image/
      </code>
    </td>
    
    <td>
      <code>
        /_og/d/
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /__og-image__/static/
      </code>
    </td>
    
    <td>
      <code>
        /_og/s/
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /__og-image__/font/
      </code>
    </td>
    
    <td>
      Removed (fonts served directly from <code>
        /_fonts/
      </code>
      
       via @nuxt/fonts)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /__og-image__/debug.json
      </code>
    </td>
    
    <td>
      <code>
        /_og/debug.json
      </code>
    </td>
  </tr>
</tbody>
</table>

#### New Cloudinary-style URL Encoding

OG Image URLs now encode all options directly in the URL path using a Cloudinary/IPX-style format. This enables automatic CDN caching since the same options always produce the same URL.

**v5 format:**

```txt
/_og/d/satori/og.png?width=1200&title=Hello%20World
```

**v6 format:**

```txt
/_og/s/w_1200,title_Hello+World,p_Ii9zYXRvcmki.png
```

Key changes:

- Options are comma-separated in the URL path (not query params)
- Known params use short aliases: `w` (width), `h` (height), `c` (component), `k` (key), etc.
- Component props are flattened to top level: `title_Hello+World`
- Complex values (fonts, query params) are base64 encoded
- The module encodes the page path as `p_<base64>`

#### Hash Mode for Long URLs (Prerendered Only)

When prerendering, if the encoded URL path exceeds 200 characters (filesystem limit is 255), the module automatically switches to hash mode:

```txt
/_og/s/o_1whacq.png
```

This typically happens with:

- Long component props (e.g., lengthy descriptions)
- Multiple custom fonts with base64-encoded configurations
- Complex query parameters

The hash is deterministic - the same options always produce the same hash. The module caches options by hash during prerendering for lookup when rendering the image. Hash mode URLs are not supported at runtime.

If you have any hardcoded references to the old URL format, update them to use the return value of `defineOgImage()` which now returns an array of generated paths:

```ts
const [ogImageUrl] = defineOgImage('NuxtSeo', { title: 'About Us' })
```

#### Long Runtime URLs

Because all options are now self-contained in the URL, runtime URLs can become long when passing many props. In v5, the URL was short because the server re-fetched the page to discover the payload - v6 avoids this round trip for stability and caching, at the cost of longer URLs.

<callout icon="i-heroicons-light-bulb">

See the [Performance](/docs/og-image/guides/performance) guide for strategies to reduce URL size, optimise component rendering, and configure caching for production.

</callout>

### Nuxt Content v2 Support Removed

The module no longer supports Nuxt Content v2. If you're using `@nuxt/content`, you must upgrade to v3 or later.

See [PR #410](https://github.com/nuxt-modules/og-image/pull/410).

The module removed the automatic `ogImage` frontmatter handling for Content v2. Use `defineOgImage()` in your page components instead.

```ts
// pages/[...slug].vue
defineOgImage('NuxtSeo', { title: 'My Page' })
```

### Config Options Removed

See [PR #410](https://github.com/nuxt-modules/og-image/pull/410).

#### `strictNuxtContentPaths` Removed

This option was deprecated and has no effect in Nuxt Content v3. Remove it from your config:

```diff
export default defineNuxtConfig({
  ogImage: {
-   strictNuxtContentPaths: true,
  }
})
```

#### Chromium Renderer Renamed to Browser

The `chromium` renderer has been renamed to `browser` for clarity. Update your component suffixes and configuration:

**Component files:**

```bash
# Rename component files
mv MyTemplate.chromium.vue MyTemplate.browser.vue
```

**Configuration:**

```diff
export default defineNuxtConfig({
  ogImage: {
    compatibility: {
      runtime: {
-       chromium: 'playwright',
+       browser: 'playwright',
      }
    }
  }
})
```

#### Browser `node` Binding Removed

The module removed the deprecated `browser: 'node'` compatibility option. Use `'playwright'` instead:

```diff
export default defineNuxtConfig({
  ogImage: {
    compatibility: {
      runtime: {
-       browser: 'node',
+       browser: 'playwright',
      }
    }
  }
})
```

#### Cloudflare Browser Rendering Support

You can now use Cloudflare Browser Rendering for runtime screenshots on Cloudflare Workers/Pages:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  ogImage: {
    browser: {
      provider: 'cloudflare',
      binding: 'BROWSER'
    }
  }
})
```

See the [Browser Renderer](/docs/og-image/renderers/browser#cloudflare-browser-rendering) docs for setup instructions.

### Import Path Changes

See [PR #410](https://github.com/nuxt-modules/og-image/pull/410).

#### `#nuxt-og-image-utils` Alias Removed

If you were importing from this legacy alias, update your imports:

```diff
- import { ... } from '#nuxt-og-image-utils'
+ import { ... } from '#og-image/shared'
```

#### `useOgImageRuntimeConfig` Import Path

The module removed the deprecated stub export from `#og-image/shared`. Import from the correct path:

```diff
- import { useOgImageRuntimeConfig } from '#og-image/shared'
+ import { useOgImageRuntimeConfig } from '#og-image/app/utils'
```

### Sharp JPEG Errors

Previously, if Sharp failed to load for JPEG rendering, it would log an error and fall back to PNG silently. Now it throws an error.

See [PR #410](https://github.com/nuxt-modules/og-image/pull/410).

Ensure you properly install Sharp and your runtime supports it if you're using JPEG output. See the [Renderers](/docs/og-image/renderers) guide for details.
