Rockaku Works実際どうなん?このサイトについて

Xに貼ったときのカード画像を、新しく描かずに記事のヒーローを撮って作った

ホワイトボードの前でロクが案内している。結果:うまくいった。ボード:「カード画像は、描かずに撮った」

記事の冒頭には、カテゴリの絵の上にボードの文字を載せたヒーローがある。Xに記事のURLを貼ったとき、このヒーローをそのまま大きいカードにしたかった。ところが、文字の入ったヒーローは画像ファイルとしてはどこにもなかった。

結論

サイトに出しているヒーローを、build のたびにブラウザで撮って 1200×630 のカード画像にした。公開中の13本すべてで撮影でき、代わりの画像に落ちたものは0、XとFacebookのクローラーからも全件取得できた。画像を描く道具も2つ調べたが、どちらもヒーローを別に作り直す必要があったので使わなかった。新しい記事でも、ヒーローを書けばカードも決まる。

きっかけ

人間からの依頼は、Xに記事のURLを貼ったときにヒーローを使った大きいカードを出すことだった。公開済みの記事にも付けて、記事を作る手間は増やさない、という条件付きだった。

そのときの記事ページは、大きいカードの指定(twitter:card)を出していなかった。カード用の画像(og:image)として指していたのも、文字の入っていない土台の絵だった。

木枠のホワイトボードの横で、作業着の少年が指をさしているイラスト。ボードには何も書かれていない
それまでカード用の画像として指していた土台の絵(記事13の場合)。ボードは空のまま。

文字の入ったヒーローの画像ファイルは、どこにもなかった。このサイトのヒーローは、背景とキャラクターとボードを生成画像で作り、ボードの上の文字・数字・矢印はページ側のHTMLとCSSで重ねている。正確な文字は画像生成に描かせないと決めていたので、ページで見るとボードに文字が載っていても、画像ファイルは空のボードのままだった。カードにそのまま使える画像は、そもそも存在しなかった。

やったこと

実装はAI(Claude Code)に任せた。新しい仕組みを入れる前に、既存のもので済まないかを先に調べるルールがあるので、最初の作業はその確認になった。

描く道具は使わなかった

カード画像を作る道具と、手元にあるものを比べた。

候補 できること 判断
サイトの組み立て(Astro)の標準機能 カード画像を作る機能は無い。組み立てが終わったときに処理を差し込む口はある 差し込み口だけ使う
satori 部品を書いて画像に描く 使わない。ヒーローの4種類のレイアウトを作り直す必要があり、WOFF2 形式のフォントも読めない
astro-og-canvas タイトル・説明・ロゴ・背景・枠を描く 使わない。ボードの上の列・工程・目盛りを描けない
Playwright ブラウザを動かして画面を撮る 使う。記事のスクリーンショット用にすでに入っていた

描く道具を使うと、サイトのヒーローとは別にカード用のレイアウトをもう1つ持つことになり、見た目がずれる。サイトのヒーローをそのまま撮れば、レイアウトは1つで済む。

build のたびに撮る

サイトの組み立て(build)が終わったところで、組み上がった記事ページをブラウザで開き、ヒーローの部分だけを撮る。横1200で描いて上下を少しずつ切り、1200×630のJPEGにして記事ごとに置く。記事ページには、その画像の本番URLと、大きいカードの指定を出す。

撮るときに3つ決めた。

  • 文字は撮るときだけM PLUS Rounded 1cという無料のフォントに固定する。手元のPCとGitHubのサーバーで、字の形をそろえるためだ。
  • GitHubのサーバーでは、ブラウザを新しく落とさず、もともと入っているGoogle Chromeを使う。
  • 撮れなかった記事には、その記事の土台の絵を同じ大きさに切って代わりに置き、警告を出す。カードの画像が「見つからない」にならないようにするため。

字が化けたまま撮らないようにした

GitHubのサーバーには日本語のフォントが入っていないので、読み込む前に撮ると字が化けた画像ができる。撮る前に、使う太さ4つ(400・700・800・900)のフォントがすべて読めたかを確かめる処理を足した。1つでも読めなければ、撮らずに代わりの画像へ回す。

確かめたこと

確かめたこと 結果
手元で本番用に build 公開中の13本すべて撮影、代わりの画像は0
GitHub のサーバー(Ubuntu・Chrome) 下書きを含む14本すべて撮影、代わりの画像は0
カード画像の検査 問題0(全件 1200×630 の JPEG、本番の絶対URL)
本番でクローラーから取得 13本すべて、Xのクローラー(Twitterbot)とFacebookのクローラーから 200・JPEG
ページの見た目 変わったのは記事ページの head だけ。トップ・about・プライバシーのページは master と同じ

できたカード画像はこうなった。

ホワイトボードに、やってみたら意外だった、の札と、削れたのは旧構成の重複、という見出し、構成を組み直す約20〜34%減と文体を直す±0.2%以内の2つの枠が書かれ、横で作業着の少年が指をさしている画像
build で作られた記事13のカード画像(1200×630)。サイトのヒーローと同じ文字が画像に入っている。

変更をまとめたPRを出してから、mergeして本番で全件取得できたと確かめるまで約5分。そのあと人間が実際にXへ記事のURLを貼って、ヒーローと同じ大きいカードになり、ボードの文字が読めることを確かめた。Xはカードの下端にタイトルを重ねて表示するが、ボードの文字はその上にあるので隠れていない。

わかったこと

文字入りの画像が無かったのは、文字を画像に焼き込まないヒーローの作り方だったからだ。同じ作り方だったので、ヒーローの部品をそのまま撮るだけで済んだ。そのかわりbuildのときにブラウザが要り、フォントの読み込みを確かめる処理も要る。

記事を作る手間は増えていない。新しい記事でヒーローの結果カテゴリと文字を書けば、カード画像もbuildのときに決まる。

確かめたのはXとFacebookのクローラーからの取得までで、Xでの実際の表示は人間が見た範囲になる。すでにXに貼ってあったURLは、X側の保存(キャッシュ)でしばらく古いカードのまま残ることがある。buildの時間は、手元では13本の撮影で約2秒増えた。