Skip to main content

Next.js 16 App Router

Implement and verify OG images in a Next.js app

Choose static metadata, route-aware generateMetadata or a generated opengraph-image, use public absolute URLs and inspect the deployed result.

Choose file-based or code-based metadata deliberately

Use a static metadata object export for fixed values and generateMetadata when route data changes the title, description or image. Both exports belong in Server Components.

A file named opengraph-image can provide file-based metadata. A generated opengraph-image.tsx can return ImageResponse when the visual depends on route data. Do not export static metadata and generateMetadata from the same route segment.

Static metadata with metadataBase

metadataBase resolves relative metadata URLs, while an explicit public absolute image URL such as https://starterpackai.com/og/home.png is easiest to audit outside the application.

tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  metadataBase: new URL('https://starterpackai.com'),
  title: 'A clear page title',
  description: 'A concise share description',
  openGraph: {
    images: ['https://starterpackai.com/og/home.png'],
  },
}

Route-aware generateMetadata in Next.js 16

When params are shown in current App Router examples, model them as a Promise and await params before loading route-specific content.

tsx
import type { Metadata } from 'next'

type Props = { params: Promise<{ slug: string }> }

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params
  const post = await getPost(slug)

  return {
    title: post.title,
    openGraph: { images: [post.ogImageUrl] },
  }
}

Dynamic opengraph-image with ImageResponse

Keep the generated route server-side, await dynamic params and return an ImageResponse with explicit dimensions.

tsx
import { ImageResponse } from 'next/og'

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
  return new ImageResponse(
    <div style={{ display: 'flex', padding: 80 }}>{slug}</div>,
    size
  )
}

Deployment verification checklist

  • Confirm metadata or generateMetadata runs in a Server Component route segment.
  • Open the deployed HTML and verify the final og:title, og:description and og:image values.
  • Open the absolute public image URL in a separate session and verify a successful image response.
  • Check the rendered 1200×630 composition at small link-card size.
  • Run a public metadata checker, then use platform-specific debuggers when caches disagree.

Next.js FAQ

Next.js OG image questions

The key App Router choices and deployment checks.

Should I use metadata or generateMetadata?

Use static metadata for fixed values and generateMetadata for route-dependent values. These metadata exports are supported in Server Components.

When should I use opengraph-image and ImageResponse?

Use the file convention for colocated image metadata; generate an ImageResponse when the artwork must be built from route data at request or build time.

Why use an absolute public image URL?

Social crawlers fetch outside the browser session. An absolute URL makes the target unambiguous and lets you test the asset independently.

Create the asset, then verify the route

Build the final card in the generator and use the checker after the Next.js page is publicly deployed.