技術
Satori で OG画像を作るときに詰まった3つ
Next.js の next/og は、JSX を書くと画像にしてくれます。CSS が使えるように見えるので油断しますが、描画しているのはブラウザではなく Satori です。3つ、実際に詰まりました。
1. filter: blur() は効かない
背景にぼかした光を置こうとして、単色の円に filter: blur() を当てました。ぼけません。硬い円板がそのまま出ます。
代わりに、光を地そのものに焼き込みます。2色を混ぜた不透明な色を作って、radial-gradient として地に置く形です。
// ratio は from 側の割合
function mix(from: string, to: string, ratio: number): stringここで大事なのは「透明を経由しない」ことです。次の失敗がそれです。
2. 光を別の要素に置くと、箱の縁で直線に切れる
radial-gradient を持った要素を絶対配置で重ねる、という素直なやり方も試しました。Satori では絶対配置の箱が版面で切られます。 光の途中に、まっすぐな切れ目が入ります。
地の色そのものをグラデーションにすれば、切られる箱がありません。透明な重ねをやめる、というのが結論でした。
3. フォントに渡し忘れた文字だけ、字形が変わる
Satori の標準フォントは日本語を持ちません。必要な文字だけを Google Fonts から取ってきて渡す形にしています。取得する URL に、描く文字列をそのまま入れます。
https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@700&text=<描く文字すべて>問題は、渡し忘れた文字だけが Satori の既定フォントに落ちることです。エラーにはなりません。同じ一行の中でウェイトも字形も食い違った画像が、黙って出ます。
対策は仕組みのほうに入れました。カードを描く関数が、描画する文字列を1式にまとめてからフォントを取りに行きます。カードを増やしても、その関数を通るかぎり渡し忘れようがありません。
- 文字を足したら、フォントに渡す文字列にも足す —— ではなく
- 描く文字列とフォントに渡す文字列を、同じ1つの式にする
ついでに踏んだこと
カードそのものの話ではありませんが、同じ時期にもう1つ壊しました。プロダクトのページの layout に openGraph を書いたところ、親の共有カードが引き継がれなくなり、og:image が消えました。
そちらは別に書いています —— X は og: ではなく twitter: を読む。