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="og: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/server.

    app/about/opengraph-image.tsx
    import { ImageResponse } from 'next/server';
     
    // Route segment config
    export const runtime = 'edge';
     
    // Image metadata
    export const alt = 'About Acme';
    export const size = {
      width: 1200,
      height: 630,
    };
     
    export const contentType = 'image/png';
     
    // Font
    const interSemiBold = fetch(
      new URL('./Inter-SemiBold.ttf', import.meta.url),
    ).then((res) => res.arrayBuffer());
     
    // Image generation
    export default function Image() {
      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.

    Note: 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.

    OptionTypeDefault
    dynamic'auto' | 'force-dynamic' | 'error' | 'force-static''auto'
    revalidatefalse | 'force-cache' | 0 | numberfalse
    runtime'nodejs' | 'edge''nodejs'
    preferredRegion'auto' | 'global' | 'home' | string | string[]'auto'
    app/opengraph-image.tsx
    export const runtime = 'edge';
     
    export default function Image() {}

    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/server';
     
    export const runtime = 'edge';
     
    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,
        },
      );
    }

    Was this helpful?