@vercel/og で動的な画像を生成するガイド【Next.js】
はじめに
現在、Next.js で、フルスタックアプリを構築しています。
@vercel/og
は、Next.js 開発においては、広く浸透しているかと思いますが、
発表されて以来、継続的なアップデートが行われてきたようです!
そこで今回は、
改めて、@vercel/og
について調べたので、結果をまとめました。
時間の節約になれば、嬉しいです :)
検証環境:
・Next.js v14.2.5/ App Router
@vercel/og とは?
OG Image Generation(@vercel/og
)は、2022 年 10 月に vercel より発表されました。
上記のリリースブログから引用すると、
ダイナミックなソーシャルカード画像を生成するための新しいライブラリである Vercel OG Image Generation を発表できることを嬉しく思います。
このアプローチは、Vercel Edge Functions、WebAssembly、および HTML/CSS を SVG に変換するためのまったく新しいコアライブラリを使用することで、既存のソリューションよりも 5 倍高速です。
つまり、
@vercel/og
を使うことで、HTML/CSS のコードから、簡単に画像を生成することが可能です!
主なユースケースとしては、
ページ毎に動的な OG 画像を生成する実装が、挙げられます。
@vercel/og の特徴
上記の vercel の公式ドキュメントより、
@vercel/og
の特徴を、紹介します!
@vercel/og の実行環境
この記事の執筆時点(2024/08/23)で、
@vercel/og
は、下記でサポートされています:
- Edge ランタイム
- Node.js ランタイム
開発元が、Vercel なので、Vercel や Next.js アプリとの相性が良いのは当然ですね。
ただ、Cloudflare など、その他の環境でも動作します!
(筆者は、GitHub Pages, Vercel, Cloudflare の環境で、動作することを確認しました)
導入としては、
Next.js/App Router の場合は、デフォルトで組み込まれています。
以下のコマンドより、インポート可能です:
import { ImageResponse } from "next/og";
Next.js/App Router 以外の場合は、
以下のコマンドより、ライブラリを導入できます:
npm i @vercel/og
@vercel/og の技術的な詳細: Satori と resvg
@vercel/og
の画像生成は、以下のような処理が行われています:
なので、@vercel/og
に依存したくない場合は、直接Satori
を導入して使うことも可能です。
ちなみに、Satori
も Next.js と同じく、vercel が開発しているライブラリです!
公式より、デモサイトが用意されています。
JSX コードからの画像生成を試せるので、satori
や@vercel/og
の雰囲気をつかめます!
ImageResponse: Next.js で動的な画像を生成する手順
実際に、Next.js/ App Router で、
動的な画像を生成する手順を紹介します!
ImageResponse コンストラクタを使用すると、JSX と CSS を使用して動的画像を生成できます。
これは、オープングラフ画像、Twitter カードなどのソーシャルメディア画像を生成するのに便利です。
ドキュメントから引用した通り、ImageResponse
をインポートすることで、簡単に使用できます!
また、実際に ImageResponse
を用いて、動的な OG 画像を生成する場合は、
Next.js (App Router)の、ファイルベースの設定を利用できます!
上記の、Next.js のファイル規約に従い、
ルートセグメントに、 opengraph-image.'(js|ts|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() {
// 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,
},
],
}
);
}
ImageResponse
のコードの部分を簡略化して解説すると、以下のようになります:
import { ImageResponse } from 'next/og'
new ImageResponse(
// 第1引数に、画像に変換したいJSXを受け取る
element: ReactElement,
// 第2引数に、サイズやフォントなどのオプションを受け取る
options: {
width?: number = 1200
height?: number = 630
emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' = 'twemoji',
fonts?: {
~~
}
)
こう見ると、シンプルですね 😎
(なお、OG 画像を作成する場合の推奨サイズは、1200x630 ピクセルです。)
他にも、デフォルトで、様々なカスタマイズができます:
-
{title}
など、動的な値を使用可能 - デザインに画像を使用できる
- 絵文字やテキストのフォントの変更
- TailwindCSS でスタイルを記述することも可能
より詳細な、ImageResponse
のオプションに関しては、下記の公式ページも参照ください!
ImageResponse
で楽しげなステッカーを作る
おまけ:上述した通り、ImageResponse
を使えば、
HTML & CSS をベースに、柔軟に画像を生成できます!
なので、OG 画像以外にも、楽しげなステッカーを作って遊んでみました 📦
動的な絵文字を受け取ったり、
GitHub/ ソースコード
figma でデザインしたsvg
画像をベースに、動的なメッセージを受け取ったり、、
GitHub/ ソースコード
デザインやコーディングの練習にもなって、楽しいですね!
おわりに
最後まで読んでいただだき、ありがとうございます 🥳
下記の開発中に、調べたことの記録のような記事ですが、
少しでも参考になれば、嬉しいです!
そして、オリジナルのフリー LGTM 画像を生成できる、オープンソースのサイトを、
リリースしました 🎉📦
よかったら、チェックしてみてください!
Happy Hacking :)
参考
もし、間違いや補足情報などがありましたら、ぜひコメントを追加してください!
Discussion