Thankfully, this isn’t an impossible task and is, in fact, quite easy with the proper tools. Using the html-to-image library, making images of DOM nodes is as simple as a single function call.
How Does html-to-image Work?
The html-to-image library produces an image in the form of a base64 data URL. It supports several output formats, including PNG, JPG, and SVG. To perform this conversion, the library uses this algorithm:
Create a clone of the target HTML element, its children, and any attached pseudo-elements. Copy the styling for all cloned elements and embed the styling inline. Embed the relevant web fonts, if there are any. Embed any images present. Convert the cloned node into XML, and then SVG. Use the SVG to create a Data URL.
Caveats and Limitations
Even though html-to-image is a great library, it’s not perfect. It has a few caveats, namely:
The library will not work in Internet Explorer or Safari. If the HTML you try to convert includes a tainted canvas element, the library will fail. As MDN explains, including non-CORS-approved data in your canvas element will taint it. Because browsers place limits on the maximum size of a data URL, there are limits on the size of the HTML the library can convert.
Using the Library
To try the library out, the first thing you need to do is create a project directory on your local machine. Next, install html-to-image in that directory using the npm package manager. Here’s the terminal command to install it:
You should also install a JavaScript bundler, to make it a little easier to use the library. The esbuild bundler can help package node modules into web-compatible scripts.
That’s all you need to install. Next, create a file called index.html in your directory, and serve it with a web server of your choice. Put the following code in index.html:
This code creates two elements on the page: a div with a gradient background, and some text and an unordered list inside another div. Next, you’ll write the JavaScript to convert these elements to images. Put the following code in a new file called script.js:
This code does a few things:
Imports the html-to-image library. Creates an array made of CSS selectors targeting the two elements. Creates a PNG image in the form of a data URL from each element of the array. Creates an img tag and sets its src attribute to the data URL, creating image copies of the two elements.
Now use esbuild to generate the bundled file (out.js) that index.html references by running the following in your terminal:
At this point, here’s what index.html should look like in your browser:
Even though the copies look exactly the same as the originals, they are actually image elements. You can confirm this by opening your dev tools and inspecting them.
This library also works with JavaScript frameworks. The html-to-image documentation contains instructions on how to generate other image formats. It also includes an example showing how to use the library with React.
Taking Screenshots With JavaScript Is Easy
There’s no native JavaScript method for creating images from HTML elements, or taking screenshots of the DOM. However, with the help of libraries and services like html-to-image, it becomes an easy task.
There are other ways of achieving similar results, such as the wkhtmltoimage library. You can use this open-source tool to take screenshots of a complete web page.