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

In a Next.js App Router project, generate an Open Graph image by adding a route such as app/api/og/route.tsx, rendering JSX with ImageResponse from next/og, then setting the page’s og:image metadata to that route’s absolute, publicly reachable URL. Vercel’s recommended image size is 1200 × 630 pixels. This approach makes it possible to create a share card from a page title or other data instead of maintaining a separate image for every page.

What you need before generating an OG image

The Vercel guide for this workflow, last updated December 19, 2025, lists Node.js 22 or newer and Next.js 12.2.3 or newer. In an App Router project, the next/og entry point provides ImageResponse; the guide says the OG package is already included in App Router projects. Other project configurations may use @vercel/og. Check the current guide and your framework/runtime combination before adapting the handler.

  • A Next.js App Router project deployed to a public URL.
  • A route that returns an image response.
  • Page metadata that points to the route’s absolute deployed URL.
  • A route accessible to social crawlers, including any applicable robots.txt rules.

Create a basic image-generation route

Create app/api/og/route.tsx. The following minimal route returns a 1200 × 630 PNG with a centered title:

import { ImageResponse } from 'next/og'

export async function GET() {
  return new ImageResponse(
    <div style={{
      display: 'flex',
      width: '100%',
      height: '100%',
      alignItems: 'center',
      justifyContent: 'center',
      background: 'white',
      color: 'black',
      fontSize: 64,
    }}>
      Article title
    </div>,
    { width: 1200, height: 630 },
  )
}

ImageResponse converts the JSX layout into an image. The 1200 × 630 dimensions are Vercel’s documented recommendation and the API reference’s default dimensions. The API reference documents a PNG content type. You can begin with a fixed card, then make the route data-driven when different pages need different text or imagery. See Vercel’s Open Graph image-generation guide and the @vercel/og API reference for the current API details.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Connect the generated image to page metadata

Generating an image at a route does not automatically tell social platforms to use it. Each page must expose an absolute URL for that image in its Open Graph metadata. For a page whose image comes from the endpoint above, the essential HTML is:

<meta property="og:image" content="https://example.com/api/og" />

Replace https://example.com with the deployed site’s public origin. A relative path is not the absolute image URL the guide asks you to provide. In Next.js, set the equivalent Open Graph metadata through the framework’s metadata conventions for the page or layout, making sure the resulting og:image value is the complete deployed URL. After deployment, open the image URL directly to confirm that it returns an image rather than an error or an HTML page.

Make the image dynamic from a title

A parameterized API route is useful when a card’s content varies per request. Read the query parameter from the request URL and use it in the rendered element. This example follows Vercel’s title pattern: it takes a title query parameter, trims it to 100 characters for display, and falls back to a default. That 100-character slice is an example choice, not a universal Vercel limit.

import { ImageResponse } from 'next/og'

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const rawTitle = searchParams.get('title') ?? 'A useful default title'
  const title = rawTitle.slice(0, 100)

  return new ImageResponse(
    <div style={{
      display: 'flex',
      width: '100%',
      height: '100%',
      alignItems: 'center',
      justifyContent: 'center',
      padding: '48px',
      background: 'white',
      color: 'black',
      fontSize: 64,
      textAlign: 'center',
    }}>
      {title}
    </div>,
    { width: 1200, height: 630 },
  )
}

A page can then point its metadata at an image URL such as https://example.com/api/og?title=Example%20article. Ensure the URL is correctly encoded when constructing it programmatically. Do not treat truncation as validation: decide what characters and content your application permits, constrain the final length to fit the visual design, and avoid putting secrets or sensitive user data in a publicly fetchable image URL.

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

For remote images, Vercel documents fetching assets with fetch; for local files, it describes using fs.readFile. Keep asset sizes in mind because images are included in the bundle-size calculation. Font files supported by the renderer are TTF, OTF, and WOFF, with TTF or OTF recommended for parsing speed.

Choose between an API route and an opengraph-image file

Vercel’s examples document both parameterized routes and Next.js convention-based files such as app/about/opengraph-image.jsx. The right choice depends on how the artwork and content vary; the documentation does not establish one universal winner.

Pattern Best fit What to plan for
Parameterized API route Cards that need request-specific content, such as a title passed as a query parameter. Constrain and sanitize user-controlled inputs, and make each page’s metadata resolve to the correct absolute route URL.
opengraph-image route file Page-specific or framework-convention-based image assets, as shown in Vercel’s examples. Decide how the file-based image maps to the page and ensure the resulting metadata is exposed when deployed.

See Vercel’s OG image examples for the documented patterns. A static page-specific card need not use a query-parameter endpoint; a dynamic endpoint is useful only when the image actually needs request-specific inputs.

Design within the renderer’s limits

The renderer uses Satori and Resvg to turn supported HTML/CSS into PNG. Its CSS support is a subset rather than a full browser engine:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Use flexbox or absolute positioning for layouts; CSS Grid is not supported.
  • Use supported TTF, OTF, or WOFF font files. Vercel recommends TTF or OTF for parsing speed.
  • Keep the function bundle at or below the documented 500 KB maximum. The figure counts JSX, CSS, fonts, images, and other assets.
  • If the bundle is too large, reduce or remove assets, or fetch appropriate assets at runtime as Vercel suggests.

These constraints matter especially for complex designs: a layout that looks correct in a normal browser may rely on unsupported CSS and render differently or fail in the image renderer. Start with a small layout and add styles incrementally.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check runtime compatibility, caching, and reliability

Vercel documents generation support on Node.js and describes accessing local files through fs.readFile and remote assets through fetch. Its runtime table says return new Response(...) is supported for Pages Router with Edge, App Router with Node.js, and App Router with Edge, but not for Pages Router with Node.js in the documented vercel/og combination. The example in this article uses the App Router and ImageResponse; if you change routers, runtimes, or handler shape, check the current compatibility guidance rather than assuming the same return pattern works everywhere.

The @vercel/og reference documents a default image size of 1200 × 630, a PNG content type, and cache-control defaults of public, immutable, no-transform, max-age=31536000. Immutable caching can leave an old card associated with a stable URL after you change its content. If an image must refresh when the underlying content changes, plan a versioned URL or another cache strategy rather than assuming every deployment or external cache will discard the old result. These are documented defaults; they do not guarantee identical behavior at every deployment or cache layer.

Allow crawlers and preview metadata before launch

  1. Permit the image path. Vercel recommends allowing social providers to fetch OG routes in robots.txt. For a route under /api/og/, its example is Allow: /api/og/*.
  2. Deploy and verify the image URL. Request the absolute URL used by og:image and confirm it returns the intended image.
  3. Inspect the page metadata. Use Vercel’s Open Graph preview tooling to inspect metadata before production; the preview tool helps find wiring and fetch problems, but does not guarantee that every social platform will display the card identically.

Vercel describes the preview workflow in Inspecting your Open Graph metadata.

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

Troubleshoot common failures

Symptom Likely cause What to check
The social preview has no image. The page has no usable og:image, the value is relative, or the image route cannot be fetched. Inspect the deployed page metadata, use the absolute public image URL, request it directly, and verify crawler access in robots.txt.
The endpoint returns an error or not an image. The route path or handler is incorrect, or the runtime and router combination is unsupported for the chosen response pattern. Confirm the route file is at the intended App Router path, check deployment logs, and compare the runtime/handler pairing with Vercel’s compatibility table.
Text or layout is missing or misplaced. The design uses CSS outside the supported subset, or the text does not fit the chosen dimensions. Replace Grid with flexbox or absolute positioning, simplify styles, constrain input length, and test the route output directly.
The image fails after adding a font or asset. The format may be unsupported or the bundle may exceed 500 KB. Use TTF, OTF, or WOFF fonts; reduce bundled files, or fetch suitable assets at runtime.
A changed card still appears old. The API reference’s documented default cache policy is immutable and long-lived. Use a changed/versioned image URL when content changes, and account for caching beyond the route itself.

Or skip the browser setup

If your goal is to capture how a public page currently looks rather than render your own designed social card, ScreenshotNeo is a website screenshot API and MCP server for developers. A GET request returns an image or PDF; its own consent cleanup and billing verdicts are distinct from generating an OG graphic with Vercel’s JSX renderer.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. It removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots, and the Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month with no card.

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.