← GrabShot Blog

How to Generate OG Images Automatically for Your Website

February 16, 2026 · 6 min read

Every link shared on Twitter, Slack, Discord, or LinkedIn shows an Open Graph preview image. If you don't set one, your links look boring. If you design them manually, you'll go crazy after 10 blog posts.

The solution: auto-generate OG images using HTML templates and a screenshot API.

The Approach

  1. Design a template in HTML/CSS (1200x630px, the OG standard)
  2. Inject dynamic data (title, author, date, category)
  3. Screenshot it via API to get a PNG
  4. Serve it as your og:image

This is exactly how Vercel's og package works, except you don't need Vercel. Any screenshot API does the job.

Step 1: Create Your HTML Template

Host a simple page that accepts query parameters and renders a card:

<!-- og-template.html -->
<html>
<head>
<style>
  body {
    width: 1200px; height: 630px;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #667eea, #764ba2);
    font-family: -apple-system, sans-serif;
    color: white; margin: 0; padding: 60px;
  }
  .card {
    text-align: center;
  }
  h1 { font-size: 56px; line-height: 1.2; margin-bottom: 16px; }
  p { font-size: 24px; opacity: 0.8; }
  .logo { font-size: 20px; margin-top: 32px; opacity: 0.6; }
</style>
</head>
<body>
  <div class="card">
    <h1 id="title"></h1>
    <p id="subtitle"></p>
    <div class="logo">yourbrand.com</div>
  </div>
  <script>
    const params = new URLSearchParams(location.search);
    document.getElementById('title').textContent = params.get('title') || 'My Blog Post';
    document.getElementById('subtitle').textContent = params.get('subtitle') || '';
  </script>
</body>
</html>

Step 2: Screenshot It with GrabShot

# Generate OG image for a specific blog post
curl "https://grabshot.dev/api/screenshot?\
url=https://yourdomain.com/og-template.html?title=My+Amazing+Post\
&width=1200&height=630&format=png" \
  -H "X-API-Key: your-key" \
  --output og-image.png

That's it. One API call, perfect OG image every time.

Step 3: Automate It

For a blog or CMS, generate OG images at build time or on first request:

// Node.js example: generate OG image on demand
const express = require('express');
const fetch = require('node-fetch');
const app = express();

const GRABSHOT_KEY = process.env.GRABSHOT_API_KEY;

app.get('/og/:slug', async (req, res) => {
  const { slug } = req.params;
  const post = await getPostBySlug(slug); // your data source

  const templateUrl = `https://yoursite.com/og-template.html?` +
    `title=${encodeURIComponent(post.title)}` +
    `&subtitle=${encodeURIComponent(post.date)}`;

  const response = await fetch(
    `https://grabshot.dev/api/screenshot?url=${encodeURIComponent(templateUrl)}&width=1200&height=630`,
    { headers: { 'X-API-Key': GRABSHOT_KEY } }
  );

  const buffer = await response.buffer();

  // Cache for 7 days
  res.set('Cache-Control', 'public, max-age=604800');
  res.set('Content-Type', 'image/png');
  res.send(buffer);
});

Then in your HTML:

<meta property="og:image" content="https://yoursite.com/og/my-blog-post">

Design Tips for Great OG Images

Why Not Vercel OG?

Vercel's @vercel/og is great if you're on Vercel. But it uses Satori (limited CSS subset), only works in Edge Runtime, and you're locked into their platform.

A screenshot API approach works with any framework, any hosting, and supports full CSS/JS. More flexible, same result.

Generate OG Images with GrabShot

Screenshot any HTML template at 1200x630. Perfect social previews, every time.

Try Free →

Want to see GrabShot in action?

Try our free screenshot tool — no signup required.

Try GrabShot Free →