How to Add Dynamic OG Images to Your Developer Blog in 2 Minutes

  • Автор темы Автор темы Sascha
  • Дата начала Дата начала

Sascha

Команда форума
Администратор
Ofline
https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdklm7to4237pcfm06074.png

Your Blog Posts Deserve Better Social Previews​


You spend hours writing a technical blog post. You share it on Twitter. And the preview looks like this:


No image. No description. Just a sad, generic text preview that nobody clicks on.

The fix is Open Graph meta tags — specifically og:image. But if you have 50+ blog posts, you can't open Figma and design a unique image for each one. You need dynamic generation.

Why Puppeteer/Playwright Sucks for Blog OG Images​


The "standard" approach is:

  1. Spin up a headless browser in a serverless function
  2. Load an HTML template with your post title
  3. Screenshot it
  4. Serve the PNG

This works in theory. In practice:

  • Cold boot times of 3-5 seconds mean social platforms time out and cache nothing
  • Memory usage of 200-500MB per invocation means expensive serverless bills
  • Font loading is unreliable in headless environments
  • You end up maintaining a mini rendering pipeline for what should be a simple image

A Better Approach: URL-Based Image Generation​


What if every blog post got a unique social preview by just adding a URL to your og:image tag?


Код:
<meta property="og:image" 
  content="https://socialcard.risero.io/generate?title=Building+a+REST+API+with+Hono&template=blog&api_key=YOUR_KEY" />



That URL returns a 1200×630 PNG. No serverless function in your codebase. No headless browser. No build step. The image is edge-cached for 24 hours so it loads instantly when someone shares your link.

How It Works Under the Hood​


Instead of using a browser to render HTML:

  1. Satori (by Vercel) — converts JSX to SVG using a custom layout engine
  2. resvg-wasm — rasterizes SVG to PNG in WebAssembly
  3. Cloudflare Workers — runs at the edge, <100ms response time

Browser-quality rendering without an actual browser.

Framework Integration Examples​

Next.js (App Router)​


Код:
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug);
  const ogImage = new URL('https://socialcard.risero.io/generate');
  ogImage.searchParams.set('title', post.title);
  ogImage.searchParams.set('description', post.excerpt);
  ogImage.searchParams.set('template', 'blog');
  ogImage.searchParams.set('api_key', 'YOUR_KEY');

  return {
    openGraph: {
      images: [{ url: ogImage.toString(), width: 1200, height: 630 }],
    },
  };
}


Astro​


Код:
---
const { title, description } = Astro.props;
const ogUrl = `https://socialcard.risero.io/generate?title=${encodeURIComponent(title)}&template=developer&api_key=YOUR_KEY`;
---
<meta property="og:image" content={ogUrl} />


Hugo​


Код:
{{ $ogUrl := printf "https://socialcard.risero.io/generate?title=%s&template=blog&api_key=YOUR_KEY" (urlquery .Title) }}
<meta property="og:image" content="{{ $ogUrl }}" />


Ghost (via Code Injection)​


Код:
<script>
  const title = document.querySelector('meta[property="og:title"]')?.content || document.title;
  const ogMeta = document.createElement('meta');
  ogMeta.setAttribute('property', 'og:image');
  ogMeta.content = `https://socialcard.risero.io/generate?title=${encodeURIComponent(title)}&template=blog&api_key=YOUR_KEY`;
  document.head.appendChild(ogMeta);
</script>


Plain HTML (any static site)​


Код:
<meta property="og:image" 
  content="https://socialcard.risero.io/generate?title=Welcome+to+My+Blog&template=minimal&api_key=YOUR_KEY" />


Templates Built for Dev Content​


The API has 10 templates, but these are the ones built specifically for developer blogs:

  • blog — title, description, author with gradient accent. Perfect for articles.
  • developer — dark theme, monospace font, terminal aesthetics. For dev tool blogs.
  • changelog — version badge with diff-style indicators. For release notes.
  • github — repo card with language, stars, forks. For open source posts.
  • announcement — launch badge with vibrant gradient. For product announcements.

Each supports light/dark themes and custom accent colors.

Get Started in 2 Minutes​

  1. Get a free API key at socialcard.risero.io (just your email, no credit card)
  2. Try the live playground to preview templates with your own titles
  3. Copy the URL and drop it in your og:image meta tag
  4. Share a link on Twitter/LinkedIn/Slack and see the preview

Free tier gives you 50 images/day — enough for any personal or team blog.



I built this to solve my own dev blog problem. If you try it, I'd love to hear which templates work best for your content and what's missing.

 
Назад
Сверху Снизу