【Next.js】satoriを使ってJSXからOGP画像を動的に生成する
やりたいこと
SNSなどで共有された時にアイキャッチとして表示されることから、一種のSEO対策とも言えるOGP(Open Graph Protcol)画像。
QiitaやZennのようなサービスだとそのOGP画像が動的に生成されるが、当サイト(Next.js製のSPA)でもそれを実現したい。
実装方法
Metadata Files APIの場合
Next.js 13.3から追加されたMetadata Files APIを利用すれば、任意のルート下にjsxファイルを作成しそこでImageResponse
を返すだけで、わざわざ画像へのパスを指定することもなく実現できる。
1. ファイルの作成
まずopengraph-image.tsx
を作成し、OGP画像を設定したいルート下に配置する。
2. 画像の生成
あとは公式サイトの方法に沿って任意の画像をjsx記法で実装し、ImageResponse
を返すだけ。
ImageResponse
での画像生成は内部でsatoriを使用しているため、指定できるスタイルはsatoriのドキュメントから確認できる。
3. metaタグが出力される
すると自動的にOGPのためのmeta
タグが出力される。
実際にhttp://localhost:3001/opengraph-image?xxx
にアクセスしてみると、記事タイトルが埋め込まれた画像が返されることを確認。
これで/blog/[slug]
に全て動的なOGP画像が設定された。
build前に生成する場合
OGP画像用のルートを用意するのではなく、画像として事前に生成したい場合。この方法だとGitで管理できるというメリットがある。
今回はbuild(static export)時に全記事のOGP画像を生成し/public/img/<特定の記事ディレクトリ>
下に配置する、という場合を想定して実装してみる。
1. satoriをインストール
HTML・CSSからSVGを生成できるvercel製のライブラリsatoriとそれをPNGに変換するためのsharpをインストールする。
2. 画像を生成し書き出す
今回は任意のフォントや画像を使用してみる。
- jsx記法で画像の要素を指定し、SVG画像を生成
readFileSync
で任意のフォントを読み込み適用する
sharp
でPNGに変換- 指定したパスに画像を書き出す
3. 全記事の画像を生成
先ほど実装したOGP画像生成を記事の数だけ行う必要がある。
そこで当サイトの場合はgenerateStaticParams
の中で全記事のルートを生成するついでに画像を生成するようにした。
すると/public/img/<特定の記事ディレクトリ>
下に無事画像が生成された 🎉