MENU
OpenGraph Twitter Image
The opengraph-image and twitter-image file conventions let you define Open Graph and Twitter images for a route segment. These images are used when links to your site are shared on social networks or messaging apps.
To define them for a route segment, place special files in the corresponding folder:
- opengraph-image.(jpg | jpeg | png | gif | js | ts | tsx) (
- twitter-image.(jpg | jpeg | png | gif | js | ts | tsx) (
- opengraph-image.alt.txt
- twitter-image.alt.txt
(generated output in <head>)
<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>" />
<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>" />
<meta property="og:image:alt" content="About Acme" />
<meta property="twitter:image:alt" content="About Acme" />You can programmatically generate images using code. By default, these images, including opengraph-image.js and twitter-image.js, are statically optimized at build time and cached unless they use dynamic APIs or configurations.
Notice below that when you programmatically generate the images, you can export the configuration variables 'alt', 'size', and 'contentType' additionally.
opengraph-image.tsx:
opengraph-image.tsx:
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
// 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({ params }: { params: { slug: string } }) {
// 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,
},
],
}
)
}This example utilizes the Node.js runtime to fetch a local image from the file system and provides it as an ArrayBuffer to the src attribute of an <img> element. The local asset should be placed relative to the project root, not the location of the example source file.
opengraph-image.js:
opengraph-image.js:
import { ImageResponse } from 'next/og'
import { join } from 'node:path'
import { readFile } from 'node:fs/promises'
export default async function Image() {
const logoData = await readFile(join(process.cwd(), 'logo.png'))
const logoSrc = Uint8Array.from(logoData).buffer
return new ImageResponse(
(
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<img src={logoSrc} height="100" />
</div>
)
)
}