Automate Social Media Preview Images with a Screenshot API
Source: Dev.to
The Problem
Every time you publish a blog post, launch a feature, or share a link, platforms like Twitter, Slack, Discord, and LinkedIn look for an og:image meta tag. If it’s missing or generic, your link looks forgettable.
Designing a unique image per page doesn’t scale—you need automation.
The Solution: HTML → Image
The idea is simple:
- Design your OG image as an HTML template (with CSS!).
- Pass dynamic data (title, author, date) as parameters.
- Render it to a PNG via a headless‑browser screenshot API.
- Serve the generated PNG from your
og:imagemeta tag.
Minimal example with a screenshot API
curl "https://rendly-api.fly.dev/api/v1/templates/og-basic/render?title=My+Blog+Post&author=Mack" \
-H "Authorization: Bearer YOUR_API_KEY" \
--output og-image.pngOne HTTP call, one image.
Building the HTML Template
Your template is just HTML + CSS. Here’s a starter:
<div style="font-family: system-ui; padding: 2rem; background: #f0f0f0;">
<h1>{{title}}</h1>
<p>by {{author}} · {{date}}</p>
</div>The magic: you already know HTML and CSS—no new design tool to learn.
Integrating with Your Blog
Next.js / React
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
openGraph: {
images: [
`https://rendly-api.fly.dev/api/v1/templates/og-basic/render?title=${encodeURIComponent(post.title)}&author=${post.author}`
],
},
};
}Rails
# Example Ruby code to generate the OG image URL
og_image_url = "https://rendly-api.fly.dev/api/v1/templates/og-basic/render?title=#{CGI.escape(@post.title)}&author=#{@post.author}"Static Sites (Hugo, Jekyll, 11ty)
Set the URL in your front‑matter or template. Most static site generators support dynamic meta tags.
Why Not Just Use Puppeteer Locally?
You can, but:
- Headless Chrome uses ~500 MB+ RAM.
- Cold starts are slow (2–5 seconds).
- You must manage browser updates, fonts, and rendering quirks.
- It doesn’t scale well on serverless platforms (Lambda timeout, memory limits).
A dedicated API handles all of this. You get a URL, you get an image.
Performance Tips
- Cache aggressively – OG images rarely change. Set
Cache-Control: public, max-age=86400. - Use webhooks – If your API supports async rendering, generate images on publish rather than on‑demand.
- Keep templates simple – Fewer DOM nodes = faster rendering.
- Use system fonts – Custom fonts add latency;
system‑uiloads instantly.
The ROI
Links with custom preview images get 2–3× more clicks on social media. For a blog that publishes weekly, automating this saves hours per month and measurably increases traffic.
I’m building Rendly, a screenshot and image‑generation API designed for exactly this workflow. Free tier available — no credit card required.