If you have ever shipped a feature that takes screenshots from Node.js, you already know the trap.
The first version looks simple:
await page.goto(url);
await page.screenshot({ path: "page.png", fullPage: true });
Then production arrives.
You need Chromium installed in the right environment. Fonts differ between machines. Pages hang forever. Cookie banners cover half the viewport. Some captures need mobile emulation. Some need PDFs. Some need to run in batches. Eventually, your "take a screenshot" helper turns into browser infrastructure.
That is the point where a hosted screenshot API becomes useful.
This post walks through capturing screenshots from Node.js with the official SnapshotFlow TypeScript SDK. The goal is not to hide the API behind magic. It is to keep your app code focused on the job: request a render, get back an image, PDF, JSON payload, batch result, or visual diff.
Install the SDK
SnapshotFlow ships an official npm package:
npm install snapshotflow
It requires Node.js 18 or later.
Create an API key in the SnapshotFlow dashboard, then store it in your environment:
export SNAPSHOTFLOW_API_KEY="your_api_key"
The SDK is a typed wrapper around the HTTP API. Rendering still happens on the backend, so your Node process does not need Puppeteer, Playwright, a Chromium binary, or a browser pool.
For the full reference, see the Node.js screenshot API guide.
Capture a basic screenshot
Start with the smallest useful example:
import { SnapshotFlow } from "snapshotflow";
const client = new SnapshotFlow({
apiKey: process.env.SNAPSHOTFLOW_API_KEY!,
});
const shot = await client.take({
url: "https://example.com",
fullPage: true,
width: 1440,
});
await shot.save("example.png");
The take() method returns a binary ScreenshotResult. That result includes:
buffercontentTypecachedetagsave(path)toBase64()blob()
So if you need to upload the image to S3, return it from an API route, or store it in a job artifact directory, you do not need to re-fetch anything.
Use TypeScript-friendly options
The HTTP API uses snake_case query parameters. The SDK lets you use camelCase options in Node.js:
const shot = await client.take({
url: "https://github.com",
width: 1440,
height: 900,
deviceScaleFactor: 2,
fullPage: true,
blockAds: true,
blockCookieBanners: true,
waitUntil: "networkidle2",
delay: 1000,
});
await shot.save("github.png");
That gives you a high-resolution full-page capture, waits for the page to settle, and blocks common distractions before the screenshot is taken.
This is where using an API starts to feel different from owning the browser stack. Your code describes the capture. The service handles the rendering environment.
Top comments (0)