OGP画像を App Router 以降の Next.js の Static Export で動的に出力するコツ
こんな風な出力を SNS で実現するものです。
Next.js で OGP 画像を動的に出力する方法はインターネット上で検索をすればいろいろ見つかりますが、実際のところ App Router 以降で書かれていなかったり、Static Export 前提で書かれていなかったりして、いろいろ悪戦苦闘したりします。
なので、今回はちょっとメモ代わりにコツを書いておきます。
ImageResponse は next/og から import する
ImageResponse は Next.js 14 から next/og からの import に変更されました。
import { ImageResponse } from "next/og";
ドキュメント上でもサンプル上で記載があります。
画像を使う場合
画像なのですが、 Static Export を使う場合いろいろと制約があるようで、単に import する場合やバイナリを取得する方法などいずれもエラーが出て解決しなかったため、現状は base64 にして組み込むという方式をとっています。
const OgpBackground = () => {
return (
<img
alt=""
style={{ display: "flex", position: "absolute", top: "0", left: "0" }}
src={
"data:image/png;base64,iVBORw...CYII="
}
/>
);
};
export default OgpBackground;
今後引き続き最適解を調査していこうと思いますが、一旦この方法で。
Google Font の利用について
Google Font の利用については Use fs (Node.js only) or fetch to read the font as Buffer/ArrayBuffer and provide data here.
と公式ドキュメントにあるとおり、ArrayBuffer を Google Fonts API から取得して渡してやる必要があります。以下のブログ記事が参考になりました。ありがとうございました。
レイアウトは一苦労
div の Style は display: flex
もしくは display: none
でないといけないらしく、そうでない場合、以下のエラーが出ます。
Error: Expected <div> to have explicit "display: flex" or "display: none" if it has more than one child node.
デザイン自体は Figma で行い、テンプレートとして利用しました。
通常の HTML とはちょっと異なるまどろっこしいレイアウトをする必要がありますが、試行錯誤して形になりました。
特に気を付ける点をしては、Markdown を表示したいと思った場合に上記エラーに遭遇したりします。