How to create a site thumbnail with Puppeteer

Published on Dmytro Krasun 3 min read
We can consider the screenshot of URL or HTML as a thumbnail, but I write about the thumbnail of a screenshot. How do you take a screenshot within the defined viewport but with different image width and height? Resize!

Puppeteer only supports setting viewport width and height. And you can’t generate a small image (preview) of the site within a viewport of 1028x1024 pixels. But there is always a workaround! So, let’s play with the sharp library and resize the screenshot after taking it.

Resizing a website screenshot with sharp and Puppeteer

Please, install the sharp library first:

npm i sharp

And then let’s take a screenshot and resize it:

const puppeteer = require('puppeteer');
const sharp = require('sharp');
(async () => {
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.goto('https://screenshotone.com/');
await page.setViewport({ width: 1280, height: 1024 });
const binaryScreenshot = await await page.screenshot({ type: 'png', encoding: 'binary' });
await sharp(binaryScreenshot).
resize(700, 200, { fit: sharp.fit.inside }).
toFile('screenshotone.com_1280x1024px_in_700x200px.png');
} catch (e) {
console.log(e)
} finally {
await browser.close();
}
})();

The result is:

A resized screenshot of the ScreenshotOne.com site

I specified both the width and the height of the image and the sharp library, but since the screenshot doesn’t fit perfectly, I must set the fit parameter as inside. Why does it matter, and what other options can you use?

First, you can specify only the width, and then you don’t need to use fit. Height will be computed automatically and vice versa.

But when both a width and height are provided, the possible methods by which the image should fit these are: cover, contain, fill, inside, outside.

Use cover fit (default) to preserve the aspect ratio, and ensure the image covers both provided dimensions by cropping/clipping to fit. An example of cover fit:

A resized screenshot of the ScreenshotOne.com site

Use contain fit to preserve the aspect ratio, and contain within both provided dimensions using “letterboxing” where necessary. An example of contain fit:

A resized screenshot of the ScreenshotOne.com site

Use fill fit to ignore the input aspect ratio and stretch to both provided dimensions. An example of fill fit:

A resized screenshot of the ScreenshotOne.com site

Use inside fit to preserve the aspect ratio, and resize the image to be as large as possible while ensuring its dimensions are less than or equal to those specified. An example of inside fit:

A resized screenshot of the ScreenshotOne.com site

Use outside to preserve the aspect ratio, and resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified. An example of outside fit:

A resized screenshot of the ScreenshotOne.com site

Cloudflare Image Resizing

Another beautiful way to generate screenshots or render HTML in a different format is to use Cloudflare as a proxy that converts images on the go and can transform and resize them.

Cloudflare Image Resizing allows using Cloudflare’s edge platform to convert images to WebP or AVIF format on the fly, independently of where they are stored.

API as a service

Suppose you don’t want to ding with Puppeteer, write code, test it and make sure it is scalable. In that case, you can use a well-established solution — ScreenshotOne.com API that already supports different formats, resizing, and many more — get started for free.

To render screenshots of URL or HTML in a specific format. You will only need to specify two options, URL or HTML, and desired image width and height. Can it be more straightforward than:

https://api.screenshotone.com/take?image_width=100&url=https://apple.com&access_key=<your access key>

Summary

If you have time and have already installed Puppeteer, you can easily use the sharp library for image resizing. But if you don’t want to deal with Puppeteer, you can use ScreenshotOne.com API to save time.

Have a nice day 👋 and you also might find helpful: