TL;DR
- Satori にはカスタムフォントを使えるようにする機能がある
- Google Fonts の Developer API を使うとフォントファイルの置かれている URL が入手できる
- API キーが必要、API の rate limit は無制限
- これを fetch して Buffer を Satori に与えれば Google Fonts が使えるようになる
- サンプルコード: https://gist.github.com/TrpFrog/70c28ad13ccb951337b81e55054b70f8
モチベーションと方針
このサイトでは OGP 生成に Next.js の ImageResponse を使っています。例えばこの記事の OGP 画像は https://trpfrog.net/blog/google-fonts-on-satori/og-image にあります。
これらは記事ごとに手作業で作成しているのではなく、自動的に生成しているものです。これを実現するために Next.js の ImageResponse を使用しています。
例えば次のようなイメージです。(実際はもう少し複雑な処理をしていますが)
2023/10/27 追記:
Next.js 14 で ImageResponse を next/og から import するようになったのでこちらのコードも変更しました。
OGP 画像をこだわって作ると、フォントにもこだわりたい気持ちが出てきます。 Google Fonts が使えると嬉しいです。
Next.js の ImageResponse で内部的に使われているであろう JSX-to-SVG のライブラリ vercel/satori にはカスタムフォントを使用する機能があります。しかし、デフォルトで Google Fonts からフォントを読み込む機能はありません。
vercel/satori の issues には Google Fonts からフォントファイルをダウンロードすることで実現している方もいましたが、個人的にはリポジトリにフォントはあまり設置したくない気持ちがあります。(デカいので)
そこで、Google Fonts の Developer API を使います。Developer API ではフォントの配布先リンクを取得できます。これを使って Google Fonts からフォントデータをダウンロードし、Satori に渡してこの問題を解決したいと思います。
実装
まず、以下のようにしてフォント情報を fetch します。
'M PLUS Rounded 1c' の部分は好きなフォント名に変えてください。
API キーは Developer API のページ の「Get a Key」から入手できます。(もしかしたら Google Cloud への登録が必要かも?)
API キーが求められているので rate limit が設けられていると思ったのですが、どうやら無制限のようです。気にせず使ってよさそうです。(参考: https://github.com/google/fonts/issues/4589)
info には次のような JSON が入っているはずです。
ここから使いたい weight のフォントだけを拾ってきて fetch します。
最後に fetch したフォントデータの入っている ArrayBuffer を Satori に渡して SVG を生成します。(Next.js の ImageResponse を使う場合は await satori(...) を new ImageResponse(...) に読み替えてください)
生成した SVG は fs.writeFileSync 等でファイルに出力すると確認できます。
確かに Google Fonts を使って生成できていることが確認できました。
注意点
Next.js でやる場合、フォントデータはデカいのでキャッシュされないことがあります。(2MB を超えるので)
その場合、以下のようにすると warning を消すことができます。
サンプルコード
https://gist.github.com/TrpFrog/70c28ad13ccb951337b81e55054b70f8
