ブログを始めて1ヶ月で11記事書いたが、OGP画像はデフォルトの1枚だけだった。 SNSでシェアされてもどの記事も同じ画像が出る。記事の内容が画像から伝わらない。
AIエージェントに記事ごとのOGP画像を作ってもらった。生成からHugoの実装まで全部任せた。 人間がやったのは、できたものを見て2回指摘を返すことだけだった。
渡した指示
最初に渡した指示はこれだけだった。
記事ごとのOGP画像を生成してほしい。 全体のWebデザインの雰囲気を壊さないようにしつつ、記事の内容やテーマに合った画像を作成してください。
デザインのトークンも、サイズも、ファイルの置き場所も指定していない。 AIエージェントが自分でサイトのCSSと既存デザインを読んで、色とフォントとレイアウトのトーンを把握すると期待した。
あがってきたもの
AIエージェントは11記事分のOGP画像を一度に作ってきた。
各記事のSVGソースと、それを1200x630のPNGにラスタライズしたペア。 デザインは先日Hallmarkで刷新したサイトのトーンに合わせてあった。 ペアイエローの背景に、ブルーと赤のアクセント、太いボーダーとオフセットシャドウ。 記事の内容を図解する要素がそれぞれに入っている。
たとえばHallmarkでブログを刷新した記事のOGPは、階段状のパスとノードで「3回作り直した」過程を図示している。 Homebrewの自動更新記事なら、ターミナルとパッケージのアイコンが配置されている。
同時に、全記事のfront matterに image: フィールドが追加され、HugoのビルドでOGPメタデータが出力されるようになっていた。
レビュー1回目: 文字の角度が壊れていた
できたPNGを確認すると、文字の位置と角度がおかしかった。 SVGでは正しく配置されているのに、PNGに変換したときにずれていた。
「SVG内の文字の位置や角度が正しくPNG画像に反映されていない」と伝えた。
AIエージェントはここから自力で診断を始めた。
SVGをラスタライズした結果とコミット済みのPNGをピクセル単位で比較し、差分を可視化した。
原因は、SVGの transform 属性の解釈がラスタライザとPNG出力で一致していなかったことだった。
修正後、SVGとPNGのピクセルが完全に一致するようになった。
確認のために scripts/check-ogp-parity.sh という検証スクリプトまで作ってくれた。
SVGを再ラスタライズして、コミット済みのPNGとピクセル差分を比較するスクリプットだ。
レビュー2回目: ファイルの場所とURL
画像ができたが、置き場所が違っていた。
AIエージェントは static/images/ogp/<slug>.png にまとめて置いていた。
このブログの規約では、記事の画像は static/images/<slug>/ に置くことにしていた。
「作成したOGP画像は static/images ディレクトリ配下の記事名と同じディレクトリに ogp.png としてください」
と伝えた。
ここで気づいたことがもう一つあった。
layouts/partials/extend_head.html の手書きのOGPメタタグが、画像URLを相対パスのまま出力していた。
SNSのクローラーは相対パスを解決できない。絶対URLにしないとOGP画像が表示されない。
AIエージェントが extend_head.html の手書きタグを削除し、テーマの opengraph.html と twitter_cards.html パーシャルを上書きして、独自の image フィールドを絶対URLで出力するようにした。
完成したもの
最終的に、11記事すべてに記事専用のOGP画像が設定された。
各記事の static/images/<slug>/ogp.png に1200x630のPNGがあり、SVGソースも隣に置いてある。
front matterの image: フィールドがそれを指していて、Hugoのビルドで絶対URLのOGPメタデータが出力される。
ビルドして、全記事のHTMLに正しい og:image と twitter:image が出力されていることを確認した。
任せきるために必要だったもの
最初の指示は2行だった。デザインの指定も、サイズも、ファイルの置き場所も書いていない。
それで機能したのは、AIエージェントがサイトの既存デザインを自分で読んで、トーンを合わせる判断をしたからだ。 Hallmarkで刷新した直後だったので、CSSのトークンが揃っていて、参照すべきデザインが明確だった。
人間がやったのは2回のレビューだ。 1回目はPNGの文字が壊れているのを見つけて、1文で伝えた。 2回目はファイルの置き場所が規約と違うのを見つけて、直し方を指示した。
任せきるために必要だったのは、詳細な指示ではなく、できたものを確認する判断と、直すべき点を1文で伝えることだった。
追記(2026-07-23): もっとシンプルな方法があった
公開後、「画像が表示されないのはそもそもPaperModの仕様では」と聞かれた。
テーマの opengraph.html と twitter_cards.html を読み直すと、cover.image か images(配列)しか見ていなかった。
このブログが使っていた image:(単数)は、テーマにとってはただの未知のフィールドだった。
だから独自のテンプレート上書きが必要になっていた。
image: を images: の配列に書き換え、opengraph.html と twitter_cards.html にあった独自の image フィールド分岐を削除した。
テーマ標準の処理に乗せただけで、絶対URL化も含めて解決した。
独自の上書きコードより、テーマが最初から用意している仕組みを先に確認すべきだった。
