Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Install html2canvas, import its default export, select a DOM element, and await html2canvas(element, options). The promise resolves to a <canvas> element that you can display or export as an image. This is a browser-side DOM renderer, not a native screenshot facility, so the result depends on the CSS and resources the library can read.

import html2canvas from 'html2canvas';

const element = document.querySelector('#capture');
if (!element) throw new Error('Capture element not found');

const canvas = await html2canvas(element);
document.body.appendChild(canvas);

The steps below cover installation, a complete capture flow, useful options, cross-origin restrictions, large-page failures, and when a browser screenshot API is a better fit.

What html2canvas does—and what it does not do

html2canvas walks through a DOM subtree and reconstructs an image from readable HTML, styles, and resources. It does not copy the browser’s already-composited pixels. Unsupported CSS, inaccessible images, fonts, videos, plugins, or browser effects can therefore make the canvas differ from what a person sees on screen. The project’s documentation describes this distinction in its documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The library runs in a browser with the required web APIs. The official examples list modern evergreen browsers, including Chromium-based browsers, Firefox, and Safari; it is not intended for Node.js execution without a browser environment. See the browser information in the official examples.

Install and initialize html2canvas

Install from npm

In an existing front-end project, install the package:

npm install html2canvas

Confirm the package name and release channel on the current Getting Started guide if your build system or package manager has changed. The guide also documents package-manager and CDN approaches.

Import the default export

Use the default import in an ES-module build. Put the call in an event handler, a component action, or another point after the target element has been rendered.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import html2canvas from 'html2canvas';

async function captureCard() {
  const element = document.querySelector('#capture');
  if (!element) {
    throw new Error('Capture element not found');
  }

  const canvas = await html2canvas(element);
  document.body.appendChild(canvas);
}

captureCard().catch(console.error);

The returned object is a normal HTML canvas. Appending it is useful while developing because you can immediately inspect the result. In production, you will usually convert it to a data URL or a blob instead.

Capture a specific element and download a PNG

Pass any HTMLElement as the first argument. The renderer includes that element’s descendant content according to the options you provide.

import html2canvas from 'html2canvas';

const button = document.querySelector('#save-capture');
const target = document.querySelector('#capture');

if (!button || !target) {
  throw new Error('Required capture elements are missing');
}

button.addEventListener('click', async () => {
  button.disabled = true;
  try {
    const canvas = await html2canvas(target, {
      backgroundColor: '#ffffff'
    });

    const link = document.createElement('a');
    link.download = 'capture.png';
    link.href = canvas.toDataURL('image/png');
    link.click();
  } finally {
    button.disabled = false;
  }
});

canvas.toDataURL('image/png') creates a PNG data URL. The official examples show the same download-link technique. For large captures, data URLs can consume substantial memory; use a blob when you need to move a large image through an upload or download flow.

const canvas = await html2canvas(target);
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
if (!blob) throw new Error('The browser could not encode the canvas');

const downloadUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'capture.png';
link.href = downloadUrl;
link.click();
URL.revokeObjectURL(downloadUrl);

Options that solve common capture requirements

The complete option list and defaults are in the configuration reference. These are the settings most applications need.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Option Use it for Example
scale Changing output pixel density. The documented default is window.devicePixelRatio. scale: 1 for a smaller file, or scale: 2 for a denser export.
backgroundColor Setting a fallback background when the DOM has none. backgroundColor: '#fff'; use null for transparency.
x, y, width, height Cropping to a region of the rendered page. width: 600, height: 400
windowWidth, windowHeight Choosing the viewport dimensions used while html2canvas evaluates layout and media queries. windowWidth: element.scrollWidth
useCORS Attempting to load images from another origin when that origin sends permission through CORS. useCORS: true
proxy Routing resource retrieval through a proxy that can fetch the asset appropriately. proxy: 'https://your-proxy.example/cors'
ignoreElements Excluding nodes programmatically. ignoreElements: el => el.matches('.no-export')
data-html2canvas-ignore Marking individual elements to omit without writing a callback. <div data-html2canvas-ignore>Ads</div>
onclone Editing the cloned document used for rendering while leaving the live page unchanged. onclone: doc => doc.body.classList.add('export-mode')

Control sharpness and file size

Higher scale values create more output pixels and can improve detail, but they also increase memory use and encoding time. An explicit value such as 1 makes output dimensions easier to predict across displays. Keep the default when matching the device’s pixel density matters more than a consistent file size.

Render a transparent card

const canvas = await html2canvas(document.querySelector('#capture'), {
  backgroundColor: null,
  scale: 2
});

Transparency only affects the canvas background. An element that paints its own opaque background remains opaque.

Capture a full, scrollable element

A tall element may be laid out using the current viewport unless you provide dimensions. Read its scroll size and pass it as the rendering viewport:

const element = document.querySelector('#long-report');
if (!element) throw new Error('Report not found');

const canvas = await html2canvas(element, {
  windowWidth: element.scrollWidth,
  windowHeight: element.scrollHeight,
  width: element.scrollWidth,
  height: element.scrollHeight
});

This is especially useful when a responsive media query or an overflow container causes the default capture to be cut off. The official FAQ discusses matching windowWidth or windowHeight to the element’s scroll dimensions: FAQ.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Hide controls only in the cloned render

const canvas = await html2canvas(document.querySelector('#invoice'), {
  onclone: clonedDocument => {
    clonedDocument.querySelectorAll('.print-only-hide')
      .forEach(node => { node.style.display = 'none'; });
  }
});

onclone receives the document copy used by the renderer, so export-only styling does not alter the page the user is interacting with.

Cross-origin images, fonts, and iframes

Images from another origin

Browser security rules still apply. useCORS: true can request an image with CORS, but it cannot grant permission that the image server did not send. Direct loading requires the remote server to allow your origin. If it does not, configure an appropriate proxy with the proxy option; the proxy must retrieve the asset in a way the browser can use.

const canvas = await html2canvas(element, {
  useCORS: true,
  proxy: 'https://your-proxy.example/cors'
});

Do not treat either setting as a security bypass. If an image remains inaccessible, remove it from the render, arrange correct CORS headers on the asset host, or use a proxy you control and trust.

Cross-origin iframes

A page in a different origin cannot expose its document to your script. html2canvas therefore cannot render the contents of a cross-origin iframe. You can capture the surrounding page, but the embedded document must provide its own cooperation or be rendered separately from a context that can access it.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why a result is blank, clipped, or visually different

The canvas is empty or truncated

  • Reduce the requested width, height, or scale and try again.
  • For long content, set windowWidth and windowHeight to the element’s scroll dimensions.
  • Check browser canvas-size limits. Limits vary by browser and device; html2canvas cannot allocate a canvas larger than the platform permits.

Images are missing

  • Confirm that the image URL is reachable from the browser.
  • Ask the asset server for the appropriate CORS response and set useCORS: true.
  • If you use a proxy, verify its URL, authentication, and response headers.
  • Exclude decorative or third-party images with data-html2canvas-ignore when they are not essential.

The output does not match the screen

Check whether the design relies on CSS or browser effects that html2canvas does not reconstruct. Also verify fonts have loaded before starting the capture, the target has finished rendering, and the capture viewport matches the layout you intend. A DOM reconstruction should not be advertised as a pixel-perfect browser screenshot.

The target is not found

Run the code after the target is mounted and use a null check. In component frameworks, call html2canvas from a client-side event or lifecycle stage, not during server rendering. The library needs a real browser DOM.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A reliable capture workflow

  1. Render the target element and wait for its content, images, and fonts to be ready.
  2. Select the element and fail clearly if the selector returns null.
  3. Choose scale, background, viewport, crop, and exclusion settings deliberately.
  4. Handle cross-origin resources with server-side CORS or a suitable proxy.
  5. Await the promise inside try...catch; a capture can fail because of resource access or platform limits.
  6. Encode the returned canvas as PNG, JPEG, or another browser-supported canvas format, then release object URLs created for blobs.
  7. Test the smallest and largest target sizes your users will create, especially on mobile devices.

Or skip the browser setup

If you need a screenshot of a URL rather than a DOM element inside your own page, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Only clean shots are billed, while bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the result with X-Page-Verdict and X-Billed headers.

One GET request returns PNG, JPEG, WebP, or a PDF. The API supports full-page captures with lazy images, CSS-selector element captures, dark mode, device presets and custom viewports, retina scale, PDF paper and page settings, custom CSS and JavaScript, clicks, waits, resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Here is the one-call cURL form (see the ScreenshotNeo documentation):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 shots per month without a card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try it.

When to choose html2canvas versus a URL screenshot API

  • Choose html2canvas when the content is already in your page, you need a client-side export, and you can accept DOM-based rendering and browser security limits.
  • Choose a URL screenshot API when you need a repeatable server-side capture of a public page, PDF output, automated waits, consent handling, or an image that is independent of the viewer’s browser.
  • Use both when an application offers a local “export this current state” button but also generates scheduled or bulk snapshots on a server.

For an API recommendation, ScreenshotNeo is the first service to try because it produces clean shots, bills only clean shots, and has a $5 paid plan for 3,000 shots.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.