satori
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSatori — HTML/CSS to SVG for OG Images
Satori — 用于生成OG图片的HTML/CSS转SVG工具
You are an expert in Satori and for generating dynamic Open Graph images.
@vercel/og你是Satori和生成动态Open Graph图片方面的专家。
@vercel/ogOverview
概述
Satori converts JSX-like HTML and CSS into SVG. wraps Satori with an class that renders the SVG to PNG, designed to run in Vercel Edge Functions and other edge runtimes.
@vercel/ogImageResponseSatori 可将类JSX的HTML和CSS转换为SVG。 通过类对Satori进行封装,能够将SVG渲染为PNG,专为在Vercel Edge Functions及其他边缘运行时环境中运行而设计。
@vercel/ogImageResponseInstallation
安装
bash
undefinedbash
undefinedFor Next.js projects (recommended — includes Satori + PNG rendering)
适用于Next.js项目(推荐——包含Satori + PNG渲染功能)
npm install @vercel/og
npm install @vercel/og
Standalone Satori (SVG output only)
独立版Satori(仅输出SVG)
npm install satori
undefinednpm install satori
undefinedNext.js App Router — OG Image Route (Recommended)
Next.js App Router — OG图片路由(推荐)
Next.js has built-in OG image support via the re-exported from :
ImageResponsenext/ogtsx
// app/og/route.tsx OR app/opengraph-image.tsx
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
export async function GET(request: Request) {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 60,
color: 'white',
background: 'linear-gradient(to bottom, #1a1a2e, #16213e)',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
Hello, OG Image!
</div>
),
{ width: 1200, height: 630 }
)
}Next.js 通过从导出的提供内置的OG图片支持:
next/ogImageResponsetsx
// app/og/route.tsx 或 app/opengraph-image.tsx
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
export async function GET(request: Request) {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 60,
color: 'white',
background: 'linear-gradient(to bottom, #1a1a2e, #16213e)',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
Hello, OG Image!
</div>
),
{ width: 1200, height: 630 }
)
}Convention-Based OG Images (Next.js 13.3+)
基于约定的OG图片(Next.js 13.3+)
Place an or file in any route segment:
opengraph-image.tsxtwitter-image.tsxtsx
// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'
export const alt = 'Blog post image'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'
export const runtime = 'edge'
export default async function Image({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return new ImageResponse(
(
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
background: '#000',
color: '#fff',
fontSize: 48,
}}
>
<div>{post.title}</div>
</div>
),
{ ...size }
)
}Next.js auto-generates the tag for these files.
<meta property="og:image">在任意路由段中放置或文件:
opengraph-image.tsxtwitter-image.tsxtsx
// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'
export const alt = 'Blog post image'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'
export const runtime = 'edge'
export default async function Image({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return new ImageResponse(
(
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
background: '#000',
color: '#fff',
fontSize: 48,
}}
>
<div>{post.title}</div>
</div>
),
{ ...size }
)
}Next.js 会自动为这些文件生成标签。
<meta property="og:image">Standalone Satori (SVG Only)
独立版Satori(仅生成SVG)
ts
import satori from 'satori'
import { readFileSync } from 'fs'
const svg = await satori(
<div style={{ display: 'flex', color: 'black', fontSize: 40 }}>
Hello from Satori
</div>,
{
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: readFileSync('./fonts/Inter-Regular.ttf'),
weight: 400,
style: 'normal',
},
],
}
)ts
import satori from 'satori'
import { readFileSync } from 'fs'
const svg = await satori(
<div style={{ display: 'flex', color: 'black', fontSize: 40 }}>
Hello from Satori
</div>,
{
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: readFileSync('./fonts/Inter-Regular.ttf'),
weight: 400,
style: 'normal',
},
],
}
)CSS Support and Limitations
CSS支持情况与限制
Satori uses a subset of CSS with Flexbox layout (Yoga engine):
Supported:
- (default — all elements are flex containers)
display: flex - Flexbox properties: ,
flexDirection,alignItems,justifyContent,flexWrapgap - Box model: ,
width,height,padding,margin,borderborderRadius - Typography: ,
fontSize,fontWeight,fontFamily,lineHeight,letterSpacingtextAlign - Colors: ,
color,background,backgroundColoropacity - Backgrounds: (linear/radial gradients),
backgroundImagebackgroundClip - Shadows: ,
boxShadowtextShadow - Transforms: (basic transforms)
transform - Overflow:
overflow: hidden - Position: ,
absoluterelative - White space: ,
whiteSpace,wordBreaktextOverflow
Not supported:
- — use nested flex containers instead
display: grid - CSS animations or transitions
- or
position: fixedsticky - Pseudo-elements (,
::before)::after - Media queries
- CSS variables
Satori 使用CSS的子集搭配Flexbox布局(基于Yoga引擎):
支持的特性:
- (默认——所有元素均为flex容器)
display: flex - Flexbox属性:、
flexDirection、alignItems、justifyContent、flexWrapgap - 盒模型:、
width、height、padding、margin、borderborderRadius - 排版:、
fontSize、fontWeight、fontFamily、lineHeight、letterSpacingtextAlign - 颜色:、
color、background、backgroundColoropacity - 背景:(线性/径向渐变)、
backgroundImagebackgroundClip - 阴影:、
boxShadowtextShadow - 变换:(基础变换)
transform - 溢出:
overflow: hidden - 定位:、
absoluterelative - 空白处理:、
whiteSpace、wordBreaktextOverflow
不支持的特性:
- ——改用嵌套flex容器替代
display: grid - CSS动画或过渡效果
- 或
position: fixedsticky - 伪元素(、
::before)::after - 媒体查询
- CSS变量
Fonts
字体
Fonts must be loaded explicitly — there are no default system fonts:
tsx
// Load font in edge runtime
const font = fetch(new URL('./Inter-Bold.ttf', import.meta.url)).then(
(res) => res.arrayBuffer()
)
export async function GET() {
const fontData = await font
return new ImageResponse(
(<div style={{ fontFamily: 'Inter' }}>Hello</div>),
{
width: 1200,
height: 630,
fonts: [{ name: 'Inter', data: fontData, weight: 700, style: 'normal' }],
}
)
}For Google Fonts, fetch directly from the CDN or bundle the file.
.ttf必须显式加载字体——没有默认的系统字体可用:
tsx
// 在边缘运行时中加载字体
const font = fetch(new URL('./Inter-Bold.ttf', import.meta.url)).then(
(res) => res.arrayBuffer()
)
export async function GET() {
const fontData = await font
return new ImageResponse(
(<div style={{ fontFamily: 'Inter' }}>Hello</div>),
{
width: 1200,
height: 630,
fonts: [{ name: 'Inter', data: fontData, weight: 700, style: 'normal' }],
}
)
}对于Google字体,可直接从CDN获取或打包文件。
.ttfDynamic Content from URL Parameters
从URL参数获取动态内容
tsx
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const title = searchParams.get('title') ?? 'Default Title'
return new ImageResponse(
(<div style={{ display: 'flex', fontSize: 60 }}>{title}</div>),
{ width: 1200, height: 630 }
)
}tsx
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const title = searchParams.get('title') ?? 'Default Title'
return new ImageResponse(
(<div style={{ display: 'flex', fontSize: 60 }}>{title}</div>),
{ width: 1200, height: 630 }
)
}Images in OG
OG图片中的图片资源
Use with absolute URLs:
<img>tsx
<img
src="https://example.com/avatar.png"
width={100}
height={100}
style={{ borderRadius: '50%' }}
/>For local images, convert to base64 or use absolute deployment URLs.
使用标签并指定绝对URL:
<img>tsx
<img
src="https://example.com/avatar.png"
width={100}
height={100}
style={{ borderRadius: '50%' }}
/>对于本地图片,可转换为base64格式或使用绝对部署URL。
Key Patterns
核心实践模式
- Use in Next.js projects — it re-exports
next/ogwith built-in optimizationsImageResponse - Always set — Satori and
runtime = 'edge'are designed for edge runtimes@vercel/og - Use everywhere — Satori defaults to flex layout, no block or grid support
display: 'flex' - Load fonts explicitly — no system fonts are available; bundle /
.ttffiles or fetch from CDN.woff - Standard OG dimensions are 1200×630 — this is the most widely supported size
- Use convention files for automatic tags —
<meta>andopengraph-image.tsxtwitter-image.tsx - Inline styles only — Satori does not support external CSS or CSS-in-JS libraries
- 在Next.js项目中使用——它重新导出了
next/og并附带内置优化ImageResponse - 始终设置——Satori和
runtime = 'edge'专为边缘运行时设计@vercel/og - 全程使用——Satori默认采用flex布局,不支持block或grid布局
display: 'flex' - 显式加载字体——无系统字体可用;打包/
.ttf文件或从CDN获取.woff - 标准OG图片尺寸为1200×630——这是支持最广泛的尺寸
- 使用约定文件自动生成标签——
<meta>和opengraph-image.tsxtwitter-image.tsx - 仅使用内联样式——Satori不支持外部CSS或CSS-in-JS库