How to Take Screenshots with Puppeteer

This article will show you examples of using Puppeteer to take simple screenshots, full-page screenshots, multiple screenshots and screenshots of a particular HTML element.
by Josephine Loo · · Updated

Contents

    Puppeteer is a popular Node library that is very useful for developers to run automated website tests. In this tutorial, we will be showing you examples of how to use Puppeteer save screenshots of web pages as JPG images. We can use Puppeteer to capture simple screenshots, full-page screenshots, multiple screenshots, and screenshots of a particular HTML element.

    Pre-requisites

    To use Puppeteer to take screenshots of web pages, you will need to have these installed:

    For reference, these are the versions used in this tutorial:

    • Node.js - 14.17.3
    • npm - 6.14.13

    Please check the official documentation to check your version compatibility.

    Getting Started

    Step 1. Create a New Node.js Project

    Create a new folder for your project and go to the directory.

    mkdir puppeteer-screenshot
    cd puppeteer-screenshot
    

    Init a new Node.js project in the folder.

    npm init
    

    It will prompt you for input for a few aspects of the project, just press enter if you want to use the default values.

    Once you run through the npm init steps above, a package.json file will be generated and placed in the current directory.

    screenshot of a Node.js project

    Step 2. Install Puppeteer

    Run the command below to install Puppeteer.

    npm i puppeteer
    

    A folder named node_modules and a file named package-lock.json will be added to your project after running the command.

    screenshot of a Node.js project after installing Puppeteer

    When you run the command above to install Puppeteer, a recent version of Chromium which is guaranteed to work with the Puppeteer API is also downloaded.

    screenshot of Chromium being downloaded

    Step 3. Create a New File

    In the same project, create index.js file. This is where we will be writing our code to capture screenshots with Puppeteer.

    screenshot of index.js file

    Step 4. Import Puppeteer

    Inside the index.js file, import puppeteer.

    const puppeteer = require('puppeteer');
    

    Now, we have all files and dependencies required. Let’s start coding!

    Note : We will be writing the code in a self-invoking function.

    How to Save Screenshot as JPG (Simple Screenshot)

    Step 1. Create a Browser Instance and a New Page

    First, create a Chrome browser instance in headless mode. As Puppeteer runs headless by default, we don’t have to state it in the parameter. Then, create a new page in the browser.

    // Create a browser instance
      const browser = await puppeteer.launch();
    
    // Create a new page
    const page = await browser.newPage();
    

    We can take the screenshot in different device views by setting the viewport size. For example, we can set the viewport to 1280x720 pixels to take a screenshot of the page in desktop view.

    // Set viewport width and height
    await page.setViewport({ width: 1280, height: 720 });
    

    Step 2. Navigate to a URL

    Next, set the URL of your target web page and call the page.goto() method with { waitUntil: 'networkidle0' } to open the URL in current page.

    const website_url = 'https://www.bannerbear.com/blog/how-to-convert-html-into-pdf-with-node-js-and-puppeteer/';
    
    // Open URL in current page  
    await page.goto(website_url, { waitUntil: 'networkidle0' });
    

    { waitUntil: 'networkidle0' } will ensure that there are no more than 0 network connections for at least 500ms before the navigation is considered to be finished.

    Step 3. Capture a Screenshot

    Next, call page.screenshot() along with the path option to capture a screenshot of the page.

    // Capture screenshot
    await page.screenshot({
      path: 'screenshot.jpg'
    });
    

    The path will set the file path to save the image to. The screenshot type (jpg/png) will be inferred from the file extension. Make sure to state the path as the image won’t be saved to the disk if no path is provided.

    We will be saving our screenshot in JPEG format in this tutorial as the speed of taking a screenshot in JPEG is faster compared to PNG.

    Beside saving your screenshot in JPEG format, there are other ways to speed up your Puppeteer screenshots too. You can read more about them in this article: 8 Tips for Faster Puppeteer Screenshots.

    Step 4. Close the Browser

    Finally, close the browser instance after the screenshot is completed.

    // Close the browser instance
    await browser.close();
    

    This is the complete code for the operation:

    const puppeteer = require('puppeteer');
    
    (async () => {
      // Create a browser instance
      const browser = await puppeteer.launch();
    
      // Create a new page
      const page = await browser.newPage();
    
      // Set viewport width and height
      await page.setViewport({ width: 1280, height: 720 });
    
      const website_url = 'https://www.bannerbear.com/blog/how-to-convert-html-into-pdf-with-node-js-and-puppeteer/';
    
      // Open URL in current page
      await page.goto(website_url, { waitUntil: 'networkidle0' });
    
      // Capture screenshot
      await page.screenshot({
        path: 'screenshot.jpg',
      });
    
      // Close the browser instance
      await browser.close();
    })();
    

    Execute the code by running node index.js in your command line and you should get a result similar to this:

    a single screenshot of a Bannerbear page captured by Puppeteer

    The code above takes a screenshot of the web page as how it is displayed on a browser window. It works fine for websites like the Google homepage which has nothing to scroll.

    a screenshot of Google homepage captured by Puppeteer

    For most web pages that are scrollable, it does not take a complete screenshot of your web page. If you want to take a full-page screenshot, you need to add an option for page.screenshot().

    How to Save Screenshot as JPG (Full-page Screenshot)

    To take a full-page screenshot, add fullPage: true to page.screenshot().

    await page.screenshot({
          path: 'screenshot_full.jpg',
          fullPage: true 
        })
      }
    

    This will take a full-page screenshot of the web page instead of capturing just a part of the web page that fits the viewport.

    full-page screenshot captured by Puppeteer

    There are also other options that you can set for your Puppeteer screenshot like clip, encoding, omitBackground, etc. For more details, you can refer to the Puppeteer official documentation.

    How to Save Screenshot as JPG (Multiple Screenshots)

    You can also capture multiple screenshots of different web pages by passing in the URLs as an array and saving them in a folder.

    In this example, we will be taking screenshots of these pages and saving them in a folder named /images:

    First, create a new /images folder in your project directory to save the screenshots.

    screenshot of new images folder

    We want to modify this part of the code to loop through the URLs in an array and capture full-page screenshots of them:

    const website_url = urlArray[i];
    
        // Open URL in current page
        await page.goto(website_url, { waitUntil: 'networkidle0' });
      
        // Capture screenshot
        await page.screenshot({
          path: 'screenshot_full.jpg',
          fullPage: true
    });
    

    Next, create an array to store the URLs of the web pages which you want to capture full-page screenshots.

    const urlArray = [
        'https://www.bannerbear.com/blog/how-to-convert-html-into-pdf-with-node-js-and-puppeteer/',
        'https://www.bannerbear.com/blog/how-to-download-images-from-a-website-using-puppeteer/',
        'https://www.bannerbear.com/blog/5-image-apis-you-can-use-for-your-next-project-in-2022/'
    ];
    

    Then, move the code into a for loop and change the naming format of the Puppeteer screenshots:

    for(var i = 0; i < urlArray.length; i++) {
    
        const website_url = urlArray[i];
    
        // Open URL in current page
        await page.goto(website_url, { waitUntil: 'networkidle0' });
      
        // Capture screenshot
        await page.screenshot({
          path: `images/screenshot_full_${i+1}.jpg`,
          fullPage: true
        });
    
    }
    

    The code will loop through every URL in the array, capture a full-page screenshot and save them as screenshot_full_1.jpg, screenshot_full_2.jpg, and screenshot_full_3.jpg in the /images folder.

    screenshot of Bannerbear page captured by Puppeteer

    How to Save Screenshot as JPG (a Particular HTML Element)

    Other than adding the fullpage option to capture a full-page screenshot, we can also capture only a particular HTML element in the webpage. For example, we can modify the previous code to capture only the post image using the CSS selector.

    You can copy the selector of the post image by right-clicking the image and selecting Inspect. Then, right-click the highlighted HTML code of the image and copy the selector.

    screenshot of getting selector of the HTML element

    This is the selector copied:

    #article_top > div > div.hero_image_container > div.

    Next, go to your index.js file and declare a variable for the selector before .screenshot() and get the element from the web page.

    const selector = '#article_top > div > div.hero_image_container > div';
    

    We can remove { waitUntil: 'networkidle0' } and ask the page to wait for the selector instead.

    await page.goto(website_url);
    await page.waitForSelector(selector);
    
    const element = await page.$(selector);
    

    Next, change page.screenshot() to element.screenshot() to capture the element. Remove fullPage: true or set it to false.

    // Capture screenshot
    await element.screenshot({
      path: `images/post_image_${i+1}.jpg`
    });
    

    The complete code looks like this:

    const puppeteer = require('puppeteer');
    
    const urlArray = [
      'https://www.bannerbear.com/blog/how-to-convert-html-into-pdf-with-node-js-and-puppeteer/',
      'https://www.bannerbear.com/blog/how-to-download-images-from-a-website-using-puppeteer/',
      'https://www.bannerbear.com/blog/5-image-apis-you-can-use-for-your-next-project-in-2022/'
    ];
    
    const selector = '#article_top > div > div.hero_image_container > div';
    
    (async () => {
      // Create a browser instance
      const browser = await puppeteer.launch();
    
      // Create a new page
      const page = await browser.newPage();
    
      // Set viewport width and height
      await page.setViewport({ width: 1280, height: 720 });
    
      for(var i = 0; i < urlArray.length; i++) {
    
        const website_url = urlArray[i];
    
        // Open URL in current page
        await page.goto(website_url);
        await page.waitForSelector(selector);
        
        const element = await page.$(selector);
    
        // Capture screenshot
        await element.screenshot({
          path: `images/post_image_${i+1}.jpg`,
        });
      }
    
      // Close the browser instance
      await browser.close();
    })();
    

    Run node index.js and you should have the post images saved to the /images folder.

    HTML element captured by Puppeteer

    🐻 Bear Tips: Use Bannerbear's free pretty screenshot tool to add a background to your screenshot!

    Using Bannerbear API

    If you want to apply an image template or add a watermark to your images, you can do it with Bannerbear Image Generation API. It is a simple REST API that offers easy integration into any existing platform or app to generate designed images automatically.

    This is an example generated automatically from one of the Puppeteer screenshots using Bannerbear API:

    an image auto-generated using Bannerbear

    If your Puppeteer screenshots are hosted on a server, you can apply an image template to all images automatically using Bannerbear.

    Before that, you need to create a Bannerbear project and a design template. You can design the template from scratch or choose a design from the template library.

    This Pitch Deck Template consists of a dynamic image object and some dynamic text objects which can be set when calling the API.

    You need to call the API with your project API key and the template ID.

    imgUrl.forEach((url, i) => {
    
      var data = {
        template: TEMPLATE_ID,
        modifications: [
        {
          "name": "title",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "rectangle",
          "color": null
        },
        {
          "name": "page_number",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "image_container",
          "image_url": url
        },
        {
          "name": "heading_1",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "paragraph_1",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "heading_2",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "paragraph_2",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "heading_3",
          "text": "You can change this text",
          "color": null,
          "background": null
        },
        {
          "name": "paragraph_3",
          "text": "You can change this text",
          "color": null,
          "background": null
        }
       ]
      };
    
      fetch('https://api.bannerbear.com/v2/images', {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${API_KEY}`,
        }
      });
      
    });
    

    It saves a lot of time when you have a lot of images that needs to be edited as the images can be generated automatically using Bannerbear by simply calling the API.

    If you’re interested to know more about how you can automate your process using Puppeteer or Bannerbear, here are some articles that might help you:

    About the authorJosephine Loo
    Josephine is an automation enthusiast. She loves automating stuff and helping people to increase productivity with automation.

    Bannerbear Beginner Guide: How to Start Generating Images Dynamically in JavaScript with Bannerbear

    If you want to integrate dynamic image generation into your JavaScript project, this article is for you! Learn how to do it effortlessly with Bannerbear—we’ll walk you through the entire process, from setup and implementation to achieving the final result.

    How to Automatically Create Eye-Catching Images for Your App's Link Sharing Using Bannerbear (Node.js)

    Want to make your app’s link sharing stand out? Learn how to use Bannerbear to automatically create eye-catching images that boost click-through rates! This tutorial walks you through building a backend service with Node.js to automatically generate custom images based on dynamic data.

    How to Auto-Generate Social Media Posts For a Business Conference Using Bannerbear (Node.js): Part 2

    In Part 2 of our series on auto-generating social media posts for a business conference using Bannerbear, we'll be creating posts for panel sessions. The image for each post will feature key details like the session topic, moderator, and panelists.

    Automate & Scale
    Your Marketing

    Bannerbear helps you auto-generate social media visuals, banners and more with our API and nocode integrations

    How to Take Screenshots with Puppeteer
    How to Take Screenshots with Puppeteer