@vercel/og Pages Plugin は、Web ページのソーシャル画像を描画するミドルウェアです。任意の画像を作る API も含まれます。
名前のとおり、@vercel/og ↗ を使います。この Plugin と基盤の Satori ↗ ライブラリは、Vercel チームが作成しました。
@vercel/og Pages Plugin をインストールするには、次を実行します。
npm i @cloudflare/pages-plugin-vercel-ogyarn add @cloudflare/pages-plugin-vercel-ogpnpm add @cloudflare/pages-plugin-vercel-ogbun add @cloudflare/pages-plugin-vercel-ogimport React from "react";
import vercelOGPagesPlugin from "@cloudflare/pages-plugin-vercel-og";
interface Props {
ogTitle: string;
}
export const onRequest = vercelOGPagesPlugin<Props>({
imagePathSuffix: "/social-image.png",
component: ({ ogTitle, pathname }) => {
return <div style={{ display: "flex" }}>{ogTitle}</div>;
},
extractors: {
on: {
'meta[property="og:title"]': (props) => ({
element(element) {
props.ogTitle = element.getAttribute("content");
},
}),
},
},
autoInject: {
openGraph: true,
},
});Plugin は 6 つのプロパティを持つオブジェクトを受け取ります。
-
imagePathSuffix: 生成した画像を公開するパスのサフィックスです。たとえば、この Plugin をfunctions/blog/_middleware.tsにマウントし、imagePathSuffixを/social-image.pngに設定し、/blog/hello-worldページがある場合、画像は/blog/hello-world/social-image.pngで利用できます。 -
component: 画像の描画に使う React コンポーネントです。デフォルトでは、対象 Web ページのパス名(例:/blog/hello-world)と同じpathnameプロパティが渡されます。extractorsオプションで、より動的なプロパティも渡せます。 -
extractors: 省略可能なオブジェクトで、省略可能なプロパティが 2 つあります。onとonDocumentです。それぞれ、オブジェクトを受け取り、HTMLRewriterの要素ハンドラー または ドキュメントハンドラー を返す関数を設定できます。オブジェクト引数を書き換えると、React コンポーネントに追加のプロパティを渡せます。上の例では、要素ハンドラーで Web ページからog:titleメタタグを取り出し、ogTitleプロパティとして React コンポーネントへ渡します。対象 Web ページの値を使う動的画像を作るときの主な仕組みです。 -
options:@vercel/ogライブラリへそのまま渡す、省略可能なオブジェクト ↗ です。 -
onError:Response、またはResponseの Promise を返す省略可能な関数です。imagePathSuffixへのリクエストがあり、extractorsが指定されているのに、対象 Web ページが有効な HTML でないときに呼ばれます。デフォルトは404レスポンスです。 -
autoInject: 省略可能なオブジェクトで、省略可能なプロパティopenGraphがあります。trueにすると、Plugin は対象 Web ページにog:image、og:image:height、og:image:widthメタタグを自動で設定します。
この Plugin の API を使って、ミドルウェアとしてだけでなく、任意の画像も生成できます。
たとえば、次のコードは "Hello, world!" と書かれた画像を生成し、/greet で利用できます。
import React from "react";
import { ImageResponse } from "@cloudflare/pages-plugin-vercel-og/api";
export const onRequest: PagesFunction = async () => {
return new ImageResponse(
<div style={{ display: "flex" }}>Hello, world!</div>,
{
width: 1200,
height: 630,
}
);
};これは、基盤の @vercel/og ライブラリ ↗ が提供する API と同じです。