If you don’t have time to read, proceed to the “fix most issues at once” section.
The problem is so painful and common that one of the most common questions you see in Google search results is “Puppeteer full page screenshot not working”. While it is not grammatically correct, it is valid literally.
Let’s list some issues you may encounter when taking a full-page screenshot with Puppeteer, Playwright, or Selenium:
- triggering and waiting for lazy load images and other lazy load resources;
- animations that are appeared and are played only at the time you scroll a page;
- impossible to take the entire page screenshot of very long sites.
Let’s address them one-by-one by building a sophisticated solution that solves them all at once.
The pitfalls of taking full-page screenshots in Playwright, Selenium, or Puppeteer are the same. But I will use Puppeteer as the most popular library to demonstrate how to solve them.
Wait for lazy load images
Let’s take a full-page screenshot of the Apple site:
The site has lazy load images. It means they are not loaded until they are shown in the viewport—you need to scroll and view them to trigger loading. And Puppeteer, Playwright, or Selenium, by design, don’t support triggering the image load when taking a full-page screenshot.
Look at the result of the default behavior:
But it is relatively easy to fix by scrolling the page to the bottom and then taking a screenshot. Let’s do it and see what happens:
You can check out the result, and it looks promising:
It works. But it is not the only pitfall you will encounter while taking full-page screenshots.
For example, you might encounter an infinite scroll issue, and how to solve it depends on your needs. Limiting the number of “scrolls” you perform is the easiest way. Or you might use a bit tricky but straightforward logic to detect infinite scroll. If you reach the bottom of the site and the site height suddenly increases, there is probably an endless scroll.
Animations are played only on the page scroll
The approach we applied for lazy load images won’t work for sites with complex animations:
But the expected result is:
How can we achieve it? One of the easiest ways is to take site screenshots by sections and then merge all sections. It is pretty easy to do.
We need to install libraries to help us merging images:
And then, we are going to scroll the site until the bottom, take a screenshot of each section and then merge them:
Let’s test it:
And it works fine.
I set captureBeyondViewport
to false
to ensure that only the elements shown in the viewport are rendered. Otherwise, some elements might be stretched beyond the viewport and break screenshotting.
Taking the entire page screenshot of very long sites
Puppeteer or Playwright might stop taking full-page screenshots when the site is very long. In that case, the same idea used for the animation issue of taking screenshots by sections and merging them can help to handle the problem.
Fixing the most issues at once
Taking screenshots by sections is the best solution we might have today for taking the complete page screenshots:
Let’s test the code for a different site that we haven’t checked before and ensure it works. There is a screenshot for Stripe:
Yes, it works. But from time to time, you may still encounter different issues. Each site is different, and they might add custom code that might break scrolling or other tricks that will break your logic. So, you need to constantly update the code and ensure it works and supports more and more sites.
Home exercise
Want to improve the algorithm and practice full page screenshot taking? Try to take a screenshot of the Tesla website:
The problem is that you scroll the site’s background, and there is no full page. Try to do it by yourself.
Alternatives
So, what alternative is to render full-page screenshots when Puppeteer, Playwright, or Selenium can’t render them suitable?
Easy peasy. You can use a screenshot API as a service. Many good screenshot APIs might already solve your problem. As a maker of the such screenshot as a service API, I will show you how easy it is to use and the benefits you will receive as a bonus.
Sign up to get an access key and then take a screenshot as easy as sending an HTTP request:
As you see the lazy load images are handled correctly:
Let’s test the problem with rendering animations by scrolling in and out of them:
It works:
So, why waste time fixing all the problems with Puppeteer and not just using a simple API, especially when you can start for free?
Summary
In case you have time and energy to invest and to build screenshotting or HTML rendering infrastructure. I would go with Puppeetter or Playwright for full-page screenshots. Otherwise, you can save time and money by starting free with a screenshot API.
Additional resources
Have a nice day 👋 and you also might find helpful 👉 the complete guide on how to take a screenshot with Puppeteer