mcpField
X
x-image-cards

x-image-cards

github.com/0juanoDesign & UI036 installsUpdated 17w ago
Repository

About x-image-cards

x-image-cards is a skill for creating image-led X preview cards rather than marketing banners. It covers image dimensions, metadata, and generation patterns, including when to pre-generate images to avoid crawler timeouts.

Key features

  1. 01X card size and safe margins
  2. 02Open Graph metadata guidance
  3. 03Zero-width space title technique
  4. 04Dynamic image generation examples
  5. 05On-demand and pre-generation options
  6. 06Preview validation checklist

Use cases

  1. 01Designing X link preview images
  2. 02Adding Open Graph image routes
  3. 03Reducing crawler timeout risk
  4. 04Checking card metadata and appearance

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/0juano/agent-skills --skill x-image-cards

After installing, type/x-image-cardsin Claude Code to confirm it loaded.

Details

From the project README

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

SpecValueWhy
Dimensions2400×1200 physical (1200×600 logical)2x for retina, 2:1 aspect ratio
Safe margins50-56px padding (at 1x)X clips edges on mobile
URL format/og/page.png not /og/page?format=pngX prefers explicit extensions
Colors#FFFFFF primary, avoid subtle graysThumbnails 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


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

Comments

Markdown supported