Help us understand the problem. What is going on with this article?

vercel/og-imageを使ったブログOGPの簡単自動生成

この記事はDeNA 21 新卒 Advent Calendar 2020の8日目の記事です。

こんにちは、@p1assです。

皆さんはブログのOGP画像をどのように生成しているでしょうか?
以前の私はGIMPを使って手動で作成していたのですが、手動で作るのは手間で、どうにかして自動化できないかと模索していました

今回は、そんな中見つけたvercel/og-imageというOSSを紹介します。vercel/og-imageを使えば、OGP画像を生成するサーバを簡単に作成できます。OGP画像の自動生成に興味のある方の参考になれば幸いです。

なお、この記事のスコープは『URLやクエリパラメータを指定すると画像が返ってくる』ところまでで、SPAでどう動的に表示させるかといった話は含んでいません。(私のブログがHugoを使って静的に書き出しているからです)

OGP画像生成に求めるもの

OGP画像生成に求める要件は人によって異なると思います。私の場合、ブログOGPの画像生成に求めるのは次の3点でした。

  • タイトル文章から画像が自動生成される
  • 記事ごとに個別の画像は不要
  • デザインをカスタマイズできる

私のブログはバックエンドの記事が多いので、「個別の画像をOGPに入れたい」といった要件は不要です。タイトル文章から良い感じに生成されてくれたらOKです。

デザインはそこまで凝る予定はないですが、どうせなら自分オリジナルなものを作りたいです。

vercel/og-iamgeの概要

要件を満たすものを調査する中で見つけたのが、vercel/og-imageでした。vercel-ogimageはNext.jsで有名なVercel社が公開している"Open Graph Image as a Service"です。

og-imageへのリンク

vercel/og-iamgeは次のような特徴があります。

  • URL・クエリパラメータを指定することで生成画像が変化
  • テンプレートHTMLをいじることで自由に生成する画像のデザインを変更可能
  • vercel コマンドで簡単にVercelにデプロイ
  • Vercelにデプロイすると自動でCDNが設定

画像生成が簡単なのも便利ですが、特にPaaSであるVercelに簡単にデプロイできるところが魅力で、Cloud Functionsなどで自前で構築するよりもはるかに簡単に運用できます。

画像生成の例は次の公式exampleから確認できます。
https://og-image.vercel.app/

スクリーンショット 2020-12-04 12.06.13.png

左のメニューからパラメータを変更することで、生成する画像が変化します。
また、画像をクリックすることで画像URLをコピーでき、どのようなパラメータがURLやクエリパラメータに渡っているのか確認できます。

例: デフォルトで設定されているHello World画像のURL

https://og-image.vercel.app/**Hello**%20World.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fvercel-triangle-black.svg

詳しいデプロイ方法はリポジトリのREADMEを参考にしてください。

vercel/og-imageを使う上での注意点

vercel/og-imageを使う上でいくつかハマった点があるので共有します。

日本語フォントがない

Vercelにはデフォルトで日本語フォントが用意されていません。
Google FontsなどからWebフォントを読み込むようにテンプレートを変更する必要があります。

https://github.com/p1ass/og-image/blob/main/api/_lib/template.ts#L25

デフォルトのCache-Controlが1年

vercel/og-imageのデフォルトのCache-Controlは1年にセットされています。

res.setHeader('Cache-Control', 'public, immutable, no-transform, s-maxage=31536000, max-age=31536000');

https://github.com/vercel/og-image/blob/main/api/index.ts#L22

VercelのCDNはデプロイのたびにキャッシュがパージされるので一見問題ないように思えます。
しかし、TwitterのOGPサーバがCache-Controlを見てOGPをキャッシュしているようで、「デプロイしなおしてもTwitterで表示される画像が変わらない」という問題が発生します。
この問題はTwitterのCard Validatorを使っても解決しないので非常に厄介です。

私は一度、日本語フォントがない状態で生成されたOGPがCache-Contorol1年でTwitterにキャッシュされてしまい、全てのOGPが真っ白になってしまいました。
対応としては、Cache-Controlを短くした後、画像URLにプレフィックスをつけてデプロイし直し、誤ってTwitterにキャッシュされた画像が使われないようにしました。

他のOGP画像生成方法との比較

vercel/og-imageにもOGP画像を生成する方法はいくつか存在します。
その中でよく聞く方法をピックアップしてみました。

Cloud Functionsを使った画像生成

FirebaseCloudFunctionsとcanvasだけで動的にOGP画像を生成し2020年を生き延びようで紹介されている方法です。

metaタグにCloud FunctionsのURLを設定しているあたりはvercel/og-imageと同じです。画像のキャッシュのためにCloud Storageにキャッシュしているのが特徴です。

Vercelが無料なのは個人用途だけなので、会社で実装する場合はCloud Functionsの方がお金周りの観点から楽だと思います。

個人用途では、自分でデプロイパイプラインを構築する必要がないvercel/og-imageの方が楽に運用できるでしょう。

Cloudinaryを使った画像生成

Cloudinaryで動的にOGP画像を生成する方法で紹介されている手法です。

CloudinaryもVercelと同様に無料プランが用意されており、個人用途には有用です。
また、SaaSなので運用の手間が減るのもグッドポイントです。

テンプレートのカスタマイズの観点からだと、vercel/og-imageはHTMLが使えて柔軟性が高いので、少し凝ったデザインをしたいならvercel/og-imageの方が良いのではないでしょうか?
逆にそこまでこだわらないのなら、Cloudinaryを選択するのもアリだと思います。

最後に

この記事では、vercel/og-imageを中心にブログのOGP画像の生成方法について紹介しました。vercel/og-iamgeは本当に便利なのでぜひ使ってみてください!
「他にもこんなやり方があるよ」って方はTwitterやはてブなどでコメントしていただけると助かります。

明日のDeNA 21 新卒 Advent Calendar 2020の担当はfiordさんです。

アドベントカレンダーの更新情報などはDeNA 公式 Twitter アカウント @DeNAxTech で発信しているのでこちらもぜひチェックしてみてください!Blog 記事だけでなく色々な勉強会での登壇資料も発信しています。
Follow @DeNAxTech

p1ass
サーバサイドエンジニア。最近はGoをよく書いています。 ブログ : https://blog.p1ass.com
https://p1ass.com
dena_coltd
    Delight and Impact the World
https://dena.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away