Convert html to image in react, nextjs, remix, vue

How to Convert & Download HTML or div's Content as Image in any JavaScript Framework

983Reads
28 March, 2023

In this Miniblog, i am gonna demonstrate a simple easy to implement solution to convert html, div into image and download them in React, Nextjs, Remix, Vue, Vanila Javaacript or any JavaScript Framework. This can be helpful in features like creating image from div, taking snapshot of a react component, generating business card from div etc..

Let's start

First of all, you will need to install the "html2canvas" npm package, using the "npm install --save html2canvas" command if you are using npm, or using yarn or pnpm accordingly.

Then we need to import it and create a reference variable for the div or any element of which we want to take screenshot of. Then just copy paste 2 functions "exportAsImage" and "downloadImage()" down in below code snippet to get the download functionality. That's it.

import React, { useRef, useState } from "react";
import html2canvas from "html2canvas";

const DivToImage = () => {
  const exportDivImageRef: any = useRef();
  const [downloading, setDownloading] = useState<boolean>(false);

  const exportAsImage = async (element, imageFileName) => {
    setDownloading(true);
    try {
      const html: any = document.getElementsByTagName("html")[0];
      const body: any = document.getElementsByTagName("body")[0];
      let htmlWidth = html.clientWidth;
      let bodyWidth = body.clientWidth;
      const newWidth = element.scrollWidth - element.clientWidth;
      if (newWidth > element.clientWidth) {
        htmlWidth += newWidth;
        bodyWidth += newWidth;
      }
      html.style.width = htmlWidth + "px";
      body.style.width = bodyWidth + "px";
      const canvas = await html2canvas(element, {
        allowTaint: true,
        useCORS: true,
      });
      const image = canvas.toDataURL("image/png", 1.0);
      downloadImage(image, imageFileName);
      html.style.width = null;
      body.style.width = null;
    } catch (error) {
      setDownloading(false);
    }
  };

  const downloadImage = (blob, fileName) => {
    try {
      const fakeLink: any = window.document.createElement("a");
      fakeLink.style = "display:none;";
      fakeLink.download = fileName;

      fakeLink.href = blob;

      document.body.appendChild(fakeLink);
      fakeLink.click();
      document.body.removeChild(fakeLink);

      fakeLink.remove();
      setDownloading(false);
      setDownloading(false);
    } catch (error) {
      setDownloading(false);
    }
  };

  return (
    <>
      <div ref={exportRef}>
        <h4>Hello world on Image!</h4>
      </div>
      <button onClick={downloadImage}>Download Card Image</button>
    </>
  );
};

Now you can use "downloadImage()" function and call it on any button click, and the image will get downloaded.

Hope this helps. Let me know in reactions, if you encounter any issue, will be happy to help. See you in the next Dot.