html2canvas-pro
html2canvas-pro is an actively maintained fork of the popular `niklasvh/html2canvas` library, designed to capture screenshots of web pages or specific DOM elements using JavaScript. It is currently at version 2.0.2 and appears to have a consistent release cadence with several recent patch releases following a major version bump to 2.0.0. Key differentiators include enhanced support for modern CSS color functions like `color()`, `lab()`, `lch()`, `oklab()`, and `oklch()`, improved handling of `object-fit` for images, and explicit control over image smoothing via the `image-rendering` CSS property or a global option. This package aims to address various issues and provide advanced features beyond the original `html2canvas` project, making it suitable for complex screenshot requirements where standard `html2canvas` might fall short. It ships with TypeScript types for improved developer experience.
Common errors
-
Tainted canvases may not be exported.
cause An attempt was made to export a canvas that contains content loaded from a different origin (e.g., an image without proper CORS headers or a cross-origin iframe).fixEnsure all images and resources within the captured element are served from the same domain or configured with CORS headers. Set `useCORS: true` in the `html2canvas` options if resources have valid CORS headers. Consider using a proxy to fetch cross-origin images if direct CORS is not possible. -
ReferenceError: html2canvas is not defined
cause The `html2canvas` function was called before the library was properly loaded or imported, or it was imported incorrectly (e.g., using named import for a default export).fixVerify that `import html2canvas from 'html2canvas-pro';` is at the top of your module. If using CommonJS, ensure `const html2canvas = require('html2canvas-pro');` is used. In a browser environment without a bundler, confirm the script tag for `html2canvas-pro` is correctly included and loaded before the function is called. -
TypeError: Cannot read properties of undefined (reading 'appendChild')
cause The target element passed to `html2canvas` (e.g., `document.body`) or the element to which the canvas is appended is `null` or `undefined`, often because the script runs before the DOM is fully loaded.fixWrap your `html2canvas` call in a DOMContentLoaded listener or ensure it runs after the target element is guaranteed to exist in the DOM. For example: `document.addEventListener('DOMContentLoaded', () => { html2canvas(document.body).then(...) });`
Warnings
- gotcha By default, the output canvas dimensions are affected by the browser's `devicePixelRatio`. This can lead to larger canvas sizes than expected based on element dimensions.
- gotcha Capturing content from different origins (e.g., images, iframes hosted on another domain) will 'taint' the canvas, preventing its content from being read or exported due to browser security restrictions (CORS).
Install
-
npm install html2canvas-pro -
yarn add html2canvas-pro -
pnpm add html2canvas-pro
Imports
- html2canvas
import { html2canvas } from 'html2canvas-pro'; const html2canvas = require('html2canvas-pro');import html2canvas from 'html2canvas-pro';
- Options
import type { Options } from 'html2canvas-pro'; - Canvas
import type { Canvas } from 'html2canvas-pro';
Quickstart
import html2canvas from 'html2canvas-pro';
// Capture the entire document body and append it to the DOM
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
console.log('Screenshot of document body appended.');
// Get the screenshot as a Data URL
const dataURL = canvas.toDataURL('image/png');
console.log('Partial Data URL:', dataURL.substring(0, 50) + '...');
});
// Example: Capture a specific element with controlled dimensions and scale
const elementToCapture = document.createElement('div');
elementToCapture.id = 'target-element';
elementToCapture.style.cssText = 'width: 300px; height: 150px; background-color: #e0f7fa; border: 2px solid #00bcd4; margin-top: 20px; display: flex; align-items: center; justify-content: center; font-family: sans-serif;';
elementToCapture.textContent = 'Capture me!';
document.body.appendChild(elementToCapture);
html2canvas(elementToCapture, {
width: 600, // Target output width
height: 300, // Target output height
scale: 1, // Important: set scale to 1 for exact pixel dimensions, ignoring devicePixelRatio
backgroundColor: null // Set to null for a transparent background if the source has none
}).then(scaledCanvas => {
const scaledDataURL = scaledCanvas.toDataURL('image/jpeg', 0.8); // Get as JPEG with 80% quality
console.log('Scaled screenshot data URL length:', scaledDataURL.length);
// Optionally append the scaled canvas as well
document.body.appendChild(scaledCanvas);
scaledCanvas.style.marginTop = '20px';
});