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

To get started with html2canvas, install the package in a browser-based JavaScript project, import it, select a real DOM element, and await the Promise it returns. The result is an HTML <canvas> that you can display or export as a PNG, JPEG, or WebP. The example below captures a card, removes a control from the output, and downloads the result.

What html2canvas does (and what it does not)

html2canvas creates a canvas representation by traversing the DOM and reading element styles. It does not copy the browser’s already-rendered pixels. The project describes it as taking “screenshots” of webpages or parts of them directly in the user’s browser. Because it reconstructs the page, every CSS property and embedded resource must be supported and accessible to the library; the result can differ from what you see on screen.

  • It runs in a browser context with window, document, and computed styles.
  • It resolves asynchronously to a canvas rather than an image file.
  • It is useful for client-side previews, reports, receipts, and user-triggered exports when the page’s CSS and assets are compatible.
  • It is not a native, pixel-for-pixel browser screenshot service.

Install and import the package

The current official getting-started instructions show the scoped package name:

npm install @html2canvas/html2canvas

The npm package page and repository documentation also show the unscoped html2canvas name. Do not mix a package name with the other package’s import path. Check the package version you are choosing, then make installation and import agree.

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

TypeScript or modern JavaScript

import html2canvas from '@html2canvas/html2canvas';

If your project uses the unscoped package instead, install and import that same package consistently:

npm install html2canvas
import html2canvas from 'html2canvas';

These examples assume a bundler such as Vite, Webpack, or another browser build tool. In a plain HTML page, load the browser-compatible distribution your selected package version documents and use the global it provides.

Capture an element and show the canvas

Put the target element in the document before calling the function. The call returns a Promise, so use await inside an asynchronous function or a .then() handler.

<section id="capture" class="invoice">
  <h1>Invoice 1042</h1>
  <p>Total: $128.00</p>
  <button data-html2canvas-ignore>Edit</button>
</section>
import html2canvas from '@html2canvas/html2canvas';

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

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

showCapture().catch(console.error);

Appending the canvas is a useful first diagnostic: you can immediately see what the library reconstructed. In production, append it to a dedicated preview container instead of the document body.

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.

Export the result as an image

Use the canvas API after the Promise resolves. The following creates a PNG download without leaving the page.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
import html2canvas from '@html2canvas/html2canvas';

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

  const canvas = await html2canvas(element);
  const link = document.createElement('a');
  link.download = 'invoice-1042.png';
  link.href = canvas.toDataURL('image/png');
  link.click();
}

document.querySelector('#download')?.addEventListener('click', () => {
  downloadCapture().catch(console.error);
});

Replace image/png with image/jpeg or image/webp when those formats suit your workflow. JPEG does not preserve transparency. If you need a Blob for an upload, use canvas.toBlob() rather than creating a large data URL.

Useful capture options

Crop to a region

Pass x, y, width, and height to capture a specific rectangle. Coordinates and dimensions should match the page space you intend to reconstruct.

const canvas = await html2canvas(element, {
  x: 0,
  y: 0,
  width: element.scrollWidth,
  height: element.scrollHeight
});

Increase output density

For a sharper image on high-density displays, set scale, commonly to window.devicePixelRatio. A larger scale also increases memory use and output dimensions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const canvas = await html2canvas(element, {
  scale: window.devicePixelRatio
});

Exclude controls and other UI

Add data-html2canvas-ignore to any element that should not appear in the result. This is often cleaner than temporarily changing visibility.

<button data-html2canvas-ignore>Close</button>

Wait until content is ready

Call html2canvas after fonts, images, and data-driven components have finished rendering. For an image-heavy component, wait for its image elements explicitly:

await Promise.all(
  [...document.querySelectorAll('#capture img')].map(img =>
    img.complete
      ? Promise.resolve()
      : new Promise(resolve => {
          img.addEventListener('load', resolve, { once: true });
          img.addEventListener('error', resolve, { once: true });
        })
  )
);
const canvas = await html2canvas(document.querySelector('#capture'));

This prevents an avoidable race, but it cannot make an inaccessible cross-origin image readable.

Cross-origin images and canvas security

Images served from another origin can taint the canvas. Set useCORS: true only when the image server returns an appropriate Access-Control-Allow-Origin header:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const canvas = await html2canvas(element, { useCORS: true });

If the server does not grant access, route the resource through a same-origin proxy that adds the required CORS response headers. html2canvas cannot bypass browser security policy, and useCORS does not grant permission by itself. A tainted canvas prevents operations such as toDataURL() and toBlob().

Known fidelity and content limits

CSS support

CSS support is property-specific. Unsupported properties, complex effects, or differences in font availability can make the canvas look unlike the visible page. Check the project’s supported-features documentation for the properties your design depends on, then test the actual component in the browsers you support. Do not treat a successful Promise as proof of pixel-perfect fidelity.

Iframes and embedded content

Same-origin iframes can be traversed recursively. Cross-origin frames cannot be rendered because the browser blocks access to their documents; sandboxed frames without allow-same-origin have the same restriction. Plugin content such as Flash or Java applets is not rendered.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Very large elements

Canvas dimensions and total area have browser- and platform-dependent limits. An oversized capture can be blank or partially drawn without a useful error. Reduce the target, lower scale, capture in tiles, or generate separate sections. Where a page is being clipped, set windowWidth and windowHeight to the target’s scroll dimensions:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const canvas = await html2canvas(element, {
  windowWidth: element.scrollWidth,
  windowHeight: element.scrollHeight
});

There is no durable universal maximum: limits vary by browser, operating system, device, and available memory.

A practical production pattern

  1. Render the component in its final state, including the intended viewport width and theme.
  2. Wait for application data, images, and fonts that affect the component.
  3. Temporarily add or retain data-html2canvas-ignore on buttons, menus, and transient overlays.
  4. Call html2canvas with a deliberate scale and, if necessary, crop dimensions.
  5. Inspect the canvas before exporting during development.
  6. Use toBlob() for uploads and toDataURL() for small, local downloads.
  7. Test same-origin and cross-origin assets, long pages, dark mode, and the browsers your users actually run.

Troubleshooting html2canvas

The target is null or nothing happens

Make sure the selector matches, the element has been inserted, and the call runs after the relevant component mounts. Log the element before calling html2canvas and handle the rejected Promise.

Images are missing or export throws a security error

Confirm the image URL’s origin and response headers. Use useCORS: true only with server permission, or proxy the asset through your own origin. Replace inaccessible images with same-origin copies when appropriate.

Styles differ from the page

Identify the specific CSS property or font that differs and compare it with the library’s supported features. Simplify unsupported effects or provide a capture-specific style rather than promising identical pixels.

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

The output is blank, clipped, or crashes on long pages

Reduce the capture area or scale, try the target’s scroll dimensions for windowWidth and windowHeight, and split very large documents into sections. Browser canvas limits are variable.

It fails in Node.js

html2canvas depends on browser APIs and is not a Node.js server-rendering library. For server-side screenshots, the official FAQ points to real-browser tools such as Puppeteer and Playwright.

I am building a browser extension

Use the browser’s native extension screenshot API when possible. It avoids html2canvas’s canvas-size constraints and captures the browser surface rather than reconstructing DOM content.

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

When html2canvas is the wrong tool

Choose html2canvas when the job is a browser-side representation of a known DOM element and the page’s assets are accessible. Choose a native browser screenshot when you need the pixels the browser painted, server-side rendering, reliable cross-origin handling, or a page containing unsupported CSS and embedded content. For server work, Puppeteer and Playwright are the alternatives named by the project FAQ; for extensions, prefer the platform screenshot API.

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.

Or skip the browser setup

If you need a URL screenshot rather than a canvas reconstruction inside your page, ScreenshotNeo makes the request on a browser-backed service. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000 shots.

One-call cURL example

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}`);

See the ScreenshotNeo API documentation for request options. If that workflow fits better than client-side DOM reconstruction, create a free ScreenshotNeo account with 1,000 screenshots a month and no card.

FAQ

Frequently Asked Questions

Can html2canvas capture a whole website from a URL by itself?

No. It runs in a page and receives a DOM element. A URL-level capture requires loading that page in a browser context first, or using a browser screenshot service.

Does html2canvas create a PDF?

It returns a canvas. You would need a separate client-side PDF workflow, or a tool designed to produce PDFs.

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

Is the output automatically available as a file?

No. Convert the resolved canvas with the browser canvas APIs, such as toDataURL() or toBlob(), then download or upload it.

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.