ScreenshotNeo

BlogGuides

Puppeteer Screenshot Options Explained: Full Page, Clips, Formats, and Quality

Learn when to use Puppeteer’s fullPage, clip, and element screenshots, how formats and quality work, and how to save or process captures.

By the ScreenshotNeo team4 October 20267 min read

Choose the capture area first: set fullPage: true for the whole document, clip for a rectangle, or call screenshot() on an element handle for one DOM element. Then choose an output type and destination. Puppeteer defaults to PNG; its quality option applies to supported non-PNG formats, not PNG. The examples below use current Puppeteer APIs; check the reference for your installed version if behavior differs. Puppeteer ScreenshotOptions reference.

1. Install Puppeteer and take a basic screenshot

Install Puppeteer, then run this complete Node.js example. The package normally downloads a compatible browser during installation. If you manage a browser separately, use the corresponding Puppeteer configuration and version.

npm install puppeteer
// screenshot.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle2' });
    await page.screenshot({ path: 'page.png' });
  } finally {
    await browser.close();
  }
})();

Run it with node screenshot.js. The path extension can inform the screenshot type when type is omitted. To make the choice explicit, set type: 'png', 'jpeg', or 'webp' where supported by your Puppeteer/browser setup.

2. Capture the full page with fullPage

fullPage defaults to false, which captures the viewport. Set it to true to request the full page:

await page.screenshot({ path: 'full-page.png', fullPage: true });

Full-page capture is useful for long articles, landing pages, and visual regression artifacts. It can take longer and produce larger output as the page grows. A page with lazy-loaded content may not have loaded everything below the fold just because a screenshot is requested. Scroll through the page or wait for known content before capture when that content matters; the correct wait depends on the site.

3. Capture a rectangular region with clip

Use clip to capture a rectangle in page coordinates. Supply its x, y, width, and height; its optional scale defaults to 1.

await page.screenshot({
  path: 'region.png',
  clip: { x: 120, y: 240, width: 640, height: 360, scale: 1 }
});

Coordinates and dimensions must describe the intended region. If the clip extends beyond the current viewport, consider captureBeyondViewport. Its documented default is false when there is no clip and true when a clip is present. Set it explicitly if your capture depends on off-viewport content:

await page.screenshot({
  path: 'offscreen-region.png',
  clip: { x: 0, y: 900, width: 800, height: 450 },
  captureBeyondViewport: true
});

Check the ScreenshotClip reference and the API reference for the version you have installed if coordinate behavior differs.

4. Capture one DOM element

For a component such as a chart, card, or navigation bar, select the element and use its handle’s screenshot() method. Puppeteer scrolls the element into view if needed. If a script replaces or removes the element between selection and capture, the handle can become detached and the capture fails.

const card = await page.waitForSelector('.product-card');
if (!card) throw new Error('Product card was not found');
await card.screenshot({ path: 'product-card.png' });

For a changing page, wait for the element to appear and reacquire it close to the capture. This is a practical way to reduce failures caused by stale handles, not a guarantee against page changes. See Puppeteer’s screenshots guide and ElementHandle screenshot API.

5. Choose format, quality, and background

Option What it controls Use it when
type Image format; default is PNG You need to choose the output format explicitly
quality Numeric quality from 0 to 100 for applicable non-PNG formats You choose a format that supports quality control
omitBackground Hides the default white background You want a capture with transparency

For example, choose JPEG and set its quality, or omit the background for a transparent PNG:

await page.screenshot({ path: 'page.jpg', type: 'jpeg', quality: 82 });
await page.screenshot({ path: 'logo.png', type: 'png', omitBackground: true });

Do not set quality expecting sharper or smaller PNG output: Puppeteer documents that the option does not apply to PNG. The official reference lists options but does not provide a universal size, fidelity, or speed benchmark for formats. Choose based on your own output needs and inspect representative pages.

6. Save to disk or use the screenshot bytes

When you provide path, Puppeteer writes the image to that path. Without it, no file is saved. The default return value is a Uint8Array, which you can send to another API or store using Node’s filesystem module:

const fs = require('node:fs/promises');
const imageBytes = await page.screenshot({ type: 'png' });
await fs.writeFile('page.png', imageBytes);

Set encoding: 'base64' to receive a base64 string instead. Encoding is a representation choice, separate from the image format:

const base64 = await page.screenshot({ type: 'png', encoding: 'base64' });
console.log(base64);

See the Page.screenshot API reference for the return type and current option definitions.

7. Complete example covering the main options

This runnable example captures a full-page PNG, a clipped JPEG, an element, and a transparent image. It waits for the page to load and closes the browser even if an operation fails.

// options.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
    await page.goto('https://example.com', { waitUntil: 'networkidle2' });

    await page.screenshot({ path: 'full.png', type: 'png', fullPage: true });
    await page.screenshot({
      path: 'hero.jpg', type: 'jpeg', quality: 82,
      clip: { x: 0, y: 0, width: 1280, height: 500 }
    });

    const heading = await page.waitForSelector('h1');
    if (!heading) throw new Error('Heading was not found');
    await heading.screenshot({ path: 'heading.png' });

    await page.screenshot({ path: 'transparent.png', omitBackground: true });
  } finally {
    await browser.close();
  }
})();

8. Troubleshooting common screenshot problems

Symptom Likely cause What to do
Only the visible viewport is captured fullPage is omitted or false Set fullPage: true for the full document
The clip is empty, misplaced, or incomplete Coordinates or dimensions do not match the page layout; the region may extend outside the viewport Check the rectangle values and set captureBeyondViewport: true when needed
Element screenshot fails with a detached-node error The page removed or replaced the selected element Wait for the page’s state, then select the element again immediately before capture
PNG looks unchanged after changing quality quality does not apply to PNG Use an applicable non-PNG format if you need that quality setting
Transparent output appears white omitBackground was not enabled, or the page itself paints a background Set omitBackground: true; inspect page-level backgrounds if they remain
No file appears at the expected path No path was passed, or the relative path resolves from a different working directory Set an explicit path or write the returned bytes yourself
Screenshot captures loading placeholders The page navigation completed before the relevant content was ready Wait for a meaningful selector or application state before capture
Browser or page operation overlaps a capture Automation changes tabs or pages while a screenshot is in progress Sequence dependent operations; Puppeteer notes that bringToFront() does not wait for existing screenshot operations

9. Performance, reliability, and cost considerations

Capture time and output size depend on the page and the selected area; the cited API documentation provides no fixed performance benchmark. Full-page captures generally involve more page content than viewport captures, so use only the area your downstream task needs. Avoid waiting indefinitely for a network-idle condition on pages with persistent connections; wait for a specific selector or state when that is a better signal for your page.

For reliable automation, close the browser in a finally block, use explicit waits for content that matters, and keep page mutations separate from the screenshot operation. Pin compatible Puppeteer and browser versions in automated environments, and consult documentation for the installed release because option behavior can change. A local Puppeteer capture has no per-screenshot API charge, but your runtime still consumes compute and storage; account for those when running a capture service.

10. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request can return an image or PDF. See the ScreenshotNeo API documentation for the API options and response details.

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}`);
  • Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each removal step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses identify the page verdict and billing status in headers.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • 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.

Sign up for 1,000 free screenshots a month, no card required.

11. Frequently asked questions

Does fullPage include content that loads only after scrolling?

It requests a full-page capture, but it does not by itself guarantee that a site’s lazy-loaded content has been fetched. Scroll or wait for the content your use case requires.

Can I set both fullPage and clip?

They describe different capture scopes. Decide whether you need the document or a rectangle and use the corresponding option; consult the reference for your installed version if combining options.

Is quality: 100 lossless?

The API defines a numeric quality setting for applicable formats, but the reviewed documentation does not promise that a particular value is lossless. PNG does not use this option.

Does calling page.screenshot() save a file automatically?

No. Pass path to write a file, or handle the returned bytes or base64 string in your code.