DEV Community

DevToolsmith
DevToolsmith

Posted on

How to Build a Website Screenshot API with Node.js and Puppeteer

Need to capture website screenshots programmatically? Here is how to build your own screenshot API using Node.js and Puppeteer.

Why Screenshot APIs?

Common use cases:

  • Social media previews - Generate OG images from any URL
  • PDF reports - Convert HTML dashboards to PDF
  • Visual regression testing - Catch UI bugs before deploy
  • Monitoring - Track visual changes on competitor sites
  • Documentation - Auto-generate screenshots for docs

The Stack

Node.js + Express + Puppeteer + @sparticuz/chromium
Enter fullscreen mode Exit fullscreen mode

Step 1: Setup

mkdir screenshot-api && cd screenshot-api
npm init -y
npm install express puppeteer-core @sparticuz/chromium
Enter fullscreen mode Exit fullscreen mode

Step 2: Basic Screenshot Endpoint

const express = require("express");
const chromium = require("@sparticuz/chromium");
const puppeteer = require("puppeteer-core");

const app = express();

app.get("/screenshot", async (req, res) => {
  const { url, width = 1280, height = 720 } = req.query;

  if (!url) return res.status(400).json({ error: "URL required" });

  const browser = await puppeteer.launch({
    args: chromium.args,
    executablePath: await chromium.executablePath(),
    headless: chromium.headless,
  });

  const page = await browser.newPage();
  await page.setViewport({ width: +width, height: +height });
  await page.goto(url, { waitUntil: "networkidle0" });

  const screenshot = await page.screenshot({ type: "png" });
  await browser.close();

  res.type("image/png").send(screenshot);
});

app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

Step 3: Add PDF Generation

app.get("/pdf", async (req, res) => {
  const { url } = req.query;
  // ... browser setup same as above

  const pdf = await page.pdf({ format: "A4" });
  await browser.close();

  res.type("application/pdf").send(pdf);
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Deploy to Vercel

Use @sparticuz/chromium-min for Vercel serverless:

npm install @sparticuz/chromium-min
Enter fullscreen mode Exit fullscreen mode

This keeps the bundle under Vercel 50MB limit.

Or Just Use an API

If you do not want to maintain your own infrastructure, CaptureAPI handles screenshots, PDFs, and OG images with a single endpoint. Free tier: 200 captures/month.

curl "https://captureapi.dev/api/screenshot?url=https://example.com"
Enter fullscreen mode Exit fullscreen mode

Full source code and docs at captureapi.dev

Top comments (0)