JavaScript library for taking screenshots of web pages or DOM elements directly in the browser
npx @tessl/cli install tessl/npm-html2canvas@1.4.0html2canvas is a JavaScript library that enables taking "screenshots" of web pages or specific DOM elements directly in the browser without requiring server-side rendering. The library reads the DOM structure and applied CSS styles to recreate the visual representation as a canvas element, providing a client-side solution for generating images from HTML content.
npm install html2canvasimport html2canvas from "html2canvas";For CommonJS:
const html2canvas = require("html2canvas");import html2canvas from "html2canvas";
// Take a screenshot of the entire body
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
// Take a screenshot of a specific element
const element = document.getElementById('myElement');
html2canvas(element).then(function(canvas) {
// Use the canvas (e.g., convert to image, save, etc.)
const imgData = canvas.toDataURL('image/png');
console.log(imgData);
});
// With options
html2canvas(document.body, {
width: 1920,
height: 1080,
scale: 1,
backgroundColor: '#ffffff',
useCORS: true,
allowTaint: false
}).then(function(canvas) {
document.body.appendChild(canvas);
});html2canvas is built around several key components:
html2canvas()The core functionality for capturing DOM elements as canvas images.
/**
* Renders the specified HTML element to a canvas
* @param element - The DOM element to render
* @param options - Configuration options for rendering
* @returns Promise that resolves to an HTMLCanvasElement containing the rendered image
*/
function html2canvas(
element: HTMLElement,
options?: Partial<Options>
): Promise<HTMLCanvasElement>;Comprehensive options interface for customizing the rendering behavior.
type Options = CloneOptions & WindowOptions & RenderOptions & ContextOptions & {
/** Background color override for the rendered canvas */
backgroundColor?: string | null;
/** Use SVG foreignObject rendering instead of canvas rendering */
foreignObjectRendering?: boolean;
/** Whether to remove the temporary iframe container after rendering (default: true) */
removeContainer?: boolean;
};Options for controlling DOM element cloning behavior.
interface CloneOptions {
/** Function to determine which elements should be ignored during cloning */
ignoreElements?: (element: Element) => boolean;
/** Callback executed after the document is cloned but before rendering */
onclone?: (document: Document, element: HTMLElement) => void;
/** Allow tainted images to be used in rendering */
allowTaint?: boolean;
}Options for controlling viewport and scrolling behavior.
interface WindowOptions {
/** Horizontal scroll offset (default: window.pageXOffset) */
scrollX?: number;
/** Vertical scroll offset (default: window.pageYOffset) */
scrollY?: number;
/** Window width for rendering (default: window.innerWidth) */
windowWidth?: number;
/** Window height for rendering (default: window.innerHeight) */
windowHeight?: number;
}Options for controlling canvas rendering output.
interface RenderOptions {
/** Device pixel ratio for high-DPI rendering (default: window.devicePixelRatio || 1) */
scale?: number;
/** Existing canvas element to render onto */
canvas?: HTMLCanvasElement;
/** X coordinate offset for rendering (default: 0) */
x?: number;
/** Y coordinate offset for rendering (default: 0) */
y?: number;
/** Width of the rendered output (default: calculated from element) */
width?: number;
/** Height of the rendered output (default: calculated from element) */
height?: number;
}Options for controlling execution context and caching.
type ContextOptions = {
/** Enable debug logging (default: true) */
logging?: boolean;
/** Custom cache instance for resources */
cache?: Cache;
} & ResourceOptions;
interface ResourceOptions {
/** Timeout for loading images in milliseconds (default: 15000) */
imageTimeout?: number;
/** Use CORS for cross-origin images (default: false) */
useCORS?: boolean;
/** Allow tainted canvas for cross-origin content (default: false) */
allowTaint?: boolean;
/** Proxy URL for loading cross-origin resources */
proxy?: string;
}
interface Cache {
/** Add an image to the cache for reuse */
addImage(src: string): Promise<void>;
/** Get a cached resource by source URL */
match(src: string): Promise<any>;
/** Check if a resource exists in the cache */
has(src: string): boolean;
}// Capture at 2x resolution for high-DPI displays
html2canvas(element, {
scale: 2,
width: element.offsetWidth * 2,
height: element.offsetHeight * 2
}).then(canvas => {
// Canvas will be 2x the size with crisp rendering
const ctx = canvas.getContext('2d');
ctx.scale(0.5, 0.5); // Scale down for display if needed
});// Handle cross-origin images with CORS
html2canvas(element, {
useCORS: true,
allowTaint: false
}).then(canvas => {
// Canvas will include cross-origin images that support CORS
});
// Alternative: Use proxy for cross-origin content
html2canvas(element, {
proxy: 'https://your-proxy-server.com/proxy',
allowTaint: false
}).then(canvas => {
// Proxy server will fetch cross-origin resources
});// Ignore specific elements during rendering
html2canvas(document.body, {
ignoreElements: (element) => {
// Skip elements with data-html2canvas-ignore attribute
return element.hasAttribute('data-html2canvas-ignore') ||
element.classList.contains('no-screenshot');
}
}).then(canvas => {
// Filtered elements won't appear in the screenshot
});// Modify the cloned document before rendering
html2canvas(element, {
onclone: (clonedDoc, clonedElement) => {
// Remove sensitive information from clone
const sensitiveElements = clonedDoc.querySelectorAll('.sensitive-data');
sensitiveElements.forEach(el => el.textContent = '[REDACTED]');
// Modify styles for better screenshot appearance
clonedElement.style.transform = 'none';
clonedElement.style.position = 'static';
}
}).then(canvas => {
// Screenshot will reflect the modifications made to the clone
});html2canvas(element).then(canvas => {
// Convert to PNG data URL
const pngDataUrl = canvas.toDataURL('image/png');
// Convert to JPEG with quality setting
const jpegDataUrl = canvas.toDataURL('image/jpeg', 0.8);
// Convert to Blob for file operations
canvas.toBlob(blob => {
// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'screenshot.png';
a.click();
URL.revokeObjectURL(url);
}, 'image/png');
});html2canvas operations can fail for various reasons. Always handle Promise rejections:
html2canvas(element, options)
.then(canvas => {
// Success - use the canvas
console.log('Screenshot captured successfully');
})
.catch(error => {
// Handle errors
console.error('Screenshot failed:', error);
// Common error scenarios:
// - Element not attached to document
// - Security restrictions on cross-origin content
// - Invalid options or element
// - Browser compatibility issues
});