Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To generate a route-specific Open Graph image in the Next.js App Router, add an opengraph-image.tsx file to the route segment and default-export a function that returns an ImageResponse imported from next/og. Next.js uses the file to add Open Graph image metadata to the page. This approach is useful when a share image needs page-specific content, such as an article title; for an image that never changes, a static image file is simpler.

Choose a static image or generate one with code

Next.js supports both static and generated Open Graph images in the App Router. A static opengraph-image.jpg, .png, or .gif fits a route whose share image is fixed. Use opengraph-image.js, .ts, or .tsx when the image needs JSX, route parameters, or application data. More specific route-segment images take precedence over images in higher-level segments. See the Next.js Metadata and OG images guide and the opengraph-image file convention.

How do I use ImageResponse from next/og?

Put the generated metadata file in the route segment that should own the image. For example, a blog post route can use app/blog/[slug]/opengraph-image.tsx. The following pattern follows the current file-convention documentation; getPost represents your own data-loading function, not a Next.js API.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { ImageResponse } from 'next/og'

export const alt = 'A concise description of the share image'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'

export default async function Image({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  const post = await getPost(slug)

  return new ImageResponse(
    <div
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      {post.title}
    </div>,
    { ...size }
  )
}
  1. Create the file in the intended route segment. A file under a dynamic segment can use that route’s parameters to select content.
  2. Export image metadata. Set alt, size, and contentType so the generated image has descriptive alternative text, dimensions, and a MIME type.
  3. Return an ImageResponse. Pass it JSX and supported rendering options. Next.js connects the generated asset to the route’s Open Graph metadata.

In the current file-convention example, route parameters are promise-based and are read with await params. Parameter types have changed across Next.js releases, so use the signature documented for the version installed in your project. The file-convention reference describes the image function’s accepted return types, including ImageResponse.

What ImageResponse renders—and what it does not

ImageResponse turns JSX and CSS into a PNG using @vercel/og, Satori, and Resvg. It is not a browser screenshot: it supports Flexbox and a subset of CSS, but not CSS Grid. Design the image using supported styles rather than assuming every browser CSS feature will render. The Next.js 15 ImageResponse API reference documents the renderer options and constraints.

  • Bundle size: The Next.js 15 API reference documents a 500 KB maximum bundle, including JSX, CSS, fonts, images, and other assets.
  • Fonts: TTF, OTF, and WOFF are supported; TTF or OTF is preferred for parsing speed. Custom font data is supplied with a family name, weight, and style.
  • Dimensions: The documented defaults are 1200 × 630 pixels. Setting and exporting size explicitly makes the intended dimensions clear.
  • Other options: The API documents emoji selection, a debug option, and HTTP response settings such as status and headers.

Keep assets and styles within the renderer’s supported subset and bundle limit. A complex design that depends on browser-only CSS or large embedded assets may need simplifying.

Account for caching and changing content

Generated images in the metadata-file convention are statically optimized by default. The Next.js file-convention documentation says Dynamic APIs or uncached data can affect that behavior. If an image includes content that changes, decide whether static output fits its update cycle and configure data fetching and route behavior accordingly. Do not assume a generated image will refresh whenever its underlying content changes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check the Next.js version before copying examples

The import path and route parameter signature depend on the framework version. The Next.js 15 API reference records that ImageResponse moved from next/server to next/og in Next.js 14; in Next.js 13 it was introduced through @vercel/og, with an earlier next/server import documented in the version history. The Next.js 13.3 release announcement provides historical context for dynamic Open Graph image generation. For a current App Router implementation, follow documentation matching the installed release rather than mixing examples from different versions.

Validate the result

  • Confirm the file is in the route segment whose pages should use the image.
  • Check that the exported alt, size, and contentType describe the output you intend to serve.
  • Verify that route-specific data is loaded for the correct parameter and that its freshness expectations match the route’s caching behavior.
  • Use Flexbox and supported CSS, and keep JSX, styles, fonts, and images within the documented bundle limit.
  • Check the rendered page metadata and generated image in your application, using the documentation for your installed Next.js version to resolve version-specific behavior.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.