---
title: "v7.0.0"
description: "Release notes for Nuxt OG Image v7."
canonical_url: "https://nuxtseo.com/docs/og-image/releases/v7"
---

## Introduction

Nuxt OG Image v7 ships in Nuxt SEO v6. See the [Nuxt SEO v6 release notes](/docs/nuxt-seo/releases/v6).

V7 requires Nuxt 4.6.1+ or Nuxt 5. It signs image URLs with your Nuxt app secret, uses native Satori layout, and reads fonts from `@nuxt/fonts` v1.
It can also publish rendered images to object storage.

Follow the [v6 to v7 migration guide](/docs/og-image/migration-guide/v7) to upgrade.

**Quick migration:**

```bash
pnpm add nuxt-og-image@^7
npx nuxt-og-image generate-secret
```

Set the printed `NUXT_APP_SECRET` value in your production environment.

## :icon{name="i-noto-rocket"} Features

### Publish Images to Object Storage

The module can upload rendered images to a public bucket through a Nitro storage mount. Prerendered `og:image` tags then use the bucket URL. ([#730](https://github.com/nuxt-modules/og-image/pull/730))

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  ogImage: {
    publish: { storage: 'og-image-public', baseURL: 'https://images.example.com' },
  },
  nitro: {
    storage: {
      'og-image-public': { driver: 'cloudflare-r2-binding', binding: 'OG_IMAGES' },
    },
  },
})
```

A runtime image request redirects to the published copy when it exists. Otherwise, the server returns the image and uploads it in the background.
Prerendered local images now use `app.cdnURL` when you set it. See the [`publish` option](/docs/og-image/api/config#publish).

### One Secret for Signing

URL signing now derives its key from the Nuxt 4.6 app secret. One `NUXT_APP_SECRET` value covers OG images, sessions, and other Nuxt features. ([#729](https://github.com/nuxt-modules/og-image/pull/729))

```bash
npx nuxt-og-image generate-secret
# NUXT_APP_SECRET=...
```

See the [Security guide](/docs/og-image/guides/security#url-signing).

### Native Satori Layout

Satori 0.47.1 supports block, inline, flexbox, and grid layout. Templates now use this native layout. ([#736](https://github.com/nuxt-modules/og-image/pull/736))

The module now passes `translate`, `rotate`, `scale`, `inset`, `z-index`, and backdrop utilities to Satori.

### @nuxt/fonts v1 Integration

The module reads fonts through the `fonts:resolved` hook of [@nuxt/fonts](https://fonts.nuxt.com) 1.0. ([#698](https://github.com/nuxt-modules/og-image/pull/698))

- OG images can use every resolved family and weight, including families that only your site CSS uses.
- Bold text works on the [webpack](https://webpack.js.org) and rspack builders.
- Takumi loads OTF and WOFF files, as well as TTF and WOFF2.
- Satori converts static WOFF2 files and resolves static alternatives for variable fonts.

### Performance

- SSR client builds no longer include the static URL encoder, the component manifest, or URL hashing. ([#723](https://github.com/nuxt-modules/og-image/pull/723))
- On an edge benchmark, cold import CPU fell from 119.8 ms to 114.1 ms, and RSS fell from 50.8 MiB to 47.4 MiB. ([#720](https://github.com/nuxt-modules/og-image/pull/720))

## :icon{name="i-noto-warning"} Breaking Changes

### Nuxt 4.6.1 and Node 22 Required

V7 drops Nuxt 3 and Nuxt 4 versions before 4.6.1. ([#720](https://github.com/nuxt-modules/og-image/pull/720), [#739](https://github.com/nuxt-modules/og-image/pull/739))

| Dependency                    | v6                   | v7                                     |
| ----------------------------- | -------------------- | -------------------------------------- |
| Nuxt                          | `>=3.16.0`           | `^4.6.1 \|\| ^5.0.0`                   |
| [Node.js](https://nodejs.org) | `>=18.0.0`           | `^22.22.3 \|\| ^24.15.0 \|\| >=26.0.0` |
| `@unhead/vue`                 | `^2.0.5 \|\| ^3.0.0` | `^3.4.2`                               |
| `unstorage`                   | `^1.15.0`            | `^1.17.5`                              |

### Signing Key From NUXT_APP_SECRET

V6 generated a new secret on each build unless you set one. V7 derives the key from Nuxt `runtimeConfig.appSecret`. ([#729](https://github.com/nuxt-modules/og-image/pull/729))

Production needs a root secret with at least 32 characters. If it is missing or invalid, OG image requests fail with a `500` error. ([#742](https://github.com/nuxt-modules/og-image/pull/742))

```ts [nuxt.config.ts]
// Before: remove this
export default defineNuxtConfig({
  ogImage: { security: { secret: process.env.NUXT_OG_IMAGE_SECRET } },
})
```

```bash [deployment environment]
# After
NUXT_APP_SECRET=<output of npx nuxt-og-image generate-secret>
```

- V7 still reads `NUXT_OG_IMAGE_SECRET` when the app secret is empty, and warns once.
- V7 removes string values of `ogImage.security.secret` and `runtimeConfig.ogImage.secret`. `security.secret: false` still turns off signing.
- All v6 signed URLs become invalid. Rebuild prerendered pages and purge cached HTML.

### Satori 0.47.1 Required

The `satori` peer is now `^0.47.1`. The module no longer adds `display: flex` and `flex-direction: column` to a bare `<div>`{lang="html"}. ([#736](https://github.com/nuxt-modules/og-image/pull/736))

```vue
<!-- Before -->
<div class="w-full h-full justify-between p-8">

<!-- After -->
<div class="box-border flex flex-col w-full h-full justify-between p-8">
```

Text elements no longer get flex wrapping or a `0.2em` gap. Templates may also need `box-border`, `border-solid`, explicit heading margins, or `shrink-0` on SVGs.
The [migration guide](/docs/og-image/migration-guide/v7#update-satori-templates) lists each layout change.

### @nuxt/fonts 1.0 Required for Custom Fonts

With `@nuxt/fonts` before 1.0, OG images use the bundled Inter font and the build warns. ([#698](https://github.com/nuxt-modules/og-image/pull/698))

```bash
pnpm add @nuxt/fonts@^1
```

The `fontless` peer is now `^1.3.2`, and the `unifont` peer is now `^1.0.3`. If OG text uses a script outside the default subsets, set `subsets` on each family.

### Optional Peers Updated and Takumi v1 Removed

V7 requires these optional peer ranges. ([#739](https://github.com/nuxt-modules/og-image/pull/739))

| Package                                | v7 range   |
| -------------------------------------- | ---------- |
| `@takumi-rs/core`, `@takumi-rs/wasm`   | `^2.15.0`  |
| `@resvg/resvg-js`, `@resvg/resvg-wasm` | `^2.6.2`   |
| `sharp`                                | `^0.35.5`  |
| `playwright-core`                      | `^1.64.0`  |
| `chrome-launcher`                      | `^1.2.2`   |
| `tailwindcss`                          | `^4.3.3`   |
| `@unocss/core`, `@unocss/config`       | `^66.10.5` |
| `zod`                                  | `^4.6.6`   |

The Takumi `fetchedResources` and `persistentImages` options merge into `images`. Each entry keeps its `src` and `data` fields.

```ts
// Before
defineOgImage('Card', props, { takumi: { fetchedResources: [{ src, data }], persistentImages: [{ src, data }] } })

// After
defineOgImage('Card', props, { takumi: { images: [{ src, data }] } })
```

### chrome-launcher Is an Optional Peer

The module no longer installs `chrome-launcher`. Satori and Takumi apps do not need it. ([#749](https://github.com/nuxt-modules/og-image/pull/749))

If you use the browser renderer with a local Chrome, install it as a dev dependency:

```bash
pnpm add -D chrome-launcher
```

Without it, development and local builds download Chromium through [Playwright](https://playwright.dev) on the first render.
The browser renderer still needs `playwright-core`. Without it, the build fails and prints the install command.
This applies when you set `ogImage.browser` or a page uses a `.browser.vue` template.

### Server Helpers Use Nuxt's RequestEvent

`getOgImageUrl(event, ...)`{lang="ts"} now takes Nuxt's portable `RequestEvent`. In a handler that calls it, import `defineEventHandler` from `nuxt/server`. ([#720](https://github.com/nuxt-modules/og-image/pull/720))

```ts [server/api/og-image.get.ts]
// Before: the h3 defineEventHandler auto-import

// After
import { defineEventHandler } from 'nuxt/server'
import { getOgImageUrl } from '#og-image/server'

export default defineEventHandler(event => ({
  url: getOgImageUrl(event, '/blog/hello', { component: 'OgImagePost', props: { title: 'My post' } }),
}))
```

For explicit app imports, use `#og-image/app`.

### DevTools Panel Needs nuxtseo-devtools-host

The OG Image DevTools panel moved to an optional host package. ([#720](https://github.com/nuxt-modules/og-image/pull/720))

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

You do not need to add it to `modules`. Production rendering does not need it.

### Bounded Runtime Cache

With the default `runtimeCacheStorage: true` and no Nitro cache mount, the image cache is now a 64 MiB LRU cache. ([#726](https://github.com/nuxt-modules/og-image/pull/726), [#727](https://github.com/nuxt-modules/og-image/pull/727))

- `runtimeCacheStorage: false` now bypasses storage completely.
- Storage drivers receive a TTL of `cacheMaxAgeSeconds`, with a minimum of 60 seconds. ([#725](https://github.com/nuxt-modules/og-image/pull/725))

See the [Runtime Cache guide](/docs/og-image/guides/runtime-cache).

## :icon{name="i-noto-bug"} Bug Fixes

- Escape commas and plus signs in dynamic image URLs, so a client cannot cut off the signature ([#733](https://github.com/nuxt-modules/og-image/pull/733))
- Use the render timeout for storage lookups when publishing ([#731](https://github.com/nuxt-modules/og-image/pull/731))
- Respect `app.baseURL` in DevTools font previews ([#738](https://github.com/nuxt-modules/og-image/pull/738))
- Pass the cache TTL to the storage driver, by [@0xgdr](https://github.com/0xgdr) ([#725](https://github.com/nuxt-modules/og-image/pull/725))
- Declare Site Config as a native module dependency ([#734](https://github.com/nuxt-modules/og-image/pull/734))

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
