October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
browser automation

How to Capture a Full-Page Screenshot with Puppeteer Scrolling

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a normal full-page image, use Puppeteer’s built-in option: await page.screenshot({ path: 'page.png', fullPage: true }). If you must make the page load or reveal content while traversing it, use a different workflow: scroll in controlled increments, wait for page-specific content, capture overlapping viewport images, and stitch them with an image tool. Puppeteer documents the screenshot and scrolling primitives, but not one universal scroll-and-stitch recipe.

Choose the capture method first

There are two valid interpretations of “full-page screenshot.” Pick the one that matches the job rather than adding scrolling automatically.

Approach Best fit Trade-offs
fullPage: true One image of the page with minimal code Uses Puppeteer’s documented screenshot option, but it does not model a workflow in which scrolling itself triggers or reveals content.
Scroll, capture, and stitch Pages that require traversal, incremental loading, or inspection at each position Requires readiness logic, overlap planning, image stitching, and checks for dynamic content, seams, duplicated fixed elements, and missed loads.

The second row is an implementation pattern derived from Puppeteer’s documented screenshot and scrolling capabilities, not a built-in Puppeteer feature or a guaranteed recipe for every site.

Prerequisites and a stable viewport

  • Install a current Puppeteer package in a Node.js project: npm install puppeteer.
  • Use a fixed viewport before navigation. Width and height are CSS pixels, and deviceScaleFactor defaults to 1.
  • Record the viewport values so every segment has the same geometry.
  • Configure the viewport before goto() when possible. Changing it can reload a page in some circumstances, and some sites do not expect phone-like viewport changes.

A deliberate viewport also makes the output reproducible. For example, { width: 1440, height: 900, deviceScaleFactor: 1 } describes a 1× desktop capture; a higher device scale factor produces more physical pixels without changing the CSS layout dimensions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Screen recorder software for PC – record videos and take screenshots from your computer screen – compatible with Windows 11, 10, 8, 7
  • Record videos and take screenshots of your computer screen including sound
  • Highlight the movement of your mouse
  • Record your webcam and insert it into your screen video
  • Edit your recording easily
  • Perfect for video tutorials, gaming videos, online classes and more

Fast path: Puppeteer’s built-in full-page screenshot

Page.screenshot() is Puppeteer’s page screenshot method. In ScreenshotOptions, fullPage defaults to false; setting it to true requests the full page. Do not confuse it with captureBeyondViewport: that option controls capture outside the viewport and defaults to false when there is no clip and true otherwise.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}

networkidle2 is only a starting readiness condition. A page with long-lived connections, delayed images, animations, or application-specific requests may need a selector wait, an explicit delay, or another page-specific signal before capture.

When this method is enough

  • You need one document-like image and do not need to observe intermediate scroll positions.
  • The page’s content is already present or becomes ready under a condition you can express before the screenshot.
  • You can validate that lazy media, sticky elements, and dynamic sections appear correctly in the resulting file.

Manual scrolling workflow

Use this pattern when traversal is part of the requirement. It captures one viewport at a time and leaves stitching to an image-processing library. The loop below is intentionally conservative: it fixes the viewport, measures the page, scrolls by less than one viewport height to create overlap, waits briefly for page-specific work, and records each segment.

import puppeteer from 'puppeteer';
import fs from 'node:fs/promises';

const url = 'https://example.com';
const width = 1440;
const height = 900;
const overlap = 120;
const settleMs = 500;

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.setViewport({ width, height, deviceScaleFactor: 1 });
  await page.goto(url, { waitUntil: 'networkidle2' });

  const pageHeight = await page.evaluate(() =>
    Math.max(
      document.body.scrollHeight,
      document.documentElement.scrollHeight,
      document.body.offsetHeight,
      document.documentElement.offsetHeight
    )
  );
  const step = Math.max(1, height - overlap);
  const files = [];

  for (let y = 0; y < pageHeight; y += step) {
    await page.evaluate((top) => window.scrollTo(0, top), y);
    await new Promise(resolve => setTimeout(resolve, settleMs));

    const actualY = await page.evaluate(() => window.scrollY);
    const file = `segments/segment-${files.length.toString().padStart(3, '0')}.png`;
    await fs.mkdir('segments', { recursive: true });
    await page.screenshot({ path: file });
    files.push({ file, top: actualY });
  }

  console.log(JSON.stringify({ width, height, pageHeight, overlap, files }, null, 2));
} finally {
  await browser.close();
}

This code is an implementation pattern, not an official Puppeteer scroll-and-stitch API. The delay is deliberately a placeholder: replace it with a condition that reflects the page you are capturing. For example, wait for a lazy-image selector to become complete, for a “load more” operation to finish, or for a known application state. A fixed sleep alone cannot establish that every site’s content has finished loading.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why overlap matters

Adjacent screenshots should overlap by a known number of CSS pixels. Overlap gives a stitching process shared visual material for alignment and lets you crop a repeated strip from each subsequent image. Without overlap, a one-pixel scroll discrepancy or a layout shift can produce a visible gap.

Stitching the segments

Puppeteer’s screenshot API does not stitch files. Use an image-processing tool after capture. A simple vertical compositor can place each segment at the recorded scroll offset, then crop the canvas to the page’s measured height. If your page contains fixed headers, cookie notices, or animated elements, inspect every seam: those elements can repeat in each segment or change position between captures.

Rank #2
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
  • Mix an audio, music and voice tracks
  • Record single or multiple tracks simultaneously
  • Intuitive tools to split, trim, join, and many other editing features
  • Loaded with audio effects including EQ, compression, reverb, and more.
  • Load an audio file and export to all popular audio formats from studio quality wav to high compression formats

For reliable stitching, keep the viewport and device scale factor constant, preserve the measured offsets, and use the overlap to identify duplicate rows. If content changes height after the first measurement, recalculate the document height or stop only after the scroll position and page height have stabilized.

Making lazy content appear during traversal

Puppeteer documents locator scrolling through mouse-wheel events and waits for visibility and a stable bounding box before the scroll action. That behavior does not prove that all lazy-loaded content is complete. Your loop must define what “settled” means for this page.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Useful readiness checks

  • Wait for a specific section or image selector that the page promises to render.
  • After scrolling, check that targeted images report completion, or that a loading marker disappears.
  • Allow a page-specific delay for animation or deferred layout, then verify the measured document height again.
  • For infinite scroll, continue until a terminal condition (such as “no more results”) appears; do not assume the initial scrollHeight is final.

Keep these checks close to the content they protect. A global “network idle” event can be misleading on pages that maintain analytics or streaming connections, while a short delay can be insufficient for a large image or client-rendered section.

Element-only captures

If the requirement is one DOM element rather than the entire document, obtain its ElementHandle and call its screenshot method:

const element = await page.$('.invoice');
if (!element) throw new Error('Missing .invoice element');
await element.screenshot({ path: 'invoice.png' });

ElementHandle.screenshot() scrolls the element into view when necessary and then uses Page.screenshot(). It errors if the element has been detached, so reacquire the handle after a framework re-render instead of reusing a stale reference.

Output, scale, and browser-protocol considerations

  • Choose PNG when lossless text and transparent pixels matter; choose JPEG or WebP when file size is more important and your pipeline accepts those formats.
  • Viewport dimensions are CSS pixels. A deviceScaleFactor greater than one increases output pixel density but also increases memory and file size.
  • Do not infer identical option support across every connection mode. Puppeteer’s WebDriver BiDi documentation lists supported screenshot parameters and notes that not all screenshot parameters are supported, so check the actual Puppeteer and browser versions used by your deployment.
  • Validate very tall pages in your own environment. A single full-page bitmap can consume substantial memory, while segmented capture limits each screenshot but adds stitching work.

Troubleshooting common failures

The output covers only the viewport

Confirm that you called page.screenshot({ fullPage: true }) for the fast path. In a manual workflow, confirm that the scroll loop actually changes window.scrollY and that you are not saving the same file repeatedly.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Lazy images are blank

Scrolling does not guarantee completion. Add a selector-based or image-completion check after each scroll, allow the page’s own loading state to settle, and capture again. If the page changes height as images arrive, measure height repeatedly and extend the loop.

Sticky headers or banners repeat

Repeated fixed elements are a normal risk of viewport segmentation. Record their height, crop or mask the repeated region during stitching, and verify that a consent banner or chat widget is not altering the layout between segments.

Segments have seams or gaps

Use a fixed viewport and an explicit overlap. Stitch using the recorded scroll offsets, then inspect seams for layout shifts. Avoid animations where possible, or wait until the relevant element’s bounding box is stable.

The page height keeps increasing

This usually indicates infinite scroll, deferred rendering, or a script that inserts content after every traversal. Define a stopping condition, recalculate scrollHeight, and protect the loop with a maximum segment count so a faulty page cannot run indefinitely.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An element handle is detached

The DOM node was replaced after you obtained the handle. Query the selector again immediately before element.screenshot(), and wait for the replacement element to be visible and stable.

Changing the viewport changes the page

Set the viewport before navigation and keep the same dimensions for every segment. A viewport change can reload the page or activate a different responsive layout, invalidating earlier measurements.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance and reliability checklist

  1. Set and record width, height, and device scale factor before navigation.
  2. Choose fullPage: true unless traversal itself is required.
  3. For scrolling, define the page-specific readiness signal before writing the loop.
  4. Use overlap and retain each segment’s actual scroll offset.
  5. Re-measure page height when dynamic content can change it.
  6. Close the browser in a finally block, even when navigation or capture fails.
  7. Open the final image and inspect the top, bottom, lazy media, fixed elements, and every stitch seam.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API when you would rather make one request than maintain Puppeteer launch, viewport, waiting, and stitching code. Its capture pipeline accepts cookie and consent banners before the shot and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

Use the documented API call below (replace the URL and key):

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
  • Transform audio playing via your speakers and headphones
  • Improve sound quality by adjusting it with effects
  • Take control over the sound playing through audio hardware
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

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)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for the remaining options. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Every plan includes the available features, including full-page capture, selector capture, custom CSS and JavaScript, waits, request blocking, headers and cookies, device presets, PDF output, caching, signed links, asynchronous jobs, bulk capture, and a usage API.

Create a free ScreenshotNeo account to get the 1,000 monthly screenshots without a card.

Frequently Asked Questions

Should I always scroll instead of using fullPage?

No. Use fullPage: true for a conventional single-image capture. Scroll-and-stitch is appropriate when traversal itself must trigger, reveal, or inspect content.

Can Puppeteer stitch screenshots by itself?

No. Puppeteer captures the page or viewport; stitching the resulting files is a separate image-processing step.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What does captureBeyondViewport replace?

It does not replace fullPage. It controls capture outside the viewport and has different defaults depending on whether a clip is supplied.

Quick Recap

Bestseller No. 1
Screen recorder software for PC – record videos and take screenshots from your computer screen – compatible with Windows 11, 10, 8, 7
Screen recorder software for PC – record videos and take screenshots from your computer screen – compatible with Windows 11, 10, 8, 7
Record videos and take screenshots of your computer screen including sound; Highlight the movement of your mouse
$19.99
Bestseller No. 2
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
Mix an audio, music and voice tracks; Record single or multiple tracks simultaneously; Intuitive tools to split, trim, join, and many other editing features
Bestseller No. 4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
Transform audio playing via your speakers and headphones; Improve sound quality by adjusting it with effects

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.