You know what's annoying? Spinning up a headless browser just to generate a social preview image.
Puppeteer works. Sure. But it's slow, memory-hungry, and a nightmare to deploy on serverless. I spent way too long fighting Chrome binaries on Vercel before I gave up and looked for something better.
Turns out there's a simpler way.
The Problem With Puppeteer-Based OG Images
Here's the typical flow:
- Spin up a headless Chrome instance
- Render an HTML page with your dynamic content
- Screenshot it
- Serve that screenshot as your OG image
It works on your local machine. Then you deploy it and everything breaks. Chrome needs specific system libraries. Cold starts take 5-10 seconds. Memory usage spikes. And if you're on a free tier anywhere, good luck.
I've burned entire weekends on this.
Enter OGPix
OGPix takes a completely different approach. Instead of running a browser, it generates images through an API. You send parameters, you get back an image URL. That's it.
No Chrome. No Puppeteer. No deployment headaches.
How It Works — Step by Step
1. Pick a Template or Build Your Own
OGPix comes with pre-built templates for blog posts, product pages, and documentation. But you can also customize everything.
2. Generate via URL Parameters
The simplest approach — just construct a URL:
https://ogpix-pi.vercel.app/api/og?title=My+Blog+Post&description=A+quick+tutorial&theme=dark
Drop that into your meta tags:
<meta property="og:image" content="https://ogpix-pi.vercel.app/api/og?title=My+Blog+Post&description=A+quick+tutorial&theme=dark" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
3. Use It in Next.js
If you're on Next.js, add it to your layout or page head:
export const metadata = {
openGraph: {
images: [
{
url: \`https://ogpix-pi.vercel.app/api/og?title=\${encodeURIComponent(post.title)}\`,
width: 1200,
height: 630,
},
],
},
};
4. Dynamic Routes? No Problem
For blog posts or any dynamic content, just swap in the variables:
function getOGImage(title, author) {
const params = new URLSearchParams({
title,
author,
theme: 'gradient',
});
return \`https://ogpix-pi.vercel.app/api/og?\${params.toString()}\`;
}
Why This Beats Puppeteer
- Speed: Images generate in milliseconds, not seconds
- No dependencies: Zero system libraries to install
- Serverless-friendly: Works everywhere, including edge functions
- Caching: URLs are deterministic, so CDN caching just works
- Free: No paid tiers for basic usage
The Results
I switched three of my projects from Puppeteer to OGPix. Deploy times dropped. No more random failures in CI. And the images actually look better because I'm not fighting CSS rendering inconsistencies across headless browsers.
If you're still wrestling with Puppeteer for OG images, stop. There's a better way now.
Check it out at ogpix-pi.vercel.app.
Top comments (0)