Puppeteer Screenshot Options: Full-Page, Format, Quality, and More
Learn Puppeteer’s screenshot options for full pages, formats, quality, transparency, clips, elements, and file or in-memory output, with runnable examples.
To take a full-page screenshot in Puppeteer, pass fullPage: true to page.screenshot(). For example: await page.screenshot({ path: 'page.png', fullPage: true }); The default is a viewport screenshot. You can also choose PNG, JPEG, or WebP; set lossy-image quality; capture a clipped region or an element; make the background transparent; and save to a file or use the returned bytes.
This guide follows the current Puppeteer 25.12.0 API reference for page screenshots. Element-specific options are described in the 25.9.0 reference, so check your installed package’s types and documentation if you use another version. The examples below show documented API usage; they are not claims of independent execution testing.
1. Install Puppeteer and capture a full page
Install Puppeteer in a Node.js project. The package includes a compatible browser download in its standard installation flow. If your environment manages Chrome separately, use the browser executable and installation setup appropriate to that environment.
npm install puppeteer
Save this as screenshot.mjs and run it with Node.js:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
await browser.close();
}
fullPage defaults to false. When true, Puppeteer requests a screenshot of the full page. The guide’s networkidle2 navigation wait is an example, not a universal readiness rule: pages with persistent network activity or delayed content may need a different readiness condition.
2. Choose the capture area
Viewport screenshot
Call page.screenshot() without fullPage to capture the page’s current viewport. Set the viewport before navigation if the page’s responsive layout matters:
await page.setViewport({ width: 1440, height: 900 });
await page.goto('https://example.com');
await page.screenshot({ path: 'viewport.png' });
Full-page screenshot
Set fullPage: true to capture beyond the visible viewport and include the full page:
await page.screenshot({ path: 'full-page.png', fullPage: true });
Long pages can produce large images and take longer to process. Pages that load content only as the user scrolls may need an application-specific scroll or readiness step before capture; a full-page setting alone does not establish that every site has finished populating its content.
Clip a region
Use clip to specify a rectangular area. Its bounding box uses x, y, width, and height:
await page.screenshot({
path: 'region.png',
clip: { x: 80, y: 120, width: 640, height: 400 }
});
captureBeyondViewport is another documented control. Its default is false when there is no clip and true when a clip is supplied. Set it explicitly if your capture logic depends on that behavior, and ensure the clip dimensions and coordinates describe the intended region.
Capture one element
For a specific element, select it and call ElementHandle.screenshot(). Puppeteer’s guide says it tries to scroll a hidden element into view by default. The element options reference lists scrollIntoView as defaulting to true.
const card = await page.$('.product-card');
if (!card) {
throw new Error('Could not find .product-card');
}
await card.screenshot({ path: 'product-card.png' });
Use a selector that identifies one element in the rendered page. If the element is missing because the page has not rendered it yet, wait for the selector before taking the screenshot.
3. Set image format and quality
The supported image formats are png, jpeg, and webp. PNG is the default. The quality option accepts a number from 0 to 100, but it does not apply to PNG. Use it with a lossy format when you want to specify an encoding quality; the API reference does not prescribe a best value or quantify the resulting file-size difference.
await page.screenshot({
path: 'page.webp',
type: 'webp',
quality: 80,
fullPage: true
});
You can use JPEG similarly:
await page.screenshot({
path: 'page.jpg',
type: 'jpeg',
quality: 85
});
When you provide path, Puppeteer can infer the image type from the file extension. You can also provide type explicitly. Keep the extension and requested type consistent so downstream tools and teammates can identify the output correctly.
4. Capture a transparent background
Set omitBackground: true to hide the default white background and allow a transparent screenshot. The option defaults to false.
await page.screenshot({
path: 'transparent.png',
omitBackground: true
});
Transparency is useful for compositing page content into another design. It does not guarantee every page element or browser configuration will render transparency identically; inspect the result in the formats and viewers your workflow uses.
5. Save a file or use screenshot bytes
With path, Puppeteer writes the image to disk. Relative paths are resolved from the current working directory. Without a path, Puppeteer does not save the screenshot to disk: the normal Page.screenshot() overload returns a Promise<Uint8Array>. Set encoding: 'base64' to receive a base64 string instead.
import { writeFile } from 'node:fs/promises';
const bytes = await page.screenshot({ type: 'png' });
await writeFile('page.png', bytes);
const base64 = await page.screenshot({ encoding: 'base64', type: 'png' });
console.log(base64);
Use bytes when you want to upload the result, store it in an object store, or pass it to another function without creating an intermediate file. Base64 is convenient for text-based transport, but it represents binary data as text; choose the representation your receiving system expects.
6. Combine options in one capture
Screenshot options can be combined when they serve the same capture. This example requests a full-page WebP with a specified lossy quality and writes it to disk:
await page.screenshot({
path: 'full-page.webp',
fullPage: true,
type: 'webp',
quality: 80
});
For transparent output, use a format and page setup that support the result your workflow needs, then inspect the generated image. Quality does not affect PNG. If combining clip, fullPage, or captureBeyondViewport, refer to the installed Puppeteer version’s API types for the exact behavior you intend.
7. Screenshot options at a glance
| Option | Purpose | Documented default or detail |
|---|---|---|
fullPage |
Request a full-page capture | false |
type |
Image encoding: PNG, JPEG, or WebP | png |
quality |
Set encoding quality for a lossy format | 0–100; does not apply to PNG |
omitBackground |
Hide the default white background and allow transparency | false |
clip |
Choose a rectangular screenshot region | Coordinates and dimensions define the region |
captureBeyondViewport |
Control capture beyond the viewport | false without a clip; true with one |
path |
Write the image to disk | Extension can determine format; relative paths use the working directory |
encoding |
Choose returned data encoding | binary; base64 returns a string |
fromSurface |
Capture from the surface rather than the view | true |
optimizeForSpeed |
Configure the screenshot operation | false; the reference does not explain its trade-off |
fromSurface and optimizeForSpeed are documented options, but the current reference does not establish practical performance effects for optimizeForSpeed. Do not assume a speed gain from its name alone.
8. Wait for the page state you need
A screenshot captures the rendered state available at capture time. Navigation completion and visual readiness are different concerns: some sites fetch content after navigation, animate elements, or load images lazily. Pick a readiness condition based on the page and capture goal.
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('.report-ready');
await page.screenshot({ path: 'report.png', fullPage: true });
Use a selector that signals the actual content is ready when the page exposes one. A fixed delay may be useful for a known transition, but it can waste time on fast loads and still be too short on slow ones. Avoid assuming that network idle is appropriate for every page, especially if the site keeps connections open or performs background requests.
9. Troubleshooting Puppeteer screenshots
| Symptom | Likely cause | What to do |
|---|---|---|
| Only the visible screen is captured | fullPage was omitted or is false |
Pass fullPage: true. |
| The output is still PNG despite a quality value | quality does not apply to PNG |
Set type: 'jpeg' or type: 'webp'; keep quality within 0–100. |
| The screenshot is not saved where expected | No path was provided, or a relative path resolved from a different working directory |
Set a path and confirm the process working directory; without a path, consume the returned bytes. |
| The element screenshot fails or captures the wrong thing | The selector matched no element, matched an unexpected element, or the page was not ready | Wait for the intended selector, check the handle exists, and use a sufficiently specific selector. |
| An element is outside the visible viewport | The element needs scrolling before capture | Element screenshots try to scroll hidden elements into view by default; inspect the installed version’s element options and set scrollIntoView deliberately if needed. |
| A clipped screenshot has unexpected bounds | The clip coordinates or dimensions do not match the desired region | Check x, y, width, and height, and review captureBeyondViewport. |
| Content is missing from the image | Capture ran before content or lazy-loaded assets were ready | Wait for a page-specific readiness signal; for lazy content, use the site’s needed scroll/loading sequence before capture. |
| Transparent areas appear white in a viewer | The output or viewing path may not preserve or display transparency as expected | Set omitBackground: true, use a suitable output path, and inspect the file in a transparency-aware viewer. |
| Capture is slow or memory use is high | A very tall page or large viewport creates a large image | Capture only the required region or element, reduce the viewport when appropriate, and avoid retaining unnecessary copies of the bytes. |
10. Performance, reliability, and cost
Puppeteer’s screenshot options define output and capture behavior; the cited API references provide no benchmark, recommended quality setting, or quantified format trade-off. Full-page captures of long pages can involve more image data than viewport or element captures, so use the smallest capture area that satisfies the task when output size and processing matter.
For reliable automation, wait on a page-specific readiness condition, handle missing selectors, close the browser in a finally block, and write or upload returned bytes explicitly. A screenshot API’s options do not by themselves guarantee that a site is reachable or that its content is stable.
Running Puppeteer means managing a browser process and its runtime environment. If you would rather make a screenshot request without setting up browser automation, ScreenshotNeo provides a website screenshot API and MCP server. Its billing rules and plan prices are stated below.
11. Or skip the browser setup
ScreenshotNeo takes a website URL in one GET request and returns a PNG, JPEG, WebP, or PDF. Its clean-shot flow accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms along with newsletter popups and chat widgets; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the page verdict and billing status in headers.
It also offers an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. The API supports full-page capture, CSS selector capture, device and viewport settings, custom CSS and JavaScript, waiting controls, request blocking, headers and cookies, PDF options, caching, bulk capture, and more. See the ScreenshotNeo API documentation for the available parameters.
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,
)
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}`);
Replace YOUR_API_KEY with your key and change the target URL. The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed; and an MCP server lets AI agents take screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
12. FAQ
How do I take a full-page screenshot in Puppeteer?
Call page.screenshot({ fullPage: true }), optionally adding a path such as page.png.
Does Puppeteer screenshot quality work with PNG?
No. The documented quality range is 0–100 and does not apply to PNG.
Does Puppeteer save screenshots automatically?
Only when you provide a path. Without one, use the returned bytes or request base64 encoding.
What is the difference between page and element screenshots?
page.screenshot() captures the page viewport or full page. ElementHandle.screenshot() targets a selected element.
Which Puppeteer options are best for faster screenshots?
The cited reference lists optimizeForSpeed but does not describe its trade-off or provide performance measurements, so it does not support a general recommendation.


