tutorial

Capture Screenshots Programmatically

Introduction

Taking website screenshots programmatically is a common requirement in modern web development. Whether you need to generate social media previews, run visual regression tests, archive web pages for compliance, or create thumbnail galleries, automating screenshot capture saves hours of manual work.

This guide walks you through three approaches — from the simplest API call to full browser automation — so you can choose the method that fits your project.

Why Capture Screenshots Programmatically?

Manual screenshots do not scale. When you need to capture hundreds of pages, generate previews on-the-fly, or integrate capture into a CI/CD pipeline, automation is the only practical option.

Common use cases include:

  • Visual regression testing — Detect unintended UI changes before they reach production
  • Social media previews — Generate Open Graph images or link preview thumbnails automatically
  • Web archiving — Capture and store point-in-time snapshots of websites for legal or compliance purposes
  • PDF generation — Convert web pages to PDF documents for reports, invoices, or documentation
  • Monitoring dashboards — Capture periodic screenshots of dashboards to track metrics over time
  • Thumbnail galleries — Display visual previews of links in content management systems

Methods for Taking Website Screenshots

Using a Screenshot API (Simplest)

A screenshot API handles the browser, rendering engine, and infrastructure for you. You send a URL, you get an image back. No dependencies to install, no servers to maintain.

PageShot is a free screenshot API powered by Chromium. It requires no API keys, no signup, and no payment. One HTTP request returns a fully rendered screenshot.

curl "https://pageshot.site/v1/screenshot?url=https://example.com" -o screenshot.png
const response = await fetch(
  'https://pageshot.site/v1/screenshot?url=https://example.com'
);
const buffer = await response.arrayBuffer();
fs.writeFileSync('screenshot.png', Buffer.from(buffer));
import requests

response = requests.get(
    'https://pageshot.site/v1/screenshot',
    params={'url': 'https://example.com'}
)

with open('screenshot.png', 'wb') as f:
    f.write(response.content)

Using Puppeteer

Puppeteer is a Node.js library that controls a headless Chromium browser. It gives you full control over the browser lifecycle but requires installing Chromium (~400MB) and managing the process yourself.

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await browser.close();

Puppeteer is a good choice when you need fine-grained browser control, such as interacting with pages before capturing, handling authentication flows, or manipulating the DOM.

Using Playwright

Playwright supports Chromium, Firefox, and WebKit, making it ideal for cross-browser testing. The API is similar to Puppeteer but offers broader browser coverage and built-in auto-waiting.

const { chromium } = require('playwright');

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await browser.close();

Playwright is the best option when you need to verify rendering across multiple browser engines or when you are already using it for end-to-end testing.

Step-by-Step: Screenshot with PageShot API

Step 1: Choose Your Screenshot Options

PageShot supports several options to control the output:

Parameter Type Default Description
url string required The webpage URL to capture
format string png Output format: png, jpeg, or webp
width number 1280 Viewport width in pixels
height number 720 Viewport height in pixels
fullPage boolean false Capture the entire scrollable page
delay number 0 Wait time in ms before capture

Step 2: Make the API Call

Simple GET request — pass parameters as query strings:

curl "https://pageshot.site/v1/screenshot?url=https://example.com&format=jpeg&width=1920&height=1080" \
  -o screenshot.jpg

POST request — pass a JSON body for more complex options:

curl -X POST "https://pageshot.site/v1/screenshot" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "format": "png",
    "width": 1440,
    "height": 900,
    "fullPage": true,
    "delay": 2000
  }' -o screenshot.png

Convert HTML directly to an image without hosting it first:

curl -X POST "https://pageshot.site/v1/html" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Hello World</h1><p>Generated with PageShot</p>",
    "format": "png",
    "width": 800,
    "height": 600
  }' -o html-screenshot.png

Step 3: Process the Response

The API returns the image binary directly. Save it to a file, upload it to cloud storage, or pipe it into your image processing pipeline:

const response = await fetch('https://pageshot.site/v1/screenshot', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com',
    format: 'webp',
    fullPage: true,
    delay: 1000
  })
});

const imageBuffer = Buffer.from(await response.arrayBuffer());

fs.writeFileSync('screenshot.webp', imageBuffer);

const s3Key = `screenshots/${Date.now()}.webp`;
await s3.upload({ Bucket: 'my-bucket', Key: s3Key, Body: imageBuffer }).promise();

Advanced Options

PageShot also supports additional capture modes:

  • Quick previewGET /v1/preview?url=https://example.com returns a smaller, faster preview image suitable for thumbnails
  • PDF exportPOST /v1/pdf converts any URL to a PDF document, useful alongside PDFSpark for document workflows
  • HTML to imagePOST /v1/html renders raw HTML to an image without needing a hosted page

Comparison Table: API vs Puppeteer vs Playwright

Feature PageShot API Puppeteer Playwright
Setup time Zero 5-10 minutes 5-10 minutes
Dependencies None Chromium (~400MB) Chromium/Firefox/WebKit
Infrastructure Managed Self-hosted Self-hosted
API key required No N/A N/A
Cross-browser Chromium Chromium only Chromium, Firefox, WebKit
Full-page capture Yes Yes Yes
Custom viewport Yes Yes Yes
HTML to image Yes Manual setup Manual setup
PDF export Yes Yes Yes
Cost Free Compute costs Compute costs
Best for Quick integration Full browser control Cross-browser testing

When to Use Each Approach

Choose PageShot API when you want the fastest integration with zero infrastructure overhead — ideal for prototyping, side projects, thumbnail generation, and any workflow where you just need an image from a URL.

Choose Puppeteer when you need to interact with the page before capturing (filling forms, clicking buttons, handling auth) and only need Chromium.

Choose Playwright when cross-browser fidelity matters or when you are already using Playwright for end-to-end testing and want to add visual testing on top.


Start capturing screenshots now — try the interactive playground or read the API documentation. Want to compare options? See our screenshot API comparison. For visual testing workflows, read automated visual regression testing with screenshots. For PDF conversion, check out PDFSpark. Need OG images? Try OGForge. Extract URL metadata with LinkMeta.

screenshot-apiprogrammatic-screenshotsweb-capturepuppeteerplaywrighttutorial
Share this article: Twitter LinkedIn
← Back to Blog
Part of the SoftVoyagers Ecosystem