Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
browser automation

How to Take Puppeteer Screenshots of Pages with Video

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

Use page.screenshot() when you need one rendered image and page.record() when you need the page’s activity saved over time. For a selected component, call elementHandle.screenshot(). A reliable workflow is to launch or connect to Chrome, navigate to the page, wait for the state you want, capture a still or start a recording, perform the interactions, stop the recorder, and only then close the browser.

This guide covers still images, full-page and clipped captures, video recording, timing issues, common failures, and an API alternative when maintaining a browser setup is unnecessary.

Choose between a screenshot and a recording

Need Puppeteer API Result Important detail
Preserve one visual state Page.screenshot() Image bytes or a file such as PNG, JPEG or WebP Wait until the exact visual state you want is rendered.
Capture one component ElementHandle.screenshot() An image of the selected element The element is scrolled into view; a detached element causes an error.
Preserve activity over time Page.record() Documented as an MP4 video stream Call stop() on the returned recording object before closing the browser.

A screenshot is a single rendered state, not a timeline. If a page contains a video, an animation or changing data, the screenshot shows only the frame visible when the method runs. Use recording when the motion itself matters. Puppeteer’s current reference describes Page.record() as using Chrome DevTools Protocol’s Page.startScreenRecording mechanism.

The older Page.screencast() API is marked obsolete in the documentation; new code should use Page.record() instead. The screencast page says, “Use Page.record() instead.”

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.

Prerequisites and a minimal project

Install Puppeteer in a Node.js project. The package normally downloads a compatible browser during installation; if your project uses a separately installed Chrome or Chromium, launch it with the appropriate executable path and check that the browser and Puppeteer versions support the APIs you call.

mkdir puppeteer-capture
cd puppeteer-capture
npm init -y
npm install puppeteer

Create a JavaScript file and run it with node filename.js. The examples below use modern async functions and write files in the current directory.

Take a normal page screenshot

The page-level method is the simplest answer to “How do I take a screenshot of a page with Puppeteer?” Navigate first, then capture.

const puppeteer = require('puppeteer');

(async () => {
  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' });
  } finally {
    await browser.close();
  }
})();

networkidle2 waits for a low level of network activity. It is useful for ordinary pages, but it does not prove that a video has buffered, that a canvas animation has reached a particular frame, or that a web app has finished all visual work. Add a selector wait, an explicit delay, or an application-specific readiness signal when those conditions matter.

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

Return image bytes instead of writing a file

const image = await page.screenshot({ type: 'png' });
// image is a Buffer; send it to storage, an HTTP response, or another process.

When path is supplied, Puppeteer writes the file. Without it, the method returns image data. Select the output format with type: 'png', type: 'jpeg', or type: 'webp' where supported by your installed release; JPEG and WebP options can include a quality value.

Capture an element, full page, or clipped region

Capture one element

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

The element screenshot method scrolls the target into view when necessary. If a framework replaces the node between waitForSelector and screenshot, the handle may be detached. Re-select the element immediately before capture, or use a stable locator strategy in your installed Puppeteer version.

Capture the whole document

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

Full-page capture is useful for long documents, but it can expose layout that appears only while scrolling and may interact oddly with sticky headers or virtualized lists. Confirm the exact behavior against the Puppeteer release installed in your project.

Capture a rectangle

await page.screenshot({
  path: 'hero.png',
  clip: { x: 0, y: 0, width: 1200, height: 700 }
});

The screenshot options reference also lists encoding, omitBackground, and captureBeyondViewport. That options page is published under a “next” reference, so verify option names and support in your installed version before making them part of a production interface. The API reference for Page.screenshot() is the authoritative place to check your release.

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

Make a page with video ready for a still image

If the requirement is a still image of a page that contains video, decide which frame you want and wait for that condition. A fixed delay is easy but fragile; a page-controlled event or selector is better.

await page.goto('https://example.com/video-demo', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('video');
await page.evaluate(() => new Promise(resolve => {
  const video = document.querySelector('video');
  if (!video) return resolve();
  if (video.readyState >= 2) return resolve();
  video.addEventListener('loadeddata', resolve, { once: true });
}));
// Optional: allow the desired frame to appear.
await new Promise(resolve => setTimeout(resolve, 1000));
await page.screenshot({ path: 'video-page.png' });

Autoplay policies can prevent playback, especially when audio is enabled. If your test owns the page, configure the page or browser context for the behavior you need and do not assume that a loaded video is playing. A screenshot cannot capture a video frame that has not been painted yet.

Record page activity as MP4 video

The documented recording flow is: navigate, start the recorder, perform actions or wait through the animation, stop the recorder, then close the browser.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle2' });

    const recorder = await page.record({ path: 'recording.mp4' });
    try {
      await page.click('button.start-demo');
      await page.waitForSelector('.demo-complete');
    } finally {
      await recorder.stop();
    }
  } finally {
    await browser.close();
  }
})();

The Page.record() reference states that it “Outputs mp4 video stream.” Always stop the returned object, including on an error path; closing the page first can leave an incomplete file. If the interaction has no completion selector, wait for a known duration and stop explicitly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const recorder = await page.record({ path: 'animation.mp4' });
await new Promise(resolve => setTimeout(resolve, 5000));
await recorder.stop();

Record an animation and take a still at the end

const recorder = await page.record({ path: 'interaction.mp4' });
await page.click('#play');
await page.waitForSelector('#finished');
await recorder.stop();
await page.screenshot({ path: 'final-state.png' });

Stopping before the final screenshot makes the two operations easier to reason about and avoids competing capture work. In concurrent workflows, page creation and page closure wait for screenshot completion, while bringing a page to the front does not wait for screenshots already in progress.

Control timing, loading, and visual state

Use the narrowest readiness condition

  • Navigation: choose domcontentloaded, load, or networkidle2 based on the page, not habit.
  • Selector: wait for the component that must appear, then verify its text, dimensions, or state.
  • Network: wait for a request or response your application owns when data drives the screenshot.
  • Animation: use a completion signal or a measured delay; network idle alone does not mean an animation is finished.

Stabilize output

  • Set a deterministic viewport with page.setViewportSize or the equivalent API in your installed release.
  • Disable transitions in a test-only stylesheet if you need pixel-stable comparisons.
  • Freeze dates, random values, and live data in the page you control.
  • Wait for fonts and images that affect layout before capturing.

Do not claim a universal capture speed or resolution limit: the documentation does not publish a general benchmark, and the result depends on the page, browser, machine, and chosen options.

Version and compatibility cautions

The surfaced documentation labels differ: the screenshot guide and Page overview show Puppeteer 25.12.0, while the Page.record() and ScreenRecording references show 25.11.0. The Page overview also marks record() experimental. Those labels can reflect different publication points rather than a complete compatibility matrix. If page.record is undefined or recording fails, check the Puppeteer version actually installed, the Chrome or Chromium binary it launches, and the current API reference for that pair. Do not assume that a method documented online exists in every older release.

Troubleshooting checklist

“page.record is not a function”

Your installed Puppeteer may predate the documented API, or a different package version is being loaded. Run npm list puppeteer, verify the import, update deliberately, and confirm the browser/Puppeteer combination. Do not silently switch to obsolete screencast() code without checking its documented limitations.

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

The MP4 is empty or truncated

Make sure await recorder.stop() runs before page.close() or browser.close(). Put it in a finally block, as in the example, and retain the process until the stop promise resolves.

The screenshot is blank

Capture after navigation and after the required selector or data response appears. Check that the target is not behind a consent dialog, hidden by CSS, or rendered in a different frame. For an iframe, obtain its frame and wait for content inside that frame before taking the screenshot.

An element screenshot throws a detached-node error

The page replaced the element after you selected it. Wait for the final state and select the element again immediately before calling screenshot().

The video never plays

Inspect autoplay and media policy, muted state, source errors, and whether the page requires a user gesture. Wait for a meaningful media event rather than assuming that networkidle2 means playback has started.

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.

Full-page output has missing lazy images

Some sites load images only after they approach the viewport. Scroll through the page or trigger the site’s own lazy-load mechanism, wait for image completion, and then capture. This behavior is page-specific.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF, and its clean-shot pipeline accepts cookie or consent banners before removing more than 60 known consent platforms, newsletter popups, and chat widgets. Each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and whether the request was billed.

For a direct capture, see the ScreenshotNeo API documentation:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in 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)

And 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}`);

ScreenshotNeo also includes an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its options cover full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper settings, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work.

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

Plans start with 1,000 screenshots per month free with no card. Paid plans are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to get the 1,000 monthly screenshots without a card.

Frequently Asked Questions

Can Puppeteer extract still frames from an existing video file?

The documented workflow covers screenshots of the rendered page and recording page activity. It does not document extracting frames from an existing video file, so use a video-processing tool for that separate task.

Does Page.record() require FFmpeg?

The FFmpeg requirement is documented for the obsolete Page.screencast() path. Do not transfer it to Page.record() without documentation for your specific version.

Should I close the browser immediately after starting a recording?

No. Keep the page alive while the interaction runs, await the returned recorder’s stop() method, and close the browser afterward.

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

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
Crashes, No Sound, or Screen Glitches?Free driver scan
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.