How I deployed a Puppeteer API on Vercel to serve dynamic Arabic images for OG tags
Saad Batwa
Aug 15, 2024
When building a Nuxt documentation website, I needed dynamic Open Graph (OG) image generation for each page. While Nuxt has its own OG image module, it struggles with Arabic text and right-to-left layouts. Here’s how I solved this problem using Puppeteer on Vercel’s serverless platform.
I started with Nuxt, aiming to create a documentation-style website with dynamic OG images for each page. The main issues were:
Thanks to @sparticuz/chromium-min and puppeteer-core, I found a way to deploy Puppeteer on Vercel without hitting size or timeout limits.
npm install @sparticuz/chromium-min puppeteer-core
Create a server route and import the necessary packages:
import chromium from "@sparticuz/chromium-min";
import puppeteerCore, { Browser, Page } from "puppeteer-core";
Instead of bundling Chromium in the build, download it at runtime. Make sure to match the version with your installed package:
const remoteExecutablePath =
"https://github.com/Sparticuz/chromium/releases/download/v138.0.1/chromium-v138.0.1-pack.tar";
let browser: Browser | null = null;
Create the browser instance inside your server function. For local development, use a pre-installed Chromium:
if (!browser) {
browser = await puppeteerCore.launch({
args: chromium.args,
executablePath: process.env.DEV
? "/usr/bin/chromium" // Local development
: await chromium.executablePath(remoteExecutablePath), // Production
headless: true,
});
}
Now you can use Puppeteer’s full API:
const page = await browser.newPage();
await page.setViewport({ width: 1200, height: 630 });
// Set content with Arabic support
await page.setContent(`
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Cairo', sans-serif;
direction: rtl;
}
</style>
</head>
<body>
<h1>مرحباً بك</h1>
</body>
</html>
`);
// Take screenshot
const screenshot = await page.screenshot({ type: 'png' });
await page.close();
return screenshot;
This is exactly how OG images are generated on my website. Check out an example: https://uqucc.sb.sa/برمجة-جافا
The OG image you see when sharing this link on social media was generated on-demand using this exact setup!
Deploying Puppeteer on Vercel doesn’t have to be complicated. With the right setup using minimal Chromium, you can generate dynamic images, PDFs, or scrape content—all within Vercel’s generous free tier limits.
This approach has been running in production for months without any issues, handling thousands of OG image requests for free!
© 2025, All Rights Reserved.