jpskill.com
💬 コミュニケーション コミュニティ

x-image-cards

X(旧Twitter)のOGP画像を、広告バナーではなく自然な画像のように見せるカードを作成するSkill。

📜 元の英語説明(参考)

Create X/Twitter cards that look like images, not marketing banners. Use when asked to "create OG images", "set up X cards", "make social cards", or "twitter card without text".

🇯🇵 日本人クリエイター向け解説

一言でいうと

X(旧Twitter)のOGP画像を、広告バナーではなく自然な画像のように見せるカードを作成するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o x-image-cards.zip https://jpskill.com/download/5843.zip && unzip -o x-image-cards.zip && rm x-image-cards.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/5843.zip -OutFile "$d\x-image-cards.zip"; Expand-Archive "$d\x-image-cards.zip" -DestinationPath $d -Force; ri "$d\x-image-cards.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して x-image-cards.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → x-image-cards フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-17
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

[Skill 名] x-image-cards

X 画像カード

マーケティングバナーではなく、画像のように見えるXカードを作成します。ビジュアルをコンテンツにしましょう。XはすでにカードUIにタイトルと説明を表示しています。

X固有の要件

仕様 理由
寸法 2400×1200 物理 (1200×600 論理) Retina対応2倍、2:1アスペクト比
セーフマージン 50-56px パディング (1倍時) Xはモバイルで端をクリップします
URL形式 /og/page.png であって /og/page?format=png ではない Xは明示的な拡張子を好みます
#FFFFFF を主色とし、微妙なグレーは避ける サムネイルは非常に小さいです

ゼロ幅スペースのトリック

Xはog:titleを画像の上に白いテキストで重ねて表示します。これをゼロ幅スペースで隠すことができます。

<meta property="og:title" content="&#8203;" />

JSXでは: content={"\u200B"}

ページの<title>はSEOのために記述的なままにし、og:titleのみがこのトリックを使用します。

メタタグ

<meta property="og:image" content="https://example.com/og/page.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="600" />
<meta property="og:title" content="&#8203;" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://example.com/og/page.png" />

動的生成

@vercel/ogを2倍のスケールとセーフマージンで使用します。

import { ImageResponse } from '@vercel/og';

const OG_SCALE = 2;

export async function GET(request: Request) {
  return new ImageResponse(
    (
      <div style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        backgroundColor: '#0a0f1c',
        padding: 100, // 50px * 2 for safe margins
      }}>
        {/* Your visual content here */}
      </div>
    ),
    { width: 1200 * OG_SCALE, height: 600 * OG_SCALE }
  );
}

Express

app.get('/og/:slug.png', async (req, res) => {
  const image = new ImageResponse(/* ... */);
  const buffer = await image.arrayBuffer();

  res.setHeader('Content-Type', 'image/png');
  res.setHeader('Cache-Control', 'public, max-age=86400');
  res.send(Buffer.from(buffer));
});

動的ルート (オプション)

ページごとのOG画像を生成するには、2つのアプローチがあります。

オンデマンド生成

クローラーが画像をリクエストしたときに生成します。

/og/[slug].png  →  リクエスト時に画像を生成

リスク: Xクローラーは約5秒でタイムアウトします。コールドスタートがこれを超えると、プレビューが空白になる可能性があります。

事前生成 (推奨)

コンテンツが作成されたときに画像を生成して保存します。

// On content creation
const imageBuffer = await generateOgImage(data);
await db.insert({ ogImageData: imageBuffer }); // Store as BYTEA

// On request - instant response
app.get('/og/:id.png', async (req, res) => {
  const { ogImageData } = await db.get(req.params.id);
  res.setHeader('Content-Type', 'image/png');
  res.send(ogImageData);
});

事前生成により、クローラーへの即時応答が保証されます。

チェックリスト

  • [ ] 2400×1200 (2倍 Retina)
  • [ ] 2:1 アスペクト比
  • [ ] 50-56px セーフマージン
  • [ ] 高コントラストの色
  • [ ] URLに.png拡張子
  • [ ] og:titleにゼロ幅スペース
  • [ ] テスト: https://cards-dev.twitter.com/validator

BondTerminalのために構築されました。動作例: X投稿の例

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

X Image Cards

Create X cards that look like images, not marketing banners. Let the visual be the content — X already shows your title and description in the card UI.

X-Specific Requirements

Spec Value Why
Dimensions 2400×1200 physical (1200×600 logical) 2x for retina, 2:1 aspect ratio
Safe margins 50-56px padding (at 1x) X clips edges on mobile
URL format /og/page.png not /og/page?format=png X prefers explicit extensions
Colors #FFFFFF primary, avoid subtle grays Thumbnails are tiny

Zero-Width Space Trick

X overlays og:title as white text on the image. Hide it with a zero-width space:

<meta property="og:title" content="&#8203;" />

In JSX: content={"\u200B"}

Your page <title> stays descriptive for SEO — only og:title uses the trick.

Meta Tags

<meta property="og:image" content="https://example.com/og/page.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="600" />
<meta property="og:title" content="&#8203;" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://example.com/og/page.png" />

Dynamic Generation

Use @vercel/og with 2x scale and safe margins:

import { ImageResponse } from '@vercel/og';

const OG_SCALE = 2;

export async function GET(request: Request) {
  return new ImageResponse(
    (
      <div style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        backgroundColor: '#0a0f1c',
        padding: 100, // 50px * 2 for safe margins
      }}>
        {/* Your visual content here */}
      </div>
    ),
    { width: 1200 * OG_SCALE, height: 600 * OG_SCALE }
  );
}

Express

app.get('/og/:slug.png', async (req, res) => {
  const image = new ImageResponse(/* ... */);
  const buffer = await image.arrayBuffer();

  res.setHeader('Content-Type', 'image/png');
  res.setHeader('Cache-Control', 'public, max-age=86400');
  res.send(Buffer.from(buffer));
});

Dynamic Routes (Optional)

For per-page OG images, two approaches:

On-Demand Generation

Generate when crawler requests the image:

/og/[slug].png  →  generates image on request

Risk: X crawlers timeout after ~5 seconds. Cold starts can exceed this, causing blank previews.

Pre-Generated (Recommended)

Generate and store image when content is created:

// On content creation
const imageBuffer = await generateOgImage(data);
await db.insert({ ogImageData: imageBuffer }); // Store as BYTEA

// On request - instant response
app.get('/og/:id.png', (req, res) => {
  const { ogImageData } = await db.get(req.params.id);
  res.setHeader('Content-Type', 'image/png');
  res.send(ogImageData);
});

Pre-generation ensures instant response for crawlers.

Checklist

  • [ ] 2400×1200 (2x retina)
  • [ ] 2:1 aspect ratio
  • [ ] 50-56px safe margins
  • [ ] High contrast colors
  • [ ] .png extension in URL
  • [ ] Zero-width space in og:title
  • [ ] Test: https://cards-dev.twitter.com/validator

Built for BondTerminal. See it in action: example X post.