Skip to content
App Router...Metadata Filesopengraph-image and twitter-image

opengraph-image and twitter-image

The opengraph-image and twitter-image file conventions allow you to set Open Graph and Twitter images for a route segment.

They are useful for setting the images that appear on social networks and messaging apps when a user shares a link to your site.

There are two ways to set Open Graph and Twitter images:

Image files (.jpg, .png, .gif)

Use an image file to set a route segment's shared image by placing an opengraph-image or twitter-image image file in the segment.

Next.js will evaluate the file and automatically add the appropriate tags to your app's <head> element.

File conventionSupported file types
opengraph-image.jpg, .jpeg, .png, .gif
twitter-image.jpg, .jpeg, .png, .gif
opengraph-image.alt.txt
twitter-image.alt.txt

opengraph-image

Add an opengraph-image.(jpg|jpeg|png|gif) image file to any route segment.

<head> output
<meta property="og:image" content="<generated>" />
<meta property="og:image:type" content="<generated>" />
<meta property="og:image:width" content="<generated>" />
<meta property="og:image:height" content="<generated>" />

twitter-image

Add a twitter-image.(jpg|jpeg|png|gif) image file to any route segment.

<head> output
<meta name="twitter:image" content="<generated>" />
<meta name="twitter:image:type" content="<generated>" />
<meta name="twitter:image:width" content="<generated>" />
<meta name="twitter:image:height" content="<generated>" />

opengraph-image.alt.txt

Add an accompanying opengraph-image.alt.txt file in the same route segment as the opengraph-image.(jpg|jpeg|png|gif) image it's alt text.

opengraph-image.alt.txt
About Acme
<head> output
<meta property="og:image:alt" content="About Acme" />

twitter-image.alt.txt

Add an accompanying twitter-image.alt.txt file in the same route segment as the twitter-image.(jpg|jpeg|png|gif) image it's alt text.

twitter-image.alt.txt
About Acme
<head> output
<meta property="twitter:image:alt" content="About Acme" />

Generate images using code (.js, .ts, .tsx)

In addition to using literal image files, you can programmatically generate images using code.

Generate a route segment's shared image by creating an opengraph-image or twitter-image route that default exports a function.

File conventionSupported file types
opengraph-image.js, .ts, .tsx
twitter-image.js, .ts, .tsx

Good to know

The easiest way to generate an image is to use the ImageResponse API from next/og.

app/about/opengraph-image.tsx
import { ImageResponse } from 'next/og'
 
// Image metadata
export const alt = 'About Acme'
export const size = {
  width: 1200,
  height: 630,
}
 
export const contentType = 'image/png'
 
// Image generation
export default async function Image() {
  // Font
  const interSemiBold = fetch(
    new URL('./Inter-SemiBold.ttf', import.meta.url)
  ).then((res) => res.arrayBuffer())
 
  return new ImageResponse(
    (
      // ImageResponse JSX element
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        About Acme
      </div>
    ),
    // 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: await interSemiBold,
          style: 'normal',
          weight: 400,
        },
      ],
    }
  )
}
<head> output
<meta property="og:image" content="<generated>" />
<meta property="og:image:alt" content="About Acme" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

Props

The default export function receives the following props:

params (optional)

An object containing the dynamic route parameters object from the root segment down to the segment opengraph-image or twitter-image is colocated in.

app/shop/[slug]/opengraph-image.tsx
export default function Image({ params }: { params: { slug: string } }) {
  // ...
}
RouteURLparams
app/shop/opengraph-image.js/shopundefined
app/shop/[slug]/opengraph-image.js/shop/1{ slug: '1' }
app/shop/[tag]/[item]/opengraph-image.js/shop/1/2{ tag: '1', item: '2' }
app/shop/[...slug]/opengraph-image.js/shop/1/2{ slug: ['1', '2'] }

Returns

The default export function should return a Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response.

Good to know: ImageResponse satisfies this return type.

Config exports

You can optionally configure the image's metadata by exporting alt, size, and contentType variables from opengraph-image or twitter-image route.

OptionType
altstring
size{ width: number; height: number }
contentTypestring - image MIME type

alt

opengraph-image.tsx | twitter-image.tsx
export const alt = 'My images alt text'
 
export default function Image() {}
<head> output
<meta property="og:image:alt" content="My images alt text" />

size

opengraph-image.tsx | twitter-image.tsx
export const size = { width: 1200, height: 630 }
 
export default function Image() {}
<head> output
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

contentType

opengraph-image.tsx | twitter-image.tsx
export const contentType = 'image/png'
 
export default function Image() {}
<head> output
<meta property="og:image:type" content="image/png" />

Route Segment Config

opengraph-image and twitter-image are specialized Route Handlers that can use the same route segment configuration options as Pages and Layouts.

Examples

Using external data

This example uses the params object and external data to generate the image.

Good to know: By default, this generated image will be statically optimized. You can configure the individual fetch options or route segments options to change this behavior.

app/posts/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'
 
export const alt = 'About Acme'
export const size = {
  width: 1200,
  height: 630,
}
export const contentType = 'image/png'
 
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await fetch(`https://.../posts/${params.slug}`).then((res) =>
    res.json()
  )
 
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 48,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    ),
    {
      ...size,
    }
  )
}

Using Edge runtime with local assets

This example uses the Edge runtime to fetch a local image on the file system and passes it as an ArrayBuffer to the src attribute of an <img> element.

Using Node.js runtime with local assets

This example uses the Node.js runtime to fetch a local image on the file system and passes it as an ArrayBuffer to the src attribute of an <img> element.

Version History

VersionChanges
v13.3.0opengraph-image and twitter-image introduced.