Auto-Generate Social Media Preview Images with a Screenshot API

April 18, 2026

When someone shares your link on Twitter, LinkedIn, Slack, or Discord, the platform fetches your Open Graph image. A compelling image makes people click. A missing one gets scrolled past.

Generating unique images for every page used to mean Canvas APIs, ImageMagick wizardry, or paying a designer. There's a simpler way: render an HTML template with a screenshot API.

Why HTML templates beat Canvas/ImageMagick

The template pattern

Design your card as a standalone HTML page sized 1200×630 (the Open Graph standard):

<!DOCTYPE html>
<html>
<head>
<style>
  body { margin: 0; font-family: system-ui, sans-serif; }
  .card {
    width: 1200px;
    height: 630px;
    padding: 80px;
    box-sizing: border-box;
    background: linear-gradient(135deg, #1e3a8a 0%, #2563eb 100%);
    color: white;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  .title { font-size: 64px; font-weight: 800; line-height: 1.1; }
  .footer { display: flex; justify-content: space-between; align-items: center; }
  .logo { font-size: 24px; font-weight: 700; }
  .author { font-size: 20px; opacity: 0.8; }
</style>
</head>
<body>
<div class="card">
  <div class="title">{{title}}</div>
  <div class="footer">
    <div class="logo">yourbrand.com</div>
    <div class="author">{{author}}</div>
  </div>
</div>
</body>
</html>

Render it on every publish

When a new blog post is published, call the API once and cache the result:

import Client from "screenshotapis";
const client = new Client(process.env.SCREENSHOT_API_KEY);

async function generateOgImage(post) {
  const html = template
    .replace("{{title}}", post.title)
    .replace("{{author}}", post.author);

  const { data } = await client.screenshot({
    html,
    format: "png",
    device_scale_factor: 2,  // retina
  });

  await s3.putObject({
    Bucket: "og-images",
    Key: `posts/${post.slug}.png`,
    Body: data,
    ContentType: "image/png",
  });

  return `https://cdn.yourbrand.com/og-images/posts/${post.slug}.png`;
}

Add the meta tags

Include the generated image URL in your page's head:

<meta property="og:image" content="https://cdn.yourbrand.com/og-images/posts/my-post.png">
<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:image" content="https://cdn.yourbrand.com/og-images/posts/my-post.png">

Testing your OG images

Before publishing, verify your image renders correctly on each platform:

Pro tips

Generate beautiful OG images from HTML templates

Get your API key — free