Documentation
Dynamic OG Images with Satori
Generate beautiful Open Graph images at runtime. No design tools needed—just write JSX and let Satori handle the rest.
What is Satori?
Satori is a library developed by Vercel that converts HTML and CSS into SVG. It's the engine behind @vercel/og and powers dynamic OG image generation for millions of websites.
The key insight: instead of creating images in Photoshop or Figma, you write React components. Satori renders them to SVG, which can then be converted to PNG for use as OG images.
Why this matters: Dynamic OG images mean every blog post, product page, or user profile can have a unique, branded preview image—generated automatically from your data.
How It Works
JSX Template
Write your OG image as a React component with inline styles
Satori Converts
Satori renders JSX to SVG using a subset of CSS Flexbox
PNG Output
Resvg converts SVG to PNG at 1200×630 for social platforms
Quick Start with @vercel/og
The easiest way to get started is with Vercel's official package. It bundles Satori with sensible defaults and works seamlessly with Next.js.
npm install @vercel/ogimport { ImageResponse } from '@vercel/og';
export const runtime = 'edge';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const title = searchParams.get('title') || 'Default Title';
return new ImageResponse(
(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#000',
color: '#fff',
fontSize: 60,
fontWeight: 'bold',
}}
>
{title}
</div>
),
{
width: 1200,
height: 630,
}
);
}Now visit /api/og?title=Hello%20World to see your dynamic OG image.
Using Satori Directly (Advanced)
For more control, you can use Satori directly. This is what og-image.org uses for client-side rendering.
npm install satori @resvg/resvg-wasmimport satori from 'satori';
import { Resvg } from '@resvg/resvg-wasm';
// Load font (required for Satori)
const font = await fetch('/fonts/Inter-Bold.ttf')
.then(res => res.arrayBuffer());
export async function generateOGImage(element: React.ReactNode) {
// Step 1: Render JSX to SVG
const svg = await satori(element, {
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: font,
weight: 700,
style: 'normal',
},
],
});
// Step 2: Convert SVG to PNG
const resvg = new Resvg(svg);
const pngData = resvg.render();
const pngBuffer = pngData.asPng();
return pngBuffer;
}Supported CSS Properties
Satori supports a subset of CSS. Here's what works:
✅ Supported
- • Flexbox (display: flex)
- • Colors (hex, rgb, hsl)
- • Borders and border-radius
- • Padding and margin
- • Font properties
- • Background colors and gradients
- • Box shadow
- • Position (absolute/relative)
❌ Not Supported
- • CSS Grid
- • Animations
- • Pseudo-elements (::before, ::after)
- • Media queries
- • CSS variables
- • calc()
- • External stylesheets
- • Most transforms
Important: Always use inline styles with Satori. Tailwind classes won't work—you need to write raw CSS as JavaScript objects.
Best Practices
1. Always Specify Dimensions
Every element needs explicit width/height or flex properties. Satori can't infer sizes like browsers do.
2. Embed Fonts
Load font files as ArrayBuffer and pass them to Satori. System fonts aren't available in Edge/serverless environments.
3. Cache Generated Images
OG image generation is CPU-intensive. Use CDN caching or store generated images to avoid regenerating on every request.
4. Handle Text Overflow
Long titles will overflow. Use textOverflow: 'ellipsis' and fixed max-width containers.
Common Use Cases
Blog Posts
Generate unique images for each post with title, author, and publish date
E-commerce Products
Show product image, name, and price in a branded template
User Profiles
Create shareable profile cards with avatar, name, and bio
Documentation Pages
Auto-generate images showing page title and section hierarchy
Resources
Don't want to code?
Use our free generator to create OG images visually—no coding required.
Open Generator