{"id":13303,"library":"html-to-image","title":"HTML to Image Generation Library","description":"html-to-image is a robust JavaScript library designed to convert a given HTML DOM node into various image formats, including PNG, JPEG, SVG, or directly onto an HTML5 canvas element. It serves as an actively maintained and enhanced fork of the earlier `dom-to-image` project, focusing on more maintainable code and improved feature support. The library is currently stable at version 1.11.13, with recent releases indicating a consistent cadence of bug fixes and minor improvements, though major version increments are less frequent. Its key differentiators include comprehensive handling of complex CSS (e.g., `-webkit-mask` support as of v1.11.13), flexibility in output types (data URLs, blobs, or canvas elements), and an emphasis on addressing common pitfalls like iframe cloning and image processing. It is primarily used in browser environments to programmatically capture visual representations of web content for download, display, or further processing.","status":"active","version":"1.11.13","language":"javascript","source_language":"en","source_url":"https://github.com/bubkoo/html-to-image","tags":["javascript","screenshot","capture","canvas","html","dom","image","vector","svg","typescript"],"install":[{"cmd":"npm install html-to-image","lang":"bash","label":"npm"},{"cmd":"yarn add html-to-image","lang":"bash","label":"yarn"},{"cmd":"pnpm add html-to-image","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library exports its functions as named exports and provides a namespace object. Importing it as a default export (`import htmlToImage from 'html-to-image';`) will result in `undefined`.","wrong":"import htmlToImage from 'html-to-image';","symbol":"htmlToImage","correct":"import * as htmlToImage from 'html-to-image';"},{"note":"Individual functions like `toPng`, `toJpeg`, `toBlob`, `toCanvas`, `toPixelData`, and `toSvg` are directly available as named exports for ES Module environments. While CommonJS `require` works, it typically involves accessing properties off the main module object.","wrong":"const toPng = require('html-to-image').toPng;","symbol":"toPng","correct":"import { toPng, toJpeg } from 'html-to-image';"},{"note":"When using TypeScript, type imports should explicitly use `type` modifier to ensure they are stripped from the compiled JavaScript, enhancing clarity and preventing potential bundling issues if the symbol name clashes with a value export.","wrong":"import { Options } from 'html-to-image';","symbol":"Options","correct":"import { toPng, type Options } from 'html-to-image';"}],"quickstart":{"code":"import { toPng } from 'html-to-image';\n\n// Create a DOM node to capture\nconst captureNode = document.createElement('div');\ncaptureNode.id = 'my-capture-node';\ncaptureNode.style.width = '400px';\ncaptureNode.style.height = '200px';\ncaptureNode.style.backgroundColor = '#f0f0f0';\ncaptureNode.style.padding = '20px';\ncaptureNode.style.border = '1px solid #ccc';\ncaptureNode.style.borderRadius = '8px';\ncaptureNode.innerHTML = `\n  <h2 style=\"color: #333;\">Welcome!</h2>\n  <p style=\"font-size: 14px;\">This paragraph will be converted into an image.</p>\n  <img src=\"https://via.placeholder.com/100x50/ADD8E6/000000?text=Hello\" alt=\"Example Placeholder\" style=\"display:block; margin-top:10px; border-radius: 4px;\">\n`;\ndocument.body.appendChild(captureNode);\n\n// Function to capture and display the image\nasync function captureAndDisplayImage() {\n  try {\n    // Options for toPng (e.g., cacheBust helps with fresh images)\n    const options = { cacheBust: true, pixelRatio: 2 };\n    const dataUrl = await toPng(captureNode, options);\n\n    const img = new Image();\n    img.src = dataUrl;\n    img.alt = 'Captured image from DOM node';\n    img.style.border = '2px dashed #007bff';\n    img.style.marginTop = '30px';\n    img.style.display = 'block';\n    document.body.appendChild(img);\n    console.log('Image successfully generated and appended to body!');\n  } catch (err) {\n    console.error('Oops, something went wrong during image generation!', err);\n  }\n}\n\ncaptureAndDisplayImage();\n","lang":"typescript","description":"This quickstart demonstrates how to dynamically create a DOM node with various styles and an image, then use `html-to-image` to convert it into a PNG data URL, and finally display the generated image on the page."},"warnings":[{"fix":"Ensure all external resources have appropriate CORS headers ('Access-Control-Allow-Origin'). For images, try adding `crossOrigin='anonymous'` attribute to `<img>` tags if the server supports it, or use the `imagePlaceholder` option to handle failures. Alternatively, embed resources as data URLs if feasible.","message":"When capturing content that includes images, fonts, or SVGs loaded from different origins, browsers enforce Cross-Origin Resource Sharing (CORS) policies. This can lead to a 'Tainted canvases cannot be exported' error, preventing image generation.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure all web fonts are completely loaded and active before invoking `html-to-image` functions. You might need to introduce a delay, use a font loading utility, or pass a `fontFamilies` option to explicitly declare fonts if issues persist.","message":"Web fonts may not render correctly in the generated image if they are not fully loaded before the capture process or if there are issues with their origin. This can result in incorrect text appearance or missing text.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Optimize the target DOM node by simplifying its structure, reducing image resolutions, or capturing only a specific, smaller section. Consider options like `skipFonts` or `skipImages` during development or for performance-critical scenarios.","message":"Attempting to capture very large or highly complex DOM structures, especially those with numerous images, deep nesting, or intricate CSS, can lead to significant performance bottlenecks and high memory consumption, potentially causing browser crashes.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Verify the validity and accessibility of URLs for all CSS-defined images. Ensure cross-origin resources adhere to CORS policies or embed them as data URLs if practical. Inspect the browser's network tab for failed requests during image generation.","message":"CSS background images (e.g., `background-image: url(...)`) or mask images might not render if their URLs are invalid, they are cross-origin without proper CORS, or they fail to load due to network issues. SVGs used as background images are particularly susceptible.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Update `html-to-image` to version 1.11.6 or newer for improved iframe handling. For cross-origin iframes, direct capture is generally restricted by browser security. Consider alternative strategies like rendering the iframe content separately if you control its source.","message":"Content within iframes, especially those from different origins or dynamically loaded, has historically been challenging to capture. While v1.11.6 introduced improvements for cloning iframe nodes, deep or complex iframe structures may still face limitations.","severity":"breaking","affected_versions":"<1.11.6"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Configure the server hosting the external resources to include `Access-Control-Allow-Origin: *` or a specific origin. For `<img>` tags, add the `crossOrigin='anonymous'` attribute, which will trigger a CORS request for the image. If embedding SVGs with `foreignObject`, ensure they are properly encoded and self-contained.","cause":"The generated canvas contains pixels derived from images or other resources (e.g., SVGs, fonts) that were loaded from a different origin (domain, protocol, or port) without appropriate Cross-Origin Resource Sharing (CORS) headers.","error":"Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."},{"fix":"Verify that the target DOM node exists and is correctly referenced using `document.getElementById('your-id')` or `document.querySelector('your-selector')`. Ensure that the element is fully rendered and available in the DOM before `html-to-image` functions are called, typically after a `DOMContentLoaded` event or within a React/Vue `useEffect` hook.","cause":"The DOM node passed as the first argument to any `html-to-image` function (e.g., `toPng(node)`) is `null`, `undefined`, or not a valid `HTMLElement` that is currently attached to the document's DOM tree.","error":"Error: Element not found or invalid node provided."},{"fix":"Ensure all images are fully loaded before initiating the capture. You can pre-load images or use `Promise.all` with `img.onload` events. Check image URLs for correctness. Address CORS issues as described in the 'Tainted canvases' warning. The `imagePlaceholder` option can provide a fallback for failed images.","cause":"Images might not have finished loading before the capture process began, their URLs are incorrect, or they are affected by CORS restrictions (even if not causing a 'tainted canvas' error directly, they might fail to load).","error":"Images are not appearing or appear as broken icons in the generated output image."},{"fix":"Verify that all relevant CSS stylesheets and web fonts are fully loaded and applied to the DOM node before capture. For custom fonts, ensure proper `@font-face` definitions and font file availability. Simplify complex CSS properties where possible. Ensure you are using the latest version of `html-to-image` for improved CSS compatibility.","cause":"External stylesheets or web fonts might not have been fully parsed or loaded. Complex or non-standard CSS properties might have limited support, or there could be issues with inline styles vs. external styles interactions.","error":"Some CSS styles (e.g., `background-image`, `border-radius`, custom `font-family`) are missing or incorrectly applied in the output image."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}