OG Image

Creates page share images.

Field Notes
Designing for desktop density
Why a compact type scale and alpha hairlines keep dense screens calm.
Mira Chen · Oct 17, 2026
design
type

Installation

pnpm dlx shadcn@latest add @paneui/og-image

Usage

Examples

Accents and Modes

Cover Art

CJK Titles

Route files

npx shadcn@latest add @paneui/og-image-route writes app/opengraph-image.tsx and app/twitter-image.tsx; edit the SITE object at the top. Next.js links the image from every page under that folder and renders it at build time. @paneui/og-image-post-route writes app/blog/[slug]/opengraph-image.tsx, which reads params and draws OgCoverArt from the slug behind the title. For several images in one route, export generateImageMetadata and read id in the image function.

Static export

With output: "export", opengraph-image is written without an extension, and some static hosts then serve it as a download, which share previews ignore. Render the image from a route handler at app/og.png/route.tsx instead (a GET that returns the ImageResponse, with dynamic = "force-static"), and list /og.png in metadata.openGraph.images; metadata URLs don't get basePath, so prefix it yourself.

Rendering

The renderer behind ImageResponse lays out flexbox and absolute positioning only, with inline styles: no grid, classes, hooks, context or browser APIs. Every text box has a fixed size, and fades end on the same colour at alpha 0, since transparent blends through black there. Set metadataBase in the root layout so the image URL is absolute.

Fonts

The renderer reads .ttf, .otf and .woff, not .woff2. Load each weight with readFile from your repo, or fetch a subset from a font service with text= (a non-browser client gets TrueType back), and pass the family name as fontFamily; the route template does the fetch and falls back to the built-in font when it fails. A full CJK font is over 10 MB, so load only the characters on the image, plus · and ….

Titles

The title is sized by length, counting CJK and full-width characters double: 80px up to 24, 68px up to 44, 56px up to 72 and 46px beyond. The two larger sizes clamp to two lines, the smaller to three; the description clamps to two. ogImageTitleSize(title) returns the size.

Colours

OG_IMAGE_TOKENS holds the theme's background, card, foreground, muted foreground, border and primary roles for every accent in both modes. It is generated from the theme, with translucent roles flattened over the background and wide-gamut values converted to sRGB, so a theme update reaches the image when you reinstall it. colors overrides single roles.

Images

logo (square, beside the site name) and avatar (round, beside the author) take a URL or a data URI of a PNG, JPEG or SVG; WebP is not supported. Both are decorative, so the route's alt export carries the title.

Previews

The previews on this page draw the same components in the browser inside an SVG foreignObject, scaled from 1200 × 630.

API Reference

OgImage

title*
string
Clamped to three lines and sized by length.
siteName*
string
Shown at the top, beside logo.
url
string
Shown at the top right, such as the host and path.
description
string
One or two lines under the title.
author
string
Shown in the footer, before date.
avatar
string
Round image beside the author.
logo
string
Square image beside the site name.
date
string
Shown as given, so format it in the page's language.
tags
string[]
The first three are shown.
accent= "blue"
"blue" | "neutral" | "green" | "orange" | "rose" | "violet"
The theme accent preset.
mode= "light"
"light" | "dark"
The theme mode.
pattern= "grid"
"grid" | "dots" | "none"
Backdrop behind the text, fading from the top corner.
colors
Partial<OgImageColors>
Overrides for single roles, on top of the accent and mode.
fontFamily
string
The family name the fonts were registered under.
style
React.CSSProperties
Merged onto the root, for a background image or a renderer quirk.
PropTypeDefaultDescription
title*string—Clamped to three lines and sized by length.
siteName*string—Shown at the top, beside logo.
urlstring—Shown at the top right, such as the host and path.
descriptionstring—One or two lines under the title.
authorstring—Shown in the footer, before date.
avatarstring—Round image beside the author.
logostring—Square image beside the site name.
datestring—Shown as given, so format it in the page's language.
tagsstring[]—The first three are shown.
accent"blue" | "neutral" | "green" | "orange" | "rose" | "violet""blue"The theme accent preset.
mode"light" | "dark""light"The theme mode.
pattern"grid" | "dots" | "none""grid"Backdrop behind the text, fading from the top corner.
colorsPartial<OgImageColors>—Overrides for single roles, on top of the accent and mode.
fontFamilystring—The family name the fonts were registered under.
styleReact.CSSProperties—Merged onto the root, for a background image or a renderer quirk.
data-slot
og-image on the root.
Data attributeDescription
data-slotog-image on the root.

OgCoverArt

The eight cover-art compositions, drawn for the same renderer. The same seed picks the same art as the in-page cover art.

seed
string
Picks composition, mirror, tones and pattern.
variant
0 – 7
The composition. Wins over seed.
mirror
"none" | "x" | "y" | "xy"
Flips the composition.
ramp
0 | 1 | 2
Shifts the tones along the accent ladder.
accent= "blue"
OgImageAccent
The theme accent preset.
mode= "light"
"light" | "dark"
The theme mode.
width= 1200
number
Width in px.
height= 630
number
Height in px.
PropTypeDefaultDescription
seedstring—Picks composition, mirror, tones and pattern.
variant0 – 7—The composition. Wins over seed.
mirror"none" | "x" | "y" | "xy"—Flips the composition.
ramp0 | 1 | 2—Shifts the tones along the accent ladder.
accentOgImageAccent"blue"The theme accent preset.
mode"light" | "dark""light"The theme mode.
widthnumber1200Width in px.
heightnumber630Height in px.

ogImageSize

The 1200 × 630 size, for the route's size export and the ImageResponse options. ogImageContentType is "image/png".

ogImageColors

ogImageColors(accent, mode, overrides?) returns the colours the card draws with.

OG_IMAGE_TOKENS

The generated map, OG_IMAGE_TOKENS[accent][mode], with background, card, foreground, mutedForeground, border, primary, primaryForeground, primarySubtle and primaryBorder as opaque hex.

ogImageTitleSize

ogImageTitleSize(title) returns the title's font size in px.