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 preview —
GET /v1/preview?url=https://example.comreturns a smaller, faster preview image suitable for thumbnails - PDF export —
POST /v1/pdfconverts any URL to a PDF document, useful alongside PDFSpark for document workflows - HTML to image —
POST /v1/htmlrenders 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.