#Next.js#OGP#OpenNext#Cloudflare#Edge Runtime#運用

作品詳細の動的OGP生成で詰まったポイントと解決策

orimemo開発チーム
5 min read

作品詳細ページのOGPを「情報量の多い動的画像」にしたい、という要件から実装を進めたところ、 Next.js + OpenNext/Cloudflareの組み合わせでいくつか落とし穴がありました。 本記事では 何が起きたか / どう直したか / なぜその設計にしたか / そもそも標準的にはどうあるべきか を整理します。

背景

  • 作品詳細ページのOGPを、タイトルだけでなく作者・紙・難易度などの作品情報を見せる画像にしたい
  • 作品データはDBから取得可能だが、クローラが確実に取得できるOGPにしたい
  • 公開/非公開や権限の影響を受けない安全なOGP生成が必要

そこで、ページ側でOGP表示用パラメータを先に作り、/api/og/works にクエリとして渡して画像を生成する方式にしました。

起きた技術的問題

1. Edge Runtimeで ImageResponse が「コンストラクタではない」エラー

ローカルで runtime = 'edge' のままOGP APIを叩くと、以下のエラーが発生しました。

TypeError: OGImageResponse is not a constructor

OpenNext/Cloudflare環境では next/og のEdge実装がスタブになっており、 ImageResponse が実体を持たず、関数として解決されてしまうために起きる症状でした。

2. Node RuntimeでもWebAssemblyが壊れていた

runtime = 'nodejs' に切り替えても以下のエラーが出ました。

WebAssembly.instantiate(): expected 4 bytes, fell off end @+0

調査すると node_modules/next/dist/compiled/@vercel/og 配下の resvg.wasm / yoga.wasm1 byte になっており、壊れていました。 (依存の取得失敗・破損が原因)

どう解決したか

1. Node RuntimeでOGP生成

OpenNext/Cloudflare環境でEdgeがスタブになるため、runtime = 'nodejs' に切り替えました。 (Vercel環境ならEdgeで動くのが標準ですが、OpenNextでは要調整)

2. wasmが壊れている場合はフォールバック

resvg.wasm / yoga.wasm のサイズをチェックし、壊れていたら静的OGPへリダイレクト。 ImageResponse のimportが失敗しても落ちないようにガードしました。

どうよくなったのか

  • 作品詳細のOGP画像がタイトル・作者・用紙・難易度・タグなどを含むリッチなものに
  • DB不要のクエリベースOGP生成で、クローラが確実に取得可能
  • パラメータが欠けても レイアウト崩れしないフォールバック
  • 壊れた環境でも 静的OGPに自動退避して落ちない

設計意図(なぜこの方式にしたか)

OGP生成は「外部クローラが確実に叩ける」ことが最優先

OGPはSNSクローラが取得するため、

  • Cookie/認証が前提になるDBアクセスを避ける
  • 速度・安定性優先でクエリパラメータだけで生成
  • 欠損があっても壊れない

という方針にしました。

作品詳細ページで先にOGP用データを整理

generateMetadata 内でDBから取得した情報を整理し、 OGPエンドポイントに 必要十分なパラメータ を渡す設計にしています。

標準的にはどうあるべきか(この技術スタックの場合)

Next.js App Router + OpenNext/Cloudflare という前提での「標準」に近い指針は以下です。

  1. OGP生成は next/ogImageResponse を使うのが王道
    • ただし Cloudflare/OpenNext では Edge 実装がスタブになる場合があるため注意
  2. Edgeが使えない場合はNode Runtimeに切り替える
    • その場合は wasmの配布状態を必ずチェック
  3. OGP URLは絶対URLにする
    • metadataBase / getSiteUrl() を活用
  4. OGPは認証に依存しない設計
    • クローラに確実に返すために、事前生成 or クエリ渡しが安全
  5. フォールバックを用意する
    • 生成失敗時に静的OGPへ落ちる設計が安定運用の鍵

まとめ

  • Next.js + OpenNext/Cloudflareでは ImageResponse のEdge実装が使えないケースがある
  • Node Runtimeに切り替えても wasm が壊れていると落ちる
  • そのため 実行環境の差を考慮したフォールバック設計が必須
  • OGPは「クローラが確実に取得できる」ことを最優先にしたほうが安定する
o

orimemo開発チーム

orimemoの技術的な側面を深掘りし、実装の舞台裏をお届けしています。 フィードバックや質問があれば、GitHubでお気軽にお声がけください。

関連記事