How to Set the Screenshot File Path and Name in Puppeteer
Use Puppeteer’s `path` option to choose a screenshot’s directory and filename. See runnable examples, path and format details, and common fixes.
Pass a path string to page.screenshot(). It specifies both the destination directory and filename:
await page.screenshot({ path: 'screenshots/homepage.png' });
A relative path is resolved from the Node.js process’s current working directory. The file extension tells Puppeteer which screenshot type to use; PNG is the documented default. Make sure the destination directory exists before saving. Puppeteer ScreenshotOptions documents these path and format options, and the screenshots guide shows the basic pattern.
Save a screenshot to a chosen path
Here is a complete example using Puppeteer. It creates the output directory explicitly, opens a page, and saves the screenshot with a specific name. Install Puppeteer with npm install puppeteer, then save this as capture.mjs and run node capture.mjs.
import puppeteer from 'puppeteer';
import { mkdir } from 'node:fs/promises';
const outputDirectory = 'screenshots';
const outputPath = `${outputDirectory}/homepage.png`;
await mkdir(outputDirectory, { recursive: true });
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: outputPath, fullPage: true });
console.log(`Saved screenshot to ${outputPath}`);
} finally {
await browser.close();
}
The path value includes the directory and filename in one string. If you omit the directory, the file is written to the working directory. This example creates its output directory rather than assuming Puppeteer will create it.
How Puppeteer resolves the path
A relative path is based on the process’s current working directory, which is the directory from which Node.js is running. It is not automatically based on the folder containing the script or on a presumed project root. For example, if the process runs from /srv/app, then screenshots/homepage.png refers to /srv/app/screenshots/homepage.png.
To avoid ambiguity, use an absolute path when the output location must be independent of the launch directory:
import path from 'node:path';
const outputPath = path.resolve('screenshots', 'homepage.png');
await page.screenshot({ path: outputPath });
path.resolve() uses the current working directory as its base when its arguments are relative. Log process.cwd() if a file appears in an unexpected location.
Choose the screenshot filename and format
The filename is yours to choose, and its extension is how Puppeteer infers the image type. Use a matching extension, such as .png or .jpeg. PNG is the documented default when a type is not otherwise specified. Check the current ScreenshotOptions API for supported types and options for the version you have installed; do not assume an arbitrary extension is supported.
await page.screenshot({ path: 'output/report.png' });
await page.screenshot({ path: 'output/report.jpeg', type: 'jpeg', quality: 85 });
Use quality with JPEG or WebP when supported by your Puppeteer version and selected type. It does not apply to PNG. If you specify a type that conflicts with the extension, keep them aligned so the filename describes the actual image format.
Save an element screenshot to a path
The same path option works with an element handle’s screenshot() method. Puppeteer scrolls the element into view if needed. The call can throw if the element’s handle has detached from the DOM before capture. See ElementHandle.screenshot().
const element = await page.waitForSelector('article');
if (!element) throw new Error('Article element was not found');
await element.screenshot({ path: 'screenshots/article.png' });
Ensure the parent directory exists here too. If the page replaces the target element during rendering, wait for the final element or reselect it immediately before taking the screenshot.
Use screenshot bytes instead of a file path
If you omit path, Puppeteer returns screenshot data instead of writing a file. The normal return value is a Uint8Array; base64 output is also available. This is useful when the next step uploads the image, stores it in object storage, or sends it to another service. See Page.screenshot().
const bytes = await page.screenshot({ type: 'png' });
// bytes is a Uint8Array; pass it to the storage or upload code you use.
Choose either a destination path or returned data based on what the rest of your application needs. A path is convenient for a local artifact; returned bytes avoid a separate local-file read when the consumer accepts binary data.
Options that affect the captured file
The path controls where the screenshot is saved and its name. Other screenshot options affect what is captured or how it is encoded:
fullPage: truecaptures the full page rather than just the viewport.typeselects an image type; the filename extension is used for inference when applicable.qualitycontrols lossy image quality for supported JPEG or WebP output.clipcaptures a specified rectangular region.omitBackground: truecan produce a transparent background for supported output types.encoding: 'base64'returns a base64 string when consuming the screenshot result rather than saving by path.
Option availability and behavior can depend on the installed Puppeteer version. Consult the API reference for ScreenshotOptions and Page.screenshot() when combining options.
Common errors and fixes
| Problem | Likely cause | Fix |
|---|---|---|
| No file appears | The relative path points under a different current working directory, or no path was passed. |
Pass path, log process.cwd(), and resolve the output path explicitly. |
| Screenshot call fails when writing | The destination directory does not exist or the process cannot write there. | Create the directory with mkdir(..., { recursive: true }) and check the process’s filesystem permissions. |
| Image has an unexpected format | The extension and selected type do not match, or the extension is not supported. | Use a documented image type and a corresponding extension; check the installed version’s API reference. |
| Element screenshot throws | The element handle detached from the DOM, often because the page replaced it. | Wait for the final element state, then query the element again before calling screenshot(). |
| Image is cut off | The call captured only the viewport, or the intended element/page was not ready. | Use fullPage: true for a full-page capture, or capture the intended element after it appears. |
| Screenshot is blank or incomplete | Capture began before navigation or relevant page content finished rendering. | Wait for navigation or a page-specific selector before capturing; choose a navigation wait condition appropriate to the site. |
Performance, reliability, and storage
- Keep paths deterministic: use an explicit absolute path or construct paths from a known working directory, especially in CI and scheduled jobs.
- Create directories deliberately: prepare the destination before capture and handle filesystem errors separately from navigation or screenshot errors.
- Use the smallest capture that meets the need: a viewport or element screenshot can use less memory and disk than a full-page image.
- Pick the format for the consumer: PNG preserves lossless image data, while lossy formats can reduce file size when their quality is acceptable.
- Manage names for repeated runs: a fixed filename is overwritten by later captures. Add a unique identifier or timestamp when each run must be retained.
- Close the browser in a
finallyblock: this releases browser resources if navigation or screenshot writing fails.
Puppeteer itself does not determine how much your output storage costs. Consider image dimensions, format, retention, and whether local files are temporary or need to be uploaded and retained.
Or skip the browser setup
If you only need a screenshot file and do not need to manage a Puppeteer browser, ScreenshotNeo provides a screenshot API. The one-call request below saves the returned image bytes as a file. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
- Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free 1,000 screenshots per month, with no card required.
FAQ
Does Puppeteer choose the filename automatically?
Only if you provide it through the path option. Set the name and directory in that string.
Is the relative path based on the script’s location?
It is based on the Node.js process’s current working directory. Use an absolute path if the launch directory may vary.
Can I save an element capture under a different filename?
Yes. Pass the desired destination and filename as the element screenshot’s path option.
Can I use the screenshot without writing it to disk?
Yes. Omit path and consume the returned screenshot data, normally a Uint8Array.


