Form BLOG-1Dynamic Open Graph images, without a screenshot servicePixelDrive

Dynamic Open Graph images, without a screenshot service

Every shared link deserves its own preview card. Here is how to render them on demand from one design — no Puppeteer, no screenshot farm.

PixelDrive··6 min read

The Open Graph image is the most-viewed asset most teams never design. It is the card that shows up when a link is pasted into Slack, X, LinkedIn or iMessage — and for blogs, docs and product pages, there can be thousands of them, one per URL. Designing each by hand is impossible; falling back to a single generic image leaves clicks on the table.

The common fix is a headless browser that screenshots an HTML page. It works until it does not: cold starts, font loading races, memory spikes, and a render pipeline you now have to babysit. There is a calmer way — treat the OG image as a templated render behind a stable URL.

Design the card once, fill it per page

Build the OG card as a single template: a fixed 1200×630 layout with your logo, background and type locked in place, and two or three variable fields — title, author, maybe a category tag. Everything visual is decided once, in a design tool, not reconstructed from CSS on every request.

From then on a page only supplies data. The title of the post, the name of the doc, the price of the product — passed as URL parameters or JSON. The render is deterministic: the same inputs always produce the same pixels, so your previews never drift.

The URL is the API

Point each page’s og:image meta tag at a render URL that carries its data. Because the URL is stable and content-addressed, a CDN and the render cache can both hold it: the first crawl renders it in about a second, every crawl after is served from cache for free.

<meta property="og:image"
  content="https://pixeldrive.pro/img/t/og_8c41f2?title=Dynamic+OG+images&author=PixelDrive&format=png">

Why this beats a screenshot service

  • No headless browser to run, scale or patch — rendering is a managed call.
  • Deterministic output: identical inputs, identical image, every time.
  • Cacheable by construction — repeat shares cost nothing and serve in milliseconds.
  • Fonts and brand are baked into the template, so previews can’t render half-styled.
  • Localise the same card by adding a language parameter — the title comes back translated.

Make it dynamic without a deploy

Because the design lives in a template rather than in your codebase, marketing can restyle every preview card on the site — new colour, new logo lockup, a seasonal frame — without a single deploy. The URLs your pages emit stay identical; only the rendered output changes.

That separation is the whole point: data comes from your app, design comes from the template, and the two meet at a cache-friendly URL.

Put it into practice. The first thousand renders are on us.

Start free