opengraph-image and twitter-image
Theopengraph-image andtwitter-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 anopengraph-image ortwitter-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 convention | Supported file types |
|---|---|
opengraph-image | .jpg,.jpeg,.png,.gif |
twitter-image | .jpg,.jpeg,.png,.gif |
opengraph-image.alt | .txt |
twitter-image.alt | .txt |
Good to know:
The
twitter-imagefile size must not exceed5MB, and theopengraph-imagefile size must not exceed8MB. If the image file size exceeds these limits, the build will fail.
opengraph-image
Add anopengraph-image.(jpg|jpeg|png|gif) image file to any route segment.
<metaproperty="og:image"content="<generated>" /><metaproperty="og:image:type"content="<generated>" /><metaproperty="og:image:width"content="<generated>" /><metaproperty="og:image:height"content="<generated>" />twitter-image
Add atwitter-image.(jpg|jpeg|png|gif) image file to any route segment.
<metaname="twitter:image"content="<generated>" /><metaname="twitter:image:type"content="<generated>" /><metaname="twitter:image:width"content="<generated>" /><metaname="twitter:image:height"content="<generated>" />opengraph-image.alt.txt
Add an accompanyingopengraph-image.alt.txt file in the same route segment as theopengraph-image.(jpg|jpeg|png|gif) image it's alt text.
About Acme<metaproperty="og:image:alt"content="About Acme" />twitter-image.alt.txt
Add an accompanyingtwitter-image.alt.txt file in the same route segment as thetwitter-image.(jpg|jpeg|png|gif) image it's alt text.
About Acme<metaproperty="twitter:image:alt"content="About Acme" />Generate images using code (.js, .ts, .tsx)
In addition to usingliteral image files, you can programmaticallygenerate images using code.
Generate a route segment's shared image by creating anopengraph-image ortwitter-image route that default exports a function.
| File convention | Supported file types |
|---|---|
opengraph-image | .js,.ts,.tsx |
twitter-image | .js,.ts,.tsx |
Good to know:
- By default, generated images arestatically optimized (generated at build time and cached) unless they useDynamic APIs or uncached data.
- You can generate multiple Images in the same file using
generateImageMetadata.opengraph-image.jsandtwitter-image.jsare special Route Handlers that is cached by default unless it uses aDynamic API ordynamic config option.
The easiest way to generate an image is to use theImageResponse API fromnext/og.
import { ImageResponse }from'next/og'import { readFile }from'node:fs/promises'import { join }from'node:path'// Image metadataexportconstalt='About Acme'exportconstsize= { width:1200, height:630,}exportconstcontentType='image/png'// Image generationexportdefaultasyncfunctionImage() {// Font loading, process.cwd() is Next.js project directoryconstinterSemiBold=awaitreadFile(join(process.cwd(),'assets/Inter-SemiBold.ttf') )returnnewImageResponse( (// ImageResponse JSX element <divstyle={{ 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: interSemiBold, style:'normal', weight:400, }, ], } )}<metaproperty="og:image"content="<generated>" /><metaproperty="og:image:alt"content="About Acme" /><metaproperty="og:image:type"content="image/png" /><metaproperty="og:image:width"content="1200" /><metaproperty="og:image:height"content="630" />Props
The default export function receives the following props:
params (optional)
A promise that resolves to an object containing thedynamic route parameters object from the root segment down to the segmentopengraph-image ortwitter-image is colocated in.
Good to know: If you use
generateImageMetadata, the function will also receive anidprop that is a promise resolving to theidvalue from one of the items returned bygenerateImageMetadata.
exportdefaultasyncfunctionImage({ params,}: { params:Promise<{ slug:string }>}) {const {slug }=await params// ...}| Route | URL | params |
|---|---|---|
app/shop/opengraph-image.js | /shop | undefined |
app/shop/[slug]/opengraph-image.js | /shop/1 | Promise<{ slug: '1' }> |
app/shop/[tag]/[item]/opengraph-image.js | /shop/1/2 | Promise<{ tag: '1', item: '2' }> |
Returns
The default export function should return aBlob |ArrayBuffer |TypedArray |DataView |ReadableStream |Response.
Good to know:
ImageResponsesatisfies this return type.
Config exports
You can optionally configure the image's metadata by exportingalt,size, andcontentType variables fromopengraph-image ortwitter-image route.
| Option | Type |
|---|---|
alt | string |
size | { width: number; height: number } |
contentType | string -image MIME type |
alt
exportconstalt='My images alt text'exportdefaultfunctionImage() {}<metaproperty="og:image:alt"content="My images alt text" />size
exportconstsize= { width:1200, height:630 }exportdefaultfunctionImage() {}<metaproperty="og:image:width"content="1200" /><metaproperty="og:image:height"content="630" />contentType
exportconstcontentType='image/png'exportdefaultfunctionImage() {}<metaproperty="og:image:type"content="image/png" />Route Segment Config
opengraph-image andtwitter-image are specializedRoute Handlers that can use the sameroute segment configuration options as Pages and Layouts.
Examples
Using external data
This example uses theparams object and external data to generate the image.
Good to know:By default, this generated image will bestatically optimized. You can configure the individual
fetchoptionsor route segmentsoptions to change this behavior.
import { ImageResponse }from'next/og'exportconstalt='About Acme'exportconstsize= { width:1200, height:630,}exportconstcontentType='image/png'exportdefaultasyncfunctionImage({ params,}: { params:Promise<{ slug:string }>}) {const {slug }=await paramsconstpost=awaitfetch(`https://.../posts/${slug}`).then((res)=>res.json() )returnnewImageResponse( ( <divstyle={{ fontSize:48, background:'white', width:'100%', height:'100%', display:'flex', alignItems:'center', justifyContent:'center', }} > {post.title} </div> ), {...size, } )}Using Node.js runtime with local assets
These examples use the Node.js runtime to fetch a local image from the file system and pass it to the<img>src attribute, either as a base64 string or anArrayBuffer. Place the local asset relative to the project root, not the example source file.
import { ImageResponse }from'next/og'import { join }from'node:path'import { readFile }from'node:fs/promises'exportdefaultasyncfunctionImage() {constlogoData=awaitreadFile(join(process.cwd(),'logo.png'),'base64')constlogoSrc=`data:image/png;base64,${logoData}`returnnewImageResponse( ( <divstyle={{ display:'flex', alignItems:'center', justifyContent:'center', }} > <imgsrc={logoSrc}height="100" /> </div> ) )}Passing anArrayBuffer to thesrc attribute of an<img> element is not part of the HTML spec. The rendering engine used bynext/og supports it, but because TypeScript definitions follow the spec, you need a@ts-expect-error directive or similar to use thisfeature.
import { ImageResponse }from'next/og'import { join }from'node:path'import { readFile }from'node:fs/promises'exportdefaultasyncfunctionImage() {constlogoData=awaitreadFile(join(process.cwd(),'logo.png'))constlogoSrc=Uint8Array.from(logoData).bufferreturnnewImageResponse( ( <divstyle={{ display:'flex', alignItems:'center', justifyContent:'center', }} > {/* @ts-expect-error Satori accepts ArrayBuffer/typed arrays for <img src> at runtime */} <imgsrc={logoSrc}height="100" /> </div> ) )}Version History
| Version | Changes |
|---|---|
v16.0.0 | params is now a promise that resolves to an object |
v13.3.0 | opengraph-image andtwitter-image introduced. |
Was this helpful?