How to render HTML with Puppeteer

Updated on Dmytro Krasun 3 min read
Suppose you want a reliable way to render HTML with the latest versions of browsers.In that case, I bet you can't find a better solution than rendering HTML with Puppeteer — you always have an up-to-date version of the browser, and using Puppeteer is super easy.

Use cases for rendering HTML

There are many use cases when rendering HTML is proper:

  • generate bills, receipts, or invoices PDF or PNG files from the HTML templates;
  • dynamically create images for the Open Graph protocol;
  • generate marketing images at scale from templates;
  • create images for essays and writings to share on social networks;
  • make images for ads from the HTML templates;
  • and many more.

And it is super easy to do with Puppeteer.

Render HTML with Puppeteer

Puppeteer has a method page.setContent(html, options) to render HTML, it is easy and convenient to use. But don’t forget to install the Puppeteer library:

Terminal window
npm i puppeteer

And then, try it:

const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({});
try {
const page = await browser.newPage();
await page.setContent('<h1>Hello, world!</h1>');
await page.screenshot({ path: 'hello_world.png'});
} catch (e) {
console.error(e);
} finally {
await browser.close();
}
})();

The result is predictable:

Hello, world!

In case if your HTML contains links to externals resources like styles, scripts, fonts, or other kind of external resources, you can specify timeout and wain until “event”:

const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({});
try {
const page = await browser.newPage();
await page.setContent('...', {
timeout: 30000,
waitUntil: 'load' // or one of 'domcontentloaded' | 'networkidle0' | 'networkidle2'
});
await page.screenshot({ path: 'hello_world.png' });
} catch (e) {
console.error(e);
} finally {
await browser.close();
}
})();

Always specify a timeout to make sure that the request does not hang. And you can specify the waitUntil option:

  • load — consider navigation to be finished when the load event is fired;
  • domcontentloaded — consider navigation to be finished when the DOMContentLoaded event is fired.
  • networkidle0 — think navigation to be finished when there are no more than 0 network connections for at least 500 ms.
  • networkidle2 — think navigation to be finished when there are no more than 2 network connections for at least 500 ms.

The difference between networkidle0 and networkidle2 in its essence is:

  • networkidle0 comes in handy for SPAs that load resources with fetch requests;
  • networkidle2 comes in handy for pages that do long-polling or any other side activity.

Using html2canvas library

In case you need to render HTML or to take screenshots right at the client-side, in the browser, there is a magic library html2canvas. The library traverses the given HTML and renders in the canvas.

It is very easy to use. Install it:

Terminal window
npm install html2canvas

And then use:

import html2canvas from 'html2canvas';
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});

The beauty of the library is that you can take a screenshot of the page or render HTML to canvas and then images right in the browser. The downside is that library output might differ from the actual output. And it might miss the latest CSS features. So, you use it at your own risk. But for simple HTML, it should be enough.

Using API to render HTML

Using API is better when you have large volumes to take screenshots. In this case, you don’t need to be afraid that you can handle them and tweak Puppeteer. Or you want to make sure that you always render with the latest version of the browser.

If you don’t want to set up and manage Puppeteer, you can use our scalable and reliable API to render PDF or images from HTML. It supports native libraries to take screenshots for many languages

And now look how simple it is to render HTML:

GET https://api.screenshotone.com/take?html=<h1>Hello,%20world!</h1>&access_key=<your access key>

The result is the same as using Puppeteer:

Hello, world!

I hope I helped you and have a nice day 👋

You also might find helpful: