Create PNG file from <div>

This post explains how to add a button to a Astro page which downloads a certain <div> element in PNG format.

Flo

The problem

In my post regarding logo design with HTML and CSS I wanted to add a download button directly into my .mdx file I publish via Astro. This button should create a PNG from a certain div element in the .mdx file.

If you want to see a working example, head over to my tutorial on how to create a logo with HTML and (Tailwind)CSS.

The solution

Using Perplexity AI, I got to a solution very quickly. The only problem was Tailwind v4. The new color scheme used does not work with the used library html2canvas.

Thus, I changed to html2canvas-pro which works flawlessly with Tailwind v4!

To work in Astro, you have to create a React component and use it in any .mdx file.

CaptureButton.jsx
"use client";
import html2canvas from "html2canvas-pro";
export default function CaptureButton({ targetId }) {
const handleCapture = async () => {
const element = document.getElementById(targetId);
if (!element) return;
const canvas = await html2canvas(element, {
backgroundColor: null,
scale: window.devicePixelRatio || 2,
});
const dataUrl = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.href = dataUrl;
link.download = `${targetId}.png`;
link.click();
};
return (
<button
type="button"
className="mt-4 px-4 py-2 bg-indigo-600 text-white rounded-full hover:bg-indigo-800 transition cursor-pointer flex items-center gap-2"
onClick={handleCapture}
aria-label="Download logo as PNG"
>
{/* Download Icon SVG */}
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-5 h-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
aria-hidden="true"
>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4v12m0 0l-4-4m4 4l4-4M4 20h16" />
</svg>
Download logo as PNG
</button>
);
}