Run the migration CLI to automate most changes:
# 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:
components/OgImage/*.vue to include renderer suffix (e.g., .satori.vue)defineOgImageComponent() calls to defineOgImage()Breaking: OG Image components must now include a renderer suffix in their filename.
# 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.chromium.vue # for Chromium renderer
This change enables:
The CLI migration command will rename your components automatically:
npx nuxt-og-image migrate v6
You can now create renderer-specific variants of the same component:
components/OgImage/
MyTemplate.satori.vue # Complex version for Satori
MyTemplate.takumi.vue # Simplified version for Takumi (faster)
When calling defineOgImage('MyTemplate', ...), the module selects the variant matching the configured renderer.
defineOgImageComponent DeprecatedThe defineOgImageComponent() composable is deprecated. Use defineOgImage() with the component name as the first argument:
- defineOgImageComponent('NuxtSeo', { title: 'Hello' }, { fonts: ['Inter'] })
+ defineOgImage('NuxtSeo', { title: 'Hello' }, { fonts: ['Inter'] })
The API is identical - just remove "Component" from the function name. The migration CLI handles this automatically.
Nuxt Content v2 is no longer supported. If you're using @nuxt/content, you must upgrade to v3 or later.
The automatic ogImage frontmatter handling for Content v2 has been removed. Use defineOgImage() in your page components instead.
// pages/[...slug].vue
defineOgImage({
component: 'NuxtSeo',
// ...
})
strictNuxtContentPaths RemovedThis option was deprecated and has no effect in Nuxt Content v3. Remove it from your config:
export default defineNuxtConfig({
ogImage: {
- strictNuxtContentPaths: true,
}
})
node Binding RemovedThe deprecated chromium: 'node' compatibility option has been removed. Use 'playwright' instead:
export default defineNuxtConfig({
ogImage: {
compatibility: {
runtime: {
- chromium: 'node',
+ chromium: 'playwright',
}
}
}
})
#nuxt-og-image-utils Alias RemovedIf you were importing from this legacy alias, update your imports:
- import { ... } from '#nuxt-og-image-utils'
+ import { ... } from '#og-image/shared'
useOgImageRuntimeConfig Import PathThe deprecated stub export from #og-image/shared has been removed. Import from the correct path:
- import { useOgImageRuntimeConfig } from '#og-image/shared'
+ import { useOgImageRuntimeConfig } from '#og-image/app/utils'
OG Image URLs have been shortened:
| v5 | v6 |
|---|---|
/__og-image__/image/ | /_og/d/ |
/__og-image__/static/ | /_og/s/ |
/__og-image__/font/ | /_og/f/ |
/__og-image__/debug.json | /_og/debug.json |
Breaking: 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:
/_og/d/satori/og.png?width=1200&title=Hello%20World
v6 format:
/_og/s/w_1200,title_Hello+World,p_Ii9zYXRvcmki.png
Key changes:
w (width), h (height), c (component), k (key), etc.title_Hello+Worldp_<base64>When prerendering, if the encoded URL path exceeds 200 characters (filesystem limit is 255), the module automatically switches to hash mode:
/_og/s/o_1whacq.png
This typically happens with:
The hash is deterministic - the same options always produce the same hash. Options are cached 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 getOgImagePath() instead:
import { getOgImagePath } from '#og-image/app/utils'
const ogImageUrl = getOgImagePath('/about', {
props: { title: 'About Us' }
})
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:
# 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.
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.
If your OG images depend on query parameters, enable them explicitly:
export default defineNuxtConfig({
ogImage: {
cacheQueryParams: true // restore v5 behavior
}
})
Or set a custom cache key per image:
defineOgImage({
cacheKey: `my-page-${route.query.variant}`
})
New cacheVersion option controls cache key namespacing:
export default defineNuxtConfig({
ogImage: {
// Default: module version (cache invalidates on upgrade)
cacheVersion: false // disable versioning entirely
}
})
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.
Ensure Sharp is properly installed and your runtime supports it if you're using JPEG output. See the Renderers guide for details.
The UnoCSS runtime transformer that processed Tailwind/UnoCSS classes at runtime has been removed. Utility classes are now processed at build time with native Tailwind v4 support.
What this means:
@unocss/nuxt is no longer supported for OG image stylinguno.config.ts won't work in OG componentsNuxt OG Image now has native Tailwind v4 support. Classes are extracted from your OG components at build time and compiled with Tailwind's CSS engine.
If using @nuxtjs/tailwindcss:
No configuration needed - the module auto-detects your Tailwind setup.
If using Tailwind v4 with the Vite plugin:
Point the module to your CSS entry file:
export default defineNuxtConfig({
ogImage: {
tailwindCss: '~/assets/css/main.css'
}
})
Your CSS file should include @import "tailwindcss" and any @theme customizations.
Custom theme values defined in @theme are automatically resolved:
@import "tailwindcss";
@theme {
--color-brand: #ff6600;
--font-heading: "Inter", sans-serif;
}
<template>
<div class="bg-brand font-heading">
Works!
</div>
</template>
When using @nuxt/ui v3, semantic colors (primary, secondary, etc.) from your app.config.ts are automatically resolved:
export default defineAppConfig({
ui: {
colors: {
primary: 'indigo',
secondary: 'violet'
}
}
})
<template>
<div class="bg-primary-500 text-secondary-200">
Nuxt UI colors!
</div>
</template>