og-image について
サイトに動的な Open Graph 画像とソーシャルメタデータを追加する開発スキルです。複数のフレームワークと静的 HTML の設定に加え、デザインや表示確認も案内します。
主な機能
- 01フレームワークと既存メタデータの検出
- 02動的 OG 画像ルートの設定
- 03ページ単位の Open Graph と Twitter タグの追加
- 04フィード表示向け画像レイアウトの案内
- 05プラットフォームの検証ツールでプレビュー確認
活用シーン
- 01Next.js サイトへのシェア画像追加
- 02動的コンテンツのページ別プレビュー作成
- 03Astro や静的ページのソーシャルメタデータ設定
- 04欠落または不具合のあるリンクプレビューの診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tushaarmehtaa/ tushar-skills --skill og-imageインストール後、Claude Code で/og-imageを入力して読み込まれたか確認します。
詳細
OG 画像の動的生成とメタタグ一式を、1 つのルートで全ページに対応させます。リンクを共有しても、表示が崩れなくなります。
フェーズ 1:技術スタックを確認する
コードベースを確認します。
- フレームワーク:Next.js App Router/Pages Router/Astro/Remix/静的 HTML のどれですか?
- 既存のメタタグ:レイアウトファイルで
og:imageやtwitter:cardを検索します - 動的ページ:ブログ記事、製品ページ、スキルページなど、ページごとに OG が必要なものはありますか?
メタタグがすでにある場合は、変更する前に監査してください。
フェーズ 2:フレームワークごとの設定
Next.js App Router(推奨の方法)
app/api/og/route.tsx を作成します。
import { ImageResponse } from 'next/og';
export const runtime = 'edge';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const title = searchParams.get('title') || '[Project Name]';
const description = searchParams.get('description') || '[One-line description]';
return new ImageResponse(
(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#09090b',
color: '#fafafa',
fontFamily: 'system-ui, sans-serif',
padding: '60px',
}}
>
<div
style={{
fontSize: 64,
fontWeight: 'bold',
marginBottom: 24,
textAlign: 'center',
lineHeight: 1.1,
}}
>
{title}
</div>
<div
style={{
fontSize: 28,
opacity: 0.55,
textAlign: 'center',
maxWidth: '80%',
lineHeight: 1.4,
}}
>
{description}
</div>
</div>
),
{ width: 1200, height: 630 }
);
}
app/layout.tsx に追加します。実際のプロジェクト名と説明は、package.json、README、またはランディングページの文言から確認してください。
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_APP_URL || 'https://yourdomain.com'),
openGraph: {
title: '[Project Name]',
description: '[One-line description]',
images: [{
url: '/api/og?title=[Project Name]&description=[Description]',
width: 1200,
height: 630,
}],
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: '[Project Name]',
description: '[One-line description]',
images: ['/api/og?title=[Project Name]&description=[Description]'],
},
};
動的ページ(ブログ記事、スキルページ、製品ページ)では、ページごとに上書きします。
// app/[slug]/page.tsx
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
const item = getItem(slug);
if (!item) return {};
const ogUrl = `/api/og?title=${encodeURIComponent(item.title)}&description=${encodeURIComponent(item.description)}`;
return {
title: `${item.title} — [Site Name]`,
description: item.description,
openGraph: {
images: [{ url: ogUrl, width: 1200, height: 630 }],
},
twitter: {
images: [ogUrl],
},
};
}
Next.js Pages Router
同じ ImageResponse のロジックを使って pages/api/og.tsx を作成します。
_app.tsx で next/head を使うか、ページごとに <Head> を使ってメタタグを追加します。
Astro
インストールします:npm install satori @resvg/resvg-js
satori を使って PNG バッファーを生成し、Content-Type: image/png を付けて返すエンドポイントとして、src/pages/og/[...slug].png.ts を作成します。
src/layouts/Layout.astro の <head> セクションにメタタグを追加します。
静的 HTML
静的な og-image.png(1200×630)を一度生成し、次のように参照します。
<meta property="og:image" content="https://yourdomain.com/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
ページ数の多い静的サイトでは、ビルド時にページごとの OG 画像を生成することを検討してください。
フェーズ 3:必須のメタタグ
すべてのページに、次のタグが必要です。ベースレイアウトに挿入してください。
<meta property="og:type" content="website" />
<meta property="og:url" content="[Canonical page URL]" />
<meta property="og:title" content="[Page title]" />
<meta property="og:description" content="[Page description — 1-2 sentences]" />
<meta property="og:image" content="[OG image URL — absolute, not relative]" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="[Page title]" />
<meta name="twitter:description" content="[Page description]" />
<meta name="twitter:image" content="[OG image URL — must match og:image]" />
プレビューが崩れるよくある原因:
og:imageに相対 URL を使用している — 絶対 URL(https://...)でなければなりませんog:imageを設定しているのにtwitter:imageを設定していない — Twitter はog:imageを無視しますog:image:widthと:heightがない — 表示が遅くなり、場合によってはプレビューが表示されません- Next.js で
metadataBaseを設定していない — すべての相対 URL が無効になります
フェーズ 4:デザインのルール
画像はデスクトップで 1200×630 で表示され、モバイルではサムネイル用に切り抜かれます。両方を考慮してデザインしてください。
- 幅 300px でもテキストを読みやすくする — Slack/Twitter のフィードではこのサイズで表示されます
- すべてのコンテンツを中央の 80% に収める — プラットフォームによって端が予測できない形で切り抜かれます
- 暗い背景を推奨 — ライトモードのフィードで目立ちます
- タイトル:48〜64px の太字 — サムネイルサイズでも読みやすくします
- 説明/サブタイトル:24〜32px、低めの不透明度 — 補足情報として表示します
- コントラスト比は最低 4.5:1 — ライトモードとダークモードの両方のプラットフォームに対応します
フェーズ 5:確認する
デプロイ後、次のツールに URL を貼り付けてください。この確認を省略しないでください。コード上ではメタタグが正しく見えても、実際には想像以上によく問題が発生します。
- Twitter Card Validator:cards-dev.twitter.com/validator
- LinkedIn Post Inspector:linkedin.com/post-inspector/
- Facebook Debugger:developers.facebook.com/tools/debug/(WhatsApp でも動作します)
- 簡易チェック:Slack の任意のチャンネルに URL を貼り付けます
[ ] OG image route returns valid image at /api/og (or equivalent)
[ ] og:title, og:description, og:image all set in base layout
[ ] og:image:width and og:image:height set
[ ] twitter:card set to summary_large_image
[ ] twitter:image set (separate from og:image — both required)
[ ] og:image URL is absolute, not relative
[ ] Dynamic pages have per-page og:image with correct title param
[ ] Image readable at 300px thumbnail width
[ ] Verified in Twitter Card Validator or LinkedIn Inspector