     [Answers](https://scrapfly.io/blog)   /  [headless-browser](https://scrapfly.io/blog/tag/headless-browser)   /  [How to take screenshots in NodeJS?](https://scrapfly.io/blog/answers/how-to-take-screenshots-nodejs)   # How to take screenshots in NodeJS?

 by [Mazen Ramadan](https://scrapfly.io/blog/author/mazen) Aug 09, 2024 7 min read [\#headless-browser](https://scrapfly.io/blog/tag/headless-browser) [\#nodejs](https://scrapfly.io/blog/tag/nodejs) [\#playwright](https://scrapfly.io/blog/tag/playwright) [\#puppeteer](https://scrapfly.io/blog/tag/puppeteer) [\#screenshots](https://scrapfly.io/blog/tag/screenshots) 

 [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs "Share on LinkedIn")    

 

 

Puppeteer and Playwright are popular headless browser libraries for NodeJS, and one of their use cases is screenshot automation. In this guide, we'll explore using Playwright and Puppeteer to screenshot in NodeJS. We'll start by covering installation, core concepts, and common functionalities to customize website screenshots. Let's get started!



## Installation

To start, let's go over the installation process. [Puppeteer](https://www.npmjs.com/package/puppeteer) and NodeJS [Playwright](https://www.npmjs.com/package/playwright) can be installed using the below `npm` command:

shell```shell
npm install puppeteer playwright
```



Next, install Playwrights' web driver binaries using the below command:

shell```shell
npx install chromium # alternatively install `firefox` or `webkit`
```





## The Basics

To start, let's explore the basics. We can use the `screenshot` method to take Playwright and Puppeteer screenshots in NodeJS:

Puppeteer

Playwright

javascript```javascript
const puppeteer = require("puppeteer");

async function run() {
  // launch a new page
  const browser = await puppeteer.launch({
    headless: false
  });
  const page = await browser.newPage();

  // go to the target web page
  await page.goto("https://web-scraping.dev/products");

  // take page screenshot
  await page.screenshot({
    type: "png", // can also be "jpeg" or "webp" (recommended)
    path: "products.png", // save image data to a PNG file
  });

  browser.close();
}

run();
```





javascript```javascript
const { chromium } = require("playwright");

async function run() {
  // launch a new browser tab with empty context
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();

  // go to the target web page
  await page.goto("https://web-scraping.dev/products");

  // take page screenshot
  await page.screenshot({ path: "products.png" });

  await browser.close();
}

run();
```







In the above code, we start by launching a headless browser instance and navigating to the target page URL. Then, we take Playwright and Puppeteer screenshots using the same `screenshot` method.



### Waits and Timeouts

Utilizing browser timeouts is crucial to ensure the data to screenshot has fully loaded before we capture a screenshot. For this, we can utilize different waiting strategies before taking screenshots:

Puppeteer

Playwright

javascript```javascript
async function run() {
  // ...

  // go to the target web page
  await page.goto("https://web-scraping.dev/products", {
    // wait for specific load state
    waitUntil: "networkidle2", //wait for network state to be idle
    waitUntil: "domcontentloaded", // wait for DOM tree to load
    waitUntil: "load", // wait for all respurces to load, including CSS and images (default)
  });
  // ....
}
```





javascript```javascript
async function run() {
  // ...

  // go to the target web page
  await page.goto('https://web-scraping.dev/products', {
    // wait for specific load state
    waitUntil: 'networkidle', //wait for network state to be idle
    waitUntil: 'domcontentloaded', // wait for DOM tree to load
    waitUntil: 'load', // wait for all resources to load, including CSS and images (default)
  });
  // ...
}
```







Here, we use the `waitUntil` method to wait for a specific **load state** before proceeding with the rest of the program, which ensures images load correctly before taking Puppeteer and Playwright NodeJS screenshot.

Alternatively, we can **wait for a specific CSS or XPath selector to be present**:

Puppeteer

Playwright

javascript```javascript
  await page.waitForSelector("div.products", { timeout: 10000 }); // CSS
  await page.waitForSelector("xpath/" + "//div[@class='products']", {
    timeout: 10000,
  }); // XPath
```





javascript```javascript
  await page.waitForSelector('div.products', { timeout: 10000 }); // CSS
  await page.waitForSelector("//div[@class='products']", {
    timeout: 10000,
  }); // XPath
```







Finally, we can use **fixed wait conditions**:

Puppeteer

Playwright

javascript```javascript
  // wait for fixed timeout
  await new Promise((resolve) => setTimeout(resolve, 5000)); // 5 seconds
```





javascript```javascript
  // wait for fixed timeout
  await page.waitForTimeout(5000); // 5 seconds
```







Since **Puppeteer doesn't natively support waiting for fixed waiting methods**, we emulate it using promises. As for Playwright, we use the built-in `waitForTimeout` method to wait for a fixed timeout.

Note that **it's not recommended to use fixed waiting methods when capturing screenshots in Node.js**, as they often add unnecessary latency.



Scrapfly

#### Need a cloud browser for scraping?

Run headless browsers at scale with Scrapfly Cloud Browser — no infrastructure to manage.

[Try Free →](https://scrapfly.io/register)## Viewport

One key configuration to consider when taking NodeJS web page screenshots is the browser window viewport. It represents the **web browser resolution through width and height dimensions**:

Puppeteer

Playwright

javascript```javascript
const browser = await puppeteer.launch({
  headless: false,
  args: ["--window-size=1920,1080"],
});
const page = await browser.newPage();
await page.setViewport({
  width: 1920,
  height: 1080,
});
```





javascript```javascript
const browser = await chromium.launch({
  headless: false,
});
const context = await browser.newContext({
  viewport: { width: 1920, height: 1080 },
});
const page = await context.newPage();
```







Here, we set 1080p resolution using width and height values. Manipulating the viewport enables emulating different devices. For instance, Playwright provides a wide range of **device presets to emulate different web browsers and operating systems** for further customization while taking a NodeJS screenshot:

javascript```javascript
const { chromium, devices } = require('playwright');

  const browser = await chromium.launch({
    headless: false
  });
  const iphone13 = devices['iPhone 14 Pro Max'];
  const context = await browser.newContext({
    ...iphone13,
  });
  const page = await context .newPage();
```



Above, we emulate a mobile browser by selecting a device preset. Playwright will then automatically apply the selected device [UseAgent](https://scrapfly.io/blog/posts/user-agent-header-in-web-scraping/), viewport, and scale factor settings. For the full list of available device profiles, refer to the [official device registry](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json).



### Selection Targeting

When taking web page screenshots, it's often convenient to fit the image based on the requirements, and this is where selection targeting comes in handy!

#### Full Page

A common use case is taking full web page screenshots. Here's how to approach it in NodeJS:

Puppeteer

Playwright

javascript```javascript
const puppeteer = require("puppeteer");

async function scroll(page) {
  let prevHeight = -1;
  let maxScrolls = 100;
  let scrollCount = 0;

  while (scrollCount < maxScrolls) {
    // scroll to the bottom of the page
    await page.evaluate("window.scrollTo(0, document.body.scrollHeight)");
    // wait for new scroll to finish
    await new Promise((resolve) => setTimeout(resolve, 2000));
    // calculate new scroll height and compare
    let newHeight = await page.evaluate("document.body.scrollHeight");
    if (newHeight == prevHeight) {
      break;
    }
    prevHeight = newHeight;
    scrollCount += 1;
  }
}

async function run() {
  const browser = await puppeteer.launch({
    headless: false,
    args: ["--window-size=1920,1080"],
  });
  const page = await browser.newPage();
  await page.setViewport({
    width: 1920,
    height: 1080,
  });

  // go to the target web page
  await page.goto("https://web-scraping.dev/testimonials", {
    waitUntil: "load",
  });

  // scroll down to the end of the page
  await scroll(page);

  await page.screenshot({
    type: "png",
    path: "full-page-screenshot.png",
    fullPage: true,
    captureBeyondViewport: false, // prevent image flicking
  });

  browser.close();
}

run();
```





javascript```javascript
const { chromium } = require("playwright");

async function scroll(page) {
  let prevHeight = -1;
  let maxScrolls = 100;
  let scrollCount = 0;

  while (scrollCount < maxScrolls) {
    // scroll to the bottom of the page
    await page.evaluate("window.scrollTo(0, document.body.scrollHeight)");
    // wait for new scroll to finish
    await page.waitForTimeout(2000);
    // calculate new scroll height and compare
    let newHeight = await page.evaluate("document.body.scrollHeight");
    if (newHeight == prevHeight) {
      break;
    }
    prevHeight = newHeight;
    scrollCount += 1;
  }
}

async function run() {
  const browser = await chromium.launch({
    headless: false,
  });
  const context = await browser.newContext({});
  const page = await context.newPage();

  // go to the target web page
  await page.goto("https://web-scraping.dev/products", {
    waitUntil: "load",
  });

  // scroll down to the end of the page
  await scroll(page);

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

  await browser.close();
}

run();
```







Here, we take a Node.js full page screenshot on [web-scraping.dev/testimonials](https://web-scraping.dev/testimonials), which uses infinite scrolling to fetch more data. The headless browser starts by navigating to the target web page and scrolling till the page end. Then, we use the `fullpage option` to capture a webpage screen the whole browser viewport.



#### Selectors

For further NodeJS screenshot customization, we can capture screenshots of a particular HTML element on the HTML using their equivalent selectors:

Puppeteer

Playwright

javascript```javascript
async function run() {
  // launch a new browser tab
  const browser = await puppeteer.launch({
    headless: false,
    args: ["--window-size=1920,1080"],
  });
  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });

  // request the web page and wait for the target element to load
  await page.goto("https://web-scraping.dev/product/3");
  await page.waitForSelector("div.row.product-data")

  const element = await page.$('div.row.product-data');

  await element.screenshot({
    type: "png",
    path: "element-screenshot.png",
  });
```





javascript```javascript
async function run() {
  const browser = await chromium.launch({
    headless: false,
  });
  const context = await browser.newContext({
    viewport: { width: 1920, height: 1080 },
  });
  const page = await context.newPage();

  // request the web page and wait for the target element to load
  await page.goto("https://web-scraping.dev/product/3");
  await page.waitForSelector("div.row.product-data")

  // select the element and capture it
  const element = await page.$('div.row.product-data');
  await element.screenshot({
    path: "element-screenshot.png"
  })
  await browser.close();
}
```







Here, we take Playwright and Puppeteer to take a screenshot of a specific element on the web page through the following steps:

- Wait for the element to appear
- Select the element using its CSS selector
- Screenshot the selected element

For large-scale screenshot capture, a dedicated [Screenshot API](https://scrapfly.io/screenshot-api) handles the complexity. See which providers lead in our [screenshot API comparison](https://scrapfly.io/blog/posts/what-is-the-best-screenshot-api).



 

    Table of Contents- [Installation](#installation)
- [The Basics](#the-basics)
- [Waits and Timeouts](#waits-and-timeouts)
- [Viewport](#viewport)
- [Selection Targeting](#selection-targeting)
 
    Join the Newsletter  Get monthly web scraping insights 

 

  



Scale Your Web Scraping

Anti-bot bypass, browser rendering, and rotating proxies, all in one API. Start with 1,000 free credits.

  No credit card required  1,000 free API credits  Anti-bot bypass included 

 [Start Free](https://scrapfly.io/register) [View Docs](https://scrapfly.io/docs/onboarding) 

 Not ready? Get our newsletter instead. 

 

## Explore this Article with AI

 [ ChatGPT ](https://chat.openai.com/?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs) [ Gemini ](https://www.google.com/search?udm=50&aep=11&q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs) [ Grok ](https://x.com/i/grok?text=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs) [ Perplexity ](https://www.perplexity.ai/search/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs) [ Claude ](https://claude.ai/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fanswers%2Fhow-to-take-screenshots-nodejs) 



 ## Related Articles

 [  

 python headless-browser 

### How To Take Screenshots In Python?

Learn how to take Python screenshots through Selenium and Playwright, including common browser tips and tricks for custo...

 

 ](https://scrapfly.io/blog/posts/how-to-take-screenshots-in-python) [  

 http nodejs 

### Web Scraping With NodeJS and Javascript

In this article we'll take a look at scraping using Javascript through NodeJS. We'll cover common web scraping libraries...

 

 ](https://scrapfly.io/blog/posts/web-scraping-with-nodejs) [  

 nodejs headless-browser 

### How to Web Scrape with Puppeteer and NodeJS in 2026

Introduction to using Puppeteer in Nodejs for web scraping dynamic web pages and web apps. Tips and tricks, best practic...

 

 ](https://scrapfly.io/blog/posts/web-scraping-with-puppeteer-and-nodejs) 

  ## Related Questions

- [ Q How to take a screenshot with Puppeteer? ](https://scrapfly.io/blog/answers/how-to-take-screenshot-with-puppeteer)
- [ Q How to take a screenshot with Playwright? ](https://scrapfly.io/blog/answers/how-to-take-screenshot-with-playwright)
- [ Q How to take a screenshot with Selenium? ](https://scrapfly.io/blog/answers/how-to-take-screenshot-with-selenium)
- [ Q How to block resources in Puppeteer? ](https://scrapfly.io/blog/answers/how-to-block-resources-in-puppeteer)
 
  



   



 Run headless browsers at scale, **1,000 free credits** [Start Free](https://scrapfly.io/register)