The ImageResponse constructor allows you to generate dynamic images using JSX and CSS. This is useful for generating social media images such as Open Graph images, Twitter cards, and more.
ImageResponse uses @vercel/og, Satori, and Resvg to convert HTML and CSS into PNG.
Only flexbox and a subset of CSS properties are supported. Advanced layouts (e.g. display: grid) will not work.
Maximum bundle size of 500KB. The bundle size includes your JSX, CSS, fonts, images, and any other assets. If you exceed the limit, consider reducing the size of any assets or fetching at runtime.
Only ttf, otf, and woff font formats are supported. To maximize the font parsing speed, ttf or otf are preferred over woff.
You can use custom fonts in your ImageResponse by providing a fonts array in the options. The font doesn't depend on request data, so read it once at module scope. See Predictable values.
app/opengraph-image.tsx
import { ImageResponse } from 'next/og'import { readFile } from 'node:fs/promises'import { join } from 'node:path'// Image metadataexport const alt = 'My site'export const size = { width: 1200, height: 630,}export const contentType = 'image/png'const interSemiBold = await readFile( join(process.cwd(), 'assets/Inter-SemiBold.ttf'))// Image generationexport default async function Image() { return new ImageResponse( ( // ... ), // ImageResponse options { // For convenience, we can re-use the exported opengraph-image // size config to also set the ImageResponse's width and height. ...size, fonts: [ { name: 'Inter', data: interSemiBold, style: 'normal', weight: 400, }, ], } )}