- チュートリアル
- 画像
Next.jsのImage Generationを利用して、動的にOG画像を作成する
このチュートリアルでは、Next.jsの Image Generation を利用して、動的にOG画像を作成する手順を紹介します。
記事内で使用している主なソフトウェアのバージョン
- Next.js(
next
): 13.3.0
前提条件
- Next.jsの13.3.0以上を利用していること
- Next.jsの API Routes について理解していること
- Vercelへのデプロイについて理解していること
- OG画像を利用するWebサイトを作成していること
概要
Next.jsの Image Generation を利用して、OG画像を生成するAPIを作成します。
ImageResponse
はEdge Runtime を利用します。
リクエストのクエリパラメータにタイトルを付け、タイトルをOG画像に反映するようにします。
以下のようなOG画像を作成できます。
「Fictitious Communityが 〜 主催したか」の部分がタイトルとなります。
1. OG画像を生成するAPIを作成する
1-1. pages/api/og.tsx の作成
OG画像を生成するAPIにアクセスすると、画像を返却するようにします。
また、クエリパラメータに title
をつけると、その値をもとにOG画像を作成できるようにします。
ここでは、エンドポイントが /api/og
となるように、pages/api/og.tsx
というファイルを用意します。この処理では、以下のことを行います。
- Edge Runtime を利用するために、Edge API Routes として、configの
runtime
にedge
を指定する - クエリパラメータの
title
の値を利用して、動的にタイトルを表示する - HTMLとCSSでOG画像のデザインをマークアップする
- 背景画像として、以下の画像を使う(以下のコードでは
https://og-image-example.vercel.app/bg.png
から画像が取得できる想定とします。背景画像が不要な場合は、backgroundImage
のプロパティを削除して下さい)
// pages/api/og.tsx
import { ImageResponse, NextRequest } from "next/server";
export const config = {
runtime: "edge",
};
export default function handler(req: NextRequest) {
try {
const { searchParams } = new URL(req.url);
const hasTitle = searchParams.has("title");
const title = hasTitle
? searchParams.get("title")?.slice(0, 100)
: "My default title";
return new ImageResponse(
(
<div
style={{
backgroundImage: "url(https://og-image-example.vercel.app/bg.png)",
backgroundColor: "#fff",
backgroundSize: "100% 100%",
height: "100%",
width: "100%",
display: "flex",
textAlign: "left",
alignItems: "flex-start",
justifyContent: "center",
flexDirection: "column",
flexWrap: "nowrap",
}}
>
<div
style={{
width: "100%",
fontSize: 60,
fontStyle: "normal",
fontWeight: "bold",
color: "#000",
padding: "0 120px",
lineHeight: 1.3,
marginBottom: "30px",
wordWrap: "break-word",
}}
>
{title}
</div>
<div
style={{
width: "100%",
fontSize: 40,
fontStyle: "normal",
fontWeight: "bold",
color: "#000",
padding: "0 120px",
lineHeight: 1.3,
}}
>
✏️ OG Image Examples
</div>
</div>
),
{
width: 1200,
height: 630,
}
);
} catch (e: any) {
console.log(`${e.message}`);
return new Response(`Failed to generate the image`, {
status: 500,
});
}
}
マークアップから画像への変換には、Satori というライブラリが使用されています。通常のブラウザとは対応しているCSSプロパティが異なるため注意が必要です。詳細は Satori のドキュメントをご確認ください。
1-2. ローカル環境での確認
ローカル環境で正しく実行されるか、確認してみましょう。以下のURLにアクセスします。
http://localhost:3000/api/og?title=テスト
以下のように表示されれば成功です。
1-3. 本番環境へのデプロイ
ローカル環境で確認できたら、Vercelにデプロイしておきます。
2. APIを呼び出し、OG画像を設定する
次に、OG画像を設定したいサイトから、1で作成したAPIを呼び出すようにします。
※以下、1-3でデプロイしたAPIのエンドポイントは https://og-image-example.vercel.app/api/og
と想定します。
<meta>
タグの中にOG画像のURLを設定しましょう。
<head>
<title>The post's title</title>
<meta
property="og:image"
content="https://og-image-example.vercel.app/api/og?title=my post title"
/>
</head>
Newt-Inc/newt-blog-starter-nextjs から呼び出す場合、以下のようになります。
// pages/article/[slug].tsx
//(省略)
export default function ArticlePage({
app,
currentArticle,
}: {
app: AppMeta;
currentArticle: (Content & Article) | null;
}) {
//(省略)
const ogImage = useMemo(() => {
return `https://og-image-example.vercel.app/api/og?title=${currentArticle.title}`;
}, [currentArticle.title]);
//(省略)
return (
<Layout app={app}>
<Head>
<!--(省略)-->
<meta property="og:image" content={ogImage} />
<!--(省略)-->
</Head>
<!--(省略)-->
</Layout>
);
}
コードを修正したら、デプロイを行い、本番環境に反映します。
以上で、設定は終了です。
これで、動的にOG画像を作成できるようになりました。