Index of every page on this site: llms.txt

Nuxt OG Image works on Cloudflare Workers and Pages with the Takumi (recommended) or Satori renderer using Wasm bindings.

Static Assets (ASSETS Binding)

OG image generation requires loading font files at runtime. On Cloudflare, fonts are served as static assets through the ASSETS binding. Without this binding, the worker cannot access fonts and all text will be invisible.

Cloudflare Pages

No extra configuration needed. The wrangler pages deploy command configures the ASSETS binding automatically.

Cloudflare Workers (Module)

Enable deployConfig so Nitro generates a wrangler.json with the ASSETS binding:

nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'cloudflare-module',
    cloudflare: {
      deployConfig: true,
    },
  },
})

Then build and deploy:

nuxt build
npx wrangler --cwd .output deploy
Do not deploy with wrangler deploy --assets .output/public. This legacy command does not configure the ASSETS binding. Use npx wrangler --cwd .output deploy which reads the generated wrangler.json.

You can verify the binding exists in the deploy output:

Your Worker has access to the following bindings:
Binding            Resource
env.ASSETS         Assets

Custom Wrangler Config

If you manage your own wrangler.toml, add the [assets] section:

wrangler.toml
[assets]
binding = "ASSETS"
directory = ".output/public"

Runtime Cache with KV

The module caches rendered OG images in memory by default, which resets on every deploy. For persistent caching, use Cloudflare KV.

1. Create a KV Namespace

npx wrangler kv namespace create OG_IMAGE_CACHE

2. Add the Binding

[[kv_namespaces]]
binding = "OG_IMAGE_CACHE"
id = "<your-namespace-id>"

3. Configure Cache Storage

nuxt.config.ts
export default defineNuxtConfig({
  ogImage: {
    runtimeCacheStorage: {
      driver: 'cloudflare-kv-binding',
      binding: 'OG_IMAGE_CACHE',
    },
  },
})

See the Runtime Cache guide for more caching options.

Browser Rendering

Cloudflare Browser Rendering enables runtime screenshots for .browser.vue templates. This is not needed for Takumi or Satori templates.

1. Install the Dependency

pnpm add @cloudflare/puppeteer

2. Add the Binding

[browser]
binding = "BROWSER"

Rate Limits

PlanNew browsers per minute
Free3
Paid30

Sessions have a 60 second idle timeout, handled automatically by the module. See Cloudflare Browser Rendering limits for details.

Troubleshooting

Text missing from OG images

If the background and images render but text is invisible, the ASSETS binding is missing. Verify your deployment follows the setup above.

To diagnose, enable ogImage.debug and check the .json variant of your OG image URL. If fonts is an empty array, fonts failed to load.

Fonts load locally but not in production

wrangler dev injects the ASSETS binding automatically, so fonts work in local preview. Production deployments need the binding configured explicitly via deployConfig: true or a wrangler.toml with [assets].

Was this page helpful?