シェアカードの役割はただ一つ:フィードをスクロールしている人が、約1秒でプロダクトの内容を理解できることです。効果的なカードは、プロダクトが動作している様子(署名済みの提案書、クライアントが確認できるリマインダー、オファー価格など)を示し、グラデーションの上に浮かんだロゴだけではありません。コードからカードを生成することで、ブランドと常に同期が取れ、後でデザインツールを使わずに変更できます。
1. コードを書く前にブランド情報を収集する
以下の順序で、存在するものがあれば読み取ります:デザインドキュメント(DESIGN.md、PRODUCT.md、スタイルガイド)、CSSトークン(globals.css、Tailwindの@theme、CSSカスタムプロパティ)、ランディングページの見出しとサブ見出し、そしてロゴ(SVGコンポーネントまたはファイル)。実際の16進数カラーと実際の表示フォント、本文フォントを使用してください。サイトとは異なる書体のカードは、ブランドから外れたものとして認識されます。
既存の設定(opengraph-image.*、og.png.*、レイアウト内のog:image)を探し、新しいものを追加するのではなく、それを拡張してください。
次に、カードに表示するモックを決定します。ユーザーに、プロダクトを使用した後、顧客が手にしているもの(請求書、確認メール、ダッシュボードのタイル、レシート)は何かを尋ね、それを描画します。明確でない場合は、一文で提案を述べ、ユーザーが反対しない限りそのまま進めてください。
2. カードを構成する
ユーザーまたは既存のカードが特に指定しない限り、このレイアウトから始めてください。このレイアウトは、フィードが表示する小さなサイズでも読みやすくなっています。
| 領域 | 内容 |
|---|---|
| キャンバス | 1200x630。ブランドの背景色、フラットまたはモックに向かって柔らかい放射状グラデーション。 |
左カラム、幅約620~660px、パディング約60px 0 60px 72px、justify-content: space-betweenで配置 | 上部:ロゴマークと34~38pxのワードマーク。中央:64~76pxの見出し、タイトライン間隔(0.98~1.08)、わずかにネガティブな文字間隔。下部:26~28pxの落ち着いたサブタイトル。 |
| 右側 | ブランドカラーと現実的なデータを使用した製品モック。2~4度傾け、反対方向に傾けたアクセントカラーのバッキングカードを背面に配置し、0 24px 48px -20px rgba(0,0,0,0.35)のような柔らかい影を付けます。 |
役立つ小さな工夫:モックにスタンプやバッジ(「支払済み」「確認済み」)、モックの角に重なる重要な数字が1つ入ったスリップ、低不透明度の薄い背景線画。
コピー:
- 見出しはプロダクトの約束です。理想的には、ランディングページの先頭にあるのと同じ行にします。具体的であることが、賢さより優先されます。
- モックデータは具体的で信頼できるものにします(
$1,510.00、38枚、もっともらしい顧客名)。ロレム・イプサムや$XXのようなプレースホルダーテキストは、製品が未完成に見えます。 - 見出しの一部のフレーズをアクセントカラーで強調すると効果的です。複数箇所を強調すると効果が薄れます。
- テキストは大きく保ちます。フィードではカードが元のサイズの3分の1で表示されることが多いため、約18px以下のものは見えなくなります。
3. レンダリングする
Satori(JSX風のツリーをSVGに変換)を使用し、その後PNGにラスタライズします。Next.jsではnext/ogとして同梱されています。それ以外の環境では、satoriと@resvg/resvg-jsを組み合わせて使用します。フレームワークごとの配線(Next.js App Router、Astro、その他の静的サイト用のプレーンビルドスクリプト)については、references/frameworks.mdを参照してください。
SatoriはCSSのサブセットのみをサポートしており、これらの制限がほとんどの失敗の原因となります:
- フォントは、レンダリング時に渡される実際のTTF、OTF、またはWOFFファイルである必要があります。WOFF2は機能せず、システムフォントのフォールバックもありません。使用する2~3のウェイトのみを読み込んでください。references/frameworks.mdでファイルの入手方法を説明しています。
- 複数の子を持つ要素は
display: "flex"が必要です。そうしないとSatoriがエラーをスローするため、すべてのボックスはデフォルトでフレックスにします。 - CSSグリッド、CSS変数、
calc()は使用できません。ファイルの先頭にリテラルカラーを小さなマップとして記述します(const C = { ink: "#1c2128", ... })。 - テキストは自動的に折り返されます。最後の行に一語だけが残ったり、テキストがモックに重なったりしないように注意してください。明示的に行を分割する(スパンの列)か、幅とサイズを調整して修正します。
whiteSpace: "nowrap"とflexShrink: 0を組み合わせると、価格や明細項目を一行に保つことができます。 position: "absolute"は、相対配置のフレックス親の内部で機能します。バッキングカード、スタンプ、スリップに使用します。- インラインSVGパスは問題なくレンダリングされるため、画像として埋め込む代わりにロゴのSVGパスを再利用してください。ローカルのラスター画像は、base64データURIとして取り込みます。
4. 代替テキストとタグ
og:image:altには、画像が実際に何を示しているかを「ブランド名:モックが示すもの、および見出し」の形式で記述します。例:「Acme Invoices: 支払済みスタンプが押された$1,510.00の請求書。見出し:現場を離れる前に入金を受け取る。」
ページには、絶対URLで以下が必要です:og:title、og:description、og:image、og:image:width(1200)、og:image:height(630)、og:image:alt、twitter:card(summary_large_imageに設定)、twitter:image。相対パスのog:imageは、カードが表示されない最も一般的な原因です。ほとんどのアンファーラーはそれを解決しないためです。
5. 目視で確認する
PNGを確認するまでは、カードは完成したと見なさないでください。
-
開発サーバーを起動し、画像をフェッチして、画像ビューアで開くか、画像を表示できるファイル読み取りツールで開きます。
-
以下の点を注意深く確認します:孤立した単語、モックに触れているテキスト、キャンバス端でクリップされている影、不均等なパディング、フォールバックフォント(明らかに間違って見える)、コントラストの低いサブタイトル。修正して、問題がなくなるまで再レンダリングします。
-
タグと画像を一緒に確認します:
python3 scripts/check_og.py http://localhost:3000/ --out /tmp/og-check.pngこのスクリプトは、すべてのOGタグとTwitterタグをリスト表示し、画像をフェッチし、1200x630かつ5MB未満であることを確認し、相対URLと誤ったカードタイプをフラグし、問題があれば終了コード1で終了します。保存されたPNGを開いて、期待する画像であることを確認します。
-
本番ビルドを実行して、画像が引き続き生成されることを確認します。
-
デプロイ後、ライブURLに対してチェッカーを実行します。Slack、LinkedInなどはアンファーをキャッシュするため、変更前に共有されたリンクは、しばらく古いカードを表示し続ける可能性があることをユーザーに伝えてください。LinkedInのPost Inspectorは強制リフレッシュを行います。
完了したら、ユーザーにPNGのパスと、レイアウトとモックが何を示しているかを説明する短いパラグラフを1つ提供します。