DEV Community

Cover image for Generate images from HTML in Node.js
🦁 Yvonnick FRIN
🦁 Yvonnick FRIN

Posted on β€’ Originally published at yvonnickfrin.dev

70 16

Generate images from HTML in Node.js

As developers, we don't have great skills with image manipulation softwares, but we still need it. In my case I had to generate Twitter cards for social media and flyers for the meetup I co-organize. An important point for use is automation. So I wanted a solution that let me make a template and generates a lot of images without extra work.

That is why I created node-html-to-image. A Node.js module that generates images from HTML.

Here is the simplest example, you provide an output path and a HTML string. That's all!



const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  html: '<html><body>Hello world!</body></html>'
})
  .then(() => console.log('The image was created successfully!'))


Enter fullscreen mode Exit fullscreen mode

I talked about automation earlier. It comes with a templating engine, Handlebars. It enables creating multiple images using the same template.

In the following example, we changed world by a placeholder and inject its value with the content option.



const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  html: '<html><body>Hello {{name}}!</body></html>',
  content: { name: 'you' }
})
  .then(() => console.log('The image was created successfully!'))


Enter fullscreen mode Exit fullscreen mode

You want to generate images from HTML without writing a line of code? No problem, I also made a cli that use node-html-to-image underneath called node-html-to-image-cli.



npx node-html-to-image-cli index.html image.png


Enter fullscreen mode Exit fullscreen mode

Generated image:

Demonstration of node-html-to-image-cli

Feel free check out the GitHub repositories if you are interested:

Want to support ? Don't forget to leave a ⭐️


Feedback or ideas are appreciated πŸ™ Please tweet me if you have questions @YvonnickFrin!

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (19)

 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’ β€’ Edited

Percentage are relative to your parent dimensions So it will be 20 percent of body. If you don't fix body size it will be relative to the browser's viewport I guess. I don't set any viewport. So I recommend fixing body size to the resolution you want for the output file.

In the example below I fix the size to A4 format in high resolution. The output file resolution will be 2480x3508. So the card size will be 20% of 2480px. You see what I mean?

<html>
  <head>
    <style>
       body {
         width: 2480px;
         height: 3508px;
       }
       .card{
         width: 20%; /** if it's % then the image's width doesn't display properly **/
         box-shadow: 1px 3px 15px lightgray;
         height: 250px;
        }
    </style>
  </head>
  <body>
    <div class="card">
       [ ... ] (lots of subdivs)
    </div>
  </body>
</html>
Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

Thank you DesirΓ©!

Basically the module takes a screenshot of the body tag's content. So you need to fix the size of you image on this tag using CSS then you can use percent on body's children.

Maybe I should add this in the documentation?

Collapse
 
inatnat profile image
Nathaniel-kw Cheung β€’

Super cool stuff

Is there any way to use custom font? I got a HTML like this but the output image is not using the font specified (it's good to show in browser)



<br>
body {<br>
width: 1000px;<br>
height: 500px;<br>
}</p>
<div class="highlight"><pre class="highlight plaintext"><code> @font-face {
font-family: JuneBug;
src: url('JUNEBUG.TTF');
}
h1 {
    font-family: JuneBug
}

&lt;/style&gt;
</code></pre></div>
<p></head></p>

<p><body>Hello world!<br>
<h1>Hey, June</h1><br>
</body></p>

<p></html></p>

Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

Hi Nathaniel,

TTF format is made for Safari, Android and iOS. The image is generated in a chromium browser. So you can only use WOFF format.

Collapse
 
wlun001 profile image
Wei Lun β€’ β€’ Edited

This won't work on Docker, need to install anything other that npm install?

Collapse
 
quedicesebas profile image
SebastiΓ‘n Rojas Ricaurte β€’

You have to follow this for Docker github.com/puppeteer/puppeteer/blo... (tehere is specifict instructiosn for alpine also) and send this in puppeteerArgs when you call nodeHtmlToImage:

puppeteerArgs: {
headless: true,
args: [
"--no-sandbox",
"--remote-debugging-address=0.0.0.0",
"--remote-debugging-port=9222",
],
}

Collapse
 
quedicesebas profile image
SebastiΓ‘n Rojas Ricaurte β€’

ΒΏAnyone?

Collapse
 
dschep profile image
Daniel Schep β€’

Is it possible to generate a GIF from animated HTML?

Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

node-html-to-images don't handle this use case. It is an awesome idea!

Collapse
 
daniel13rady profile image
Daniel Brady β€’

Nice work. πŸ‘

Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

Thank you Daniel ❀️

Collapse
 
napoleon039 profile image
Nihar Raote β€’

Looks so cool! It's interesting that I can use HTML and CSS to generate an image.

Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

Thank you Nihar! Sure, as a developper I'm used to HTML and CSS which are great tools to make nice graphical stuff πŸ™Œ

 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

DΓ©sirΓ© I added a section about this in the documentation. What do you think of it?

Collapse
 
peacefullatom profile image
Yuriy Markov β€’

Awesomeness! πŸ‘

Collapse
 
yvonnickfrin profile image
🦁 Yvonnick FRIN β€’

Glad you like it β™₯️

Collapse
 
kaushan profile image
Kaushan β€’

That’s really great ! I used to make it via screenshot inside headless browsers. This solution is much more elegant

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay