@vercel/ogとCloudflare Pages FunctionsでOGP画像生成APIをつくる
Cloudflare上にOGP画像生成APIをつくってみたので備忘録としてまとめます。
予備知識
- @vercel/og - OGP画像生成用の便利ライブラリ。
- Cloudflare Pages Functions - Cloudflareが提供するサーバーレスファンクションのサービス。
- @cloudflare/pages-plugin-vercel-og - @vercel/ogをPages Functionsで利用するためのプラグイン。
OGP画像生成APIをつくる
動かして確認する
まずはサンプルリポジトリのOGP画像生成APIをローカルで動かしてみます。
$ npm ci
$ npm run dev
...
[wrangler:inf] Ready on http://localhost:8088
⎔ Starting local server...
コマンドを実行したらOGP画像生成用のエンドポイントにアクセスしてみます。
http://localhost:8088/ogp
こんな画像が表示されているはず
こんどはエンドポイントにtitleとavatarクエリをつけてアクセスします。avatarにはGithubのプロフィール画像を指定しました。
http://localhost:8088/ogp?title=OGPサンプル&avatar=https://avatars.githubusercontent.com/u/44719108
title,avatarクエリの内容が反映されたOGP画像
実装をみる
まずはhttp://localhost:8088/ogp
にアクセスしたときに実行されるコードを確認します。Pages Functionsはファイルベースのルーティングとなっているため、http://localhost:8088/ogp
にアクセスするとfunctions/ogp/index.tsx
のコードが実行されます。
functions
└── ogp
└── index.tsx
index.tsx
ではonRequest関数をexportして@vercel/og
のImageResponseを返すようにします。ImageResponseに定義したJSXがそのままOGP画像になります。
Open Graph (OG) Image Generation
import { ImageResponse } from "@cloudflare/pages-plugin-vercel-og/api";
...
export const onRequest: PagesFunction = async (context) => {
...
return new ImageResponse(
/* JSXでレイアウトを定義 */
)
}
contextからクエリの値など取得できるので動的に画像を生成することもできます。
export const onRequest: PagesFunction = async (context) => {
const url = new URL(context.request.url);
const title = url.searchParams.get("title") ?? "OGP SAMPLE";
const avatar = url.searchParams.get("avatar");
...
Cloudflareにデプロイする
CloudflareにアカウントがあればOGP画像生成APIをデプロイして動作を確認することもできます。
デプロイにはWranglerというCloudflareを操作するCLIを使います。さきほどのローカルでの動作確認にもWranglerを使っていました。
...
"scripts": {
"login": "wrangler login",
"setup": "wrangler pages project create ogp-sample --production-branch main",
"clean": "rm -rf .dist",
"dev": "wrangler pages dev",
"build": "npm run clean && wrangler pages functions build --outdir=.dist",
"deploy": "npm run build && wrangler pages deploy",
"destroy": "wrangler pages project delete ogp-sample"
},
"devDependencies": {
"wrangler": "^3.57.1"
...
npm run deploy
を実行するとPages FunctionsをビルドしてCloudflareにデプロイするようnpmスクリプトを定義しました。初回の実行はプロジェクトを作成するか聞かれるのでそのままEnterを押してすすんでください。
# Cloudflareにログイン
$ npm run login
# Pages Functionsをデプロイ
$ npm run deploy
...
Compiled Worker successfully
The project you specified does not exist: "ogp-sample". Would you like to create it?"
# Enterを押す
❯ Create a new project
# Enterを押す
? Enter the production branch name: › main
...
🌎 Deploying...
✨ Deployment complete! Take a peek over at https://[デプロイ毎に固有の値].ogp-sample.pages.dev
デプロイ後に表示されるhttps://[デプロイ毎に固有の値].ogp-sample.pages.dev/ogp
にアクセスするとローカルで確認したものと同じ画像が表示されるはずです(表示されない場合は少し待ってアクセスしてみてください)。
おまけ
画像に表示する文字列にカスタムフォントを適用することもできます。
http://localhost:8088/ogp/font
へアクセスするとNoto Sans JPフォントの太字でタイトルが表示されます。詳細はfunctions/ogp/font.tsx
のコードを確認してください。
参考: @vercel/og を使って Next.js で OGP 画像を生成する仕組みを作ったお話
Discussion