How to Capture Website Screenshots with Node.js in 2026
SA
SnapAPI Team
January 31, 2026 · 8 min read
How to Capture Website Screenshots with Node.js in 2026
January 31, 2026 • 5 min read
Photo by Safar Safarov on Unsplash
Taking screenshots of websites programmatically is a common need for developers. Whether you're building link previews, generating thumbnails, or creating visual testing tools, you need a reliable way to capture web pages.
This guide covers everything from your first screenshot to production patterns: error handling, retries, caching, and processing screenshots at scale in Node.js.
Installation and setup
npm install @sleywill/snapapi-js
# or use fetch directly — no dependencies required
const screenshot = await client.screenshot({
url: 'https://example.com',
format: 'png', // png | jpeg | webp | avif
full_page: true, // capture entire scrollable page
width: 1440, // viewport width
device: 'iphone_15', // or any of 26 device presets
wait_until: 'networkidle', // wait for all network requests
delay: 1000, // extra ms after load
block_ads: true, // block ads and cookie banners
dark_mode: false, // force dark/light mode
});
Express.js: Screenshot endpoint
import express from 'express';
import SnapAPI from '@sleywill/snapapi-js';
const app = express();
const snap = new SnapAPI(process.env.SNAPAPI_KEY);
app.get('/screenshot', async (req, res) => {
const { url } = req.query;
if (!url) return res.status(400).json({ error: 'url required' });
try {
const result = await snap.screenshot({
url: decodeURIComponent(url),
format: 'jpeg',
full_page: false,
width: 1200
});
// Redirect to screenshot URL or proxy it
res.redirect(result.url);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(3000);
Generating PDFs from HTML in Node.js
// Generate a PDF from any URL
const pdf = await snap.pdf({
url: 'https://example.com/invoice/123',
format: 'A4', // A4 | A3 | Letter | Legal
landscape: false,
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
print_background: true
});
console.log(pdf.url); // PDF URL ready to download or store
Batch screenshots with Promise.all
const urls = ['https://site1.com', 'https://site2.com', 'https://site3.com'];
// Parallel (faster, uses more quota simultaneously)
const results = await Promise.all(
urls.map(url => snap.screenshot({ url, format: 'jpeg' }))
);
// Sequential with rate control (for large batches)
const screenshots = [];
for (const url of urls) {
screenshots.push(await snap.screenshot({ url, format: 'jpeg' }));
await new Promise(r => setTimeout(r, 100)); // 100ms between requests
}
One of the most common Node.js use cases for screenshot APIs is generating Open Graph images for social sharing. Here's how to integrate SnapAPI into a Next.js API route:
// pages/api/og-image.js
import SnapAPI from '@sleywill/snapapi-js';
const snap = new SnapAPI(process.env.SNAPAPI_KEY);
export default async function handler(req, res) {
const { url } = req.query;
const screenshot = await snap.screenshot({
url: decodeURIComponent(url),
width: 1200,
height: 630, // Standard OG image dimensions
format: 'jpeg',
full_page: false,
wait_until: 'networkidle'
});
// Cache for 1 hour
res.setHeader('Cache-Control', 's-maxage=3600');
res.setHeader('Location', screenshot.url);
res.status(302).end();
}
Set timeout of 30s on all HTTP calls (some heavy pages take time)
Use full_page: true for archival/monitoring, false for OG images
Add a caching layer (Redis / filesystem) for frequently captured URLs
Log API response times to catch latency regressions
Set up a health check that calls the API once per minute and alerts on failure
Following this checklist ensures your screenshot integration is production-grade from day one — no late-night debugging when a timeout takes down your invoice generation flow.
TypeScript types are generated from the OpenAPI spec and published with every SDK release. All parameters, response shapes, and error types are fully typed — no any casts required in your integration code.