Handling large images in puppeteer

contents

Puppeteer has the ability to take screenshots of a website, but it comes with some limitations. If your site's height or width exceeds ~16,000 pixels then you're likely to notice some blank spots. While this might leave you scratching your head, the solution is pretty easy.

At the time of this writing (puppeteer@1.1.0), puppeteer has had issues with rendering large webpages during screenshots. To get around this you'll need to take "chunks" of screenshots from your site and recombine them later. Below is a simple example where we split a website into two screenshots and re-merge later using the merge-img package on npm

Snapshot and combine


const puppeteer = require('puppeteer');
const merge = require('merge-img');

const pageUrl = ''; // REPLACE ME
const pageElement = '#svgcanvas'; // REPLACE ME
const saveImageLocation = 'temp.png'; // REPLACE ME

(async() => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(pageUrl);
  const $ele = await page.$(pageElement);
  const { width, height } = await $ele.boundingBox();
  
  // Split into two and re-merge downstream
  return Promise.all([
    page.screenshot({
      clip: {
        x: 0,
        y: 0,
        height,
        width: Math.floor(width / 2),
      },
    }),
    page.screenshot({
      clip: {
        x: Math.floor(width / 2),
        y: 0,
        height,
        width: Math.floor(width / 2),
      },
    })
  ])
  .then(merge)
  .then((final) => final.write(saveImageLocation, browser.close))
  .catch((error) => {
    console.error(error);
    browser.close();
  });
})()

You'll simply have to insert your own values for pageUrl and pageElement in order for this to work on your site. If your site happens to be over 3,200px in any direction then you'll have to get a little fancier and separate/combine more segments.

I hope this helps you with your journey in puppeteer!

Share this article

Ready to try the benefits of Browserless?