ImageResponse

ImageResponse 建構子允許你使用 JSX 和 CSS 來生成動態圖片。這對於生成社群媒體圖片(如 Open Graph 圖片、Twitter 卡片等)非常有用。

參考

參數

ImageResponse 可使用以下參數:

import { ImageResponse } from 'next/og'

new ImageResponse(
  element: ReactElement,
  options: {
    width?: number = 1200
    height?: number = 630
    emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' = 'twemoji',
    fonts?: {
      name: string,
      data: ArrayBuffer,
      weight: number,
      style: 'normal' | 'italic'
    }[]
    debug?: boolean = false

    // 將傳遞給 HTTP 回應的選項
    status?: number = 200
    statusText?: string
    headers?: Record<string, string>
  },
)

範例可在 Vercel OG Playground 中找到。

支援的 HTML 和 CSS 功能

ImageResponse 支援常見的 CSS 屬性,包括 flexbox 和絕對定位、自訂字體、文字換行、置中以及嵌套圖片。

請參考 Satori 的文件 以查看支援的 HTML 和 CSS 功能清單。

行為

  • ImageResponse 使用 @vercel/ogSatori 和 Resvg 將 HTML 和 CSS 轉換為 PNG。
  • 僅支援 flexbox 和部分 CSS 屬性。進階佈局(例如 display: grid)無法使用。
  • 最大套件大小為 500KB。套件大小包括你的 JSX、CSS、字體、圖片和其他任何資源。如果超過限制,請考慮減少資源大小或在執行時獲取。
  • 僅支援 ttfotfwoff 字體格式。為了最大化字體解析速度,ttfotfwoff 更推薦。

範例

路由處理器

ImageResponse 可用於路由處理器中,以在請求時動態生成圖片。

app/api/route.js
import { ImageResponse } from 'next/og'

export async function GET() {
  try {
    return new ImageResponse(
      (
        <div
          style={{
            height: '100%',
            width: '100%',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            backgroundColor: 'white',
            padding: '40px',
          }}
        >
          <div
            style={{
              fontSize: 60,
              fontWeight: 'bold',
              color: 'black',
              textAlign: 'center',
            }}
          >
            Welcome to My Site
          </div>
          <div
            style={{
              fontSize: 30,
              color: '#666',
              marginTop: '20px',
            }}
          >
            Generated with Next.js ImageResponse
          </div>
        </div>
      ),
      {
        width: 1200,
        height: 630,
      }
    )
  } catch (e) {
    console.log(`${e.message}`)
    return new Response(`Failed to generate the image`, {
      status: 500,
    })
  }
}

基於檔案的元數據

你可以在 opengraph-image.tsx 檔案中使用 ImageResponse,以在構建時或請求時動態生成 Open Graph 圖片。

app/opengraph-image.tsx
import { ImageResponse } from 'next/og'

// 圖片元數據
export const alt = 'My site'
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// 圖片生成
export default async function Image() {
  return new ImageResponse(
    (
      // ImageResponse JSX 元素
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        My site
      </div>
    ),
    // ImageResponse 選項
    {
      // 為方便起見,我們可以重複使用匯出的 opengraph-image
      // 大小配置來設定 ImageResponse 的寬度和高度。
      ...size,
    }
  )
}

自訂字體

你可以通過在選項中提供 fonts 陣列來在 ImageResponse 中使用自訂字體。

app/opengraph-image.tsx
import { ImageResponse } from 'next/og'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'

// 圖片元數據
export const alt = 'My site'
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// 圖片生成
export default async function Image() {
  // 字體載入,process.cwd() 是 Next.js 專案目錄
  const interSemiBold = await readFile(
    join(process.cwd(), 'assets/Inter-SemiBold.ttf')
  )

  return new ImageResponse(
    (
      // ...
    ),
    // ImageResponse 選項
    {
      // 為方便起見,我們可以重複使用匯出的 opengraph-image
      // 大小配置來設定 ImageResponse 的寬度和高度。
      ...size,
      fonts: [
        {
          name: 'Inter',
          data: interSemiBold,
          style: 'normal',
          weight: 400,
        },
      ],
    }
  )
}

版本歷史

版本變更
v14.0.0ImageResponsenext/server 移至 next/og
v13.3.0ImageResponse 可從 next/server 匯入。
v13.0.0ImageResponse 通過 @vercel/og 套件引入。

On this page