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

Choose the capture method by what you need to capture: use canvas.toBlob() to export pixels from a canvas your app owns, html2canvas to reconstruct a DOM element, or navigator.mediaDevices.getDisplayMedia() to let a user select a screen, window, or browser tab. These approaches have different fidelity, cross-origin, and permission constraints; ordinary page JavaScript cannot silently screenshot an arbitrary page or display.

Which browser screenshot method should you use?

“Screenshot” can mean three distinct jobs in a web app. A canvas export serializes a bitmap your application has already drawn. A DOM capture library recreates part of the page from DOM and style information. Display capture asks the user to choose a source and grant access. Decide which job you need before choosing an API.

Method What it captures Fidelity and limits User involvement
HTMLCanvasElement.toBlob() or toDataURL() The bitmap in a canvas your app owns Exports the canvas bitmap; a tainted canvas cannot be read or exported No display-capture prompt
html2canvas A DOM element or page region reconstructed from DOM information Not a native screenshot; unsupported CSS and cross-origin restrictions can cause differences or omissions Runs in the page
getDisplayMedia() A screen, window, or tab selected by the user Captures a user-approved display source rather than an arbitrary page region Requires user interaction, source selection, and permission for each capture

The key distinction is that only the first method exports an already-rendered canvas bitmap. html2canvas reconstructs content, while display capture is a permission-mediated browser feature.

Export a canvas your application owns

When your application already drew a chart, editor, game frame, or other image to a <canvas>, the Canvas API is the direct route. Prefer toBlob() for a Blob you can preview, upload, or download. Use toDataURL() when a data URL is specifically useful and the image is modest in size: it encodes the whole image into an in-memory string.

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

Export as a Blob

function canvasToBlob(canvas, type = "image/png", quality) {
  return new Promise((resolve, reject) => {
    canvas.toBlob((blob) => {
      if (blob) resolve(blob);
      else reject(new Error("Canvas export did not produce a Blob"));
    }, type, quality);
  });
}

const canvas = document.querySelector("canvas");
if (!canvas) throw new Error("Canvas not found");

const blob = await canvasToBlob(canvas);
const imageUrl = URL.createObjectURL(blob);

// For a preview:
const preview = document.querySelector("#preview");
preview.src = imageUrl;

// For a download:
const link = document.createElement("a");
link.href = imageUrl;
link.download = "canvas.png";
link.click();

// Revoke the URL when the preview or download is no longer needed.
URL.revokeObjectURL(imageUrl);

toBlob() uses a callback, so the helper wraps it in a Promise for use with await. For a long-lived preview, do not revoke the object URL immediately after assigning it; revoke it when the preview is replaced or removed.

Choose an image format

PNG is the default and required supported format. JPEG and WebP may also be supported. If the browser does not support the requested format, it falls back to PNG. The optional quality value applies to lossy formats such as JPEG or WebP; it is ignored for PNG.

toDataURL() is useful when an API or markup specifically needs a data URL:

const canvas = document.querySelector("canvas");
if (!canvas) throw new Error("Canvas not found");
const dataUrl = canvas.toDataURL("image/png");

For large images, avoid turning the entire bitmap into a base64-encoded string if a Blob will do. A canvas with zero dimensions, or dimensions beyond the browser’s maximum canvas size, returns the sentinel string data:, from toDataURL(). See MDN’s HTMLCanvasElement: toDataURL() method documentation for format and exception details.

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.

Capture a DOM element with html2canvas

If the target is a DOM element rather than an app-owned canvas, html2canvas builds a representation by traversing DOM information. It does not take a native screenshot of the browser’s rendered pixels. The output can differ from what the user sees, particularly where the page uses CSS or browser features the library does not support.

Install and capture an element

Install the package in a JavaScript project:

npm install html2canvas

Then pass the element you want to capture. This module example is suitable for a bundler or other environment that supports ES modules:

import html2canvas from "html2canvas";

const element = document.querySelector("#receipt");
if (!element) throw new Error("Capture target #receipt not found");

const canvas = await html2canvas(element);
const blob = await new Promise((resolve, reject) => {
  canvas.toBlob((result) => {
    if (result) resolve(result);
    else reject(new Error("Capture did not produce an image"));
  }, "image/png");
});

const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "receipt.png";
link.click();

For the full document, the project’s getting-started example is const canvas = await html2canvas(document.body);. Capturing a smaller element is usually a better fit when the page contains unrelated content. Check the project’s Getting Started guide for setup and its stated browser support: modern evergreen browsers, including Chrome/Chromium-based browsers, Firefox, and Safari. That is the project’s compatibility statement, not a promise that every CSS feature works in every version.

Understand reconstruction limits

  • It is not pixel-for-pixel browser capture. html2canvas supports properties it understands and may render a page differently from the browser.
  • Cross-origin iframes are inaccessible. Browser security restrictions prevent the library from reading their contents.
  • Foreign images and resources are subject to CORS. A resource that cannot be used under the page’s origin rules may be absent from the result.
  • Existing tainted canvases remain restricted. A DOM reconstruction library cannot bypass the browser’s content security model.

The project documents these limitations in its documentation. If exact rendered pixels, cross-origin content, or a full-page capture are essential, validate the result for your page rather than assuming reconstruction equals a screenshot.

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

Let the user select a screen, window, or tab

Use navigator.mediaDevices.getDisplayMedia() when the user should choose a display source. The browser presents a source picker and permission flow; it is not a way for ordinary page JavaScript to silently capture a display.

Start a user-mediated capture

Call it in response to a user action, such as a button click. The stream below is attached to a video element so the user can preview the selected source:

const button = document.querySelector("#start-capture");
const video = document.querySelector("#capture-preview");

button.addEventListener("click", async () => {
  try {
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: true,
      audio: false
    });
    video.srcObject = stream;
    await video.play();

    // Stop the capture when the user ends it in the browser UI,
    // or when your app no longer needs the stream.
    for (const track of stream.getTracks()) {
      track.addEventListener("ended", () => {
        video.srcObject = null;
      });
    }
  } catch (error) {
    console.error("Display capture was not started:", error);
  }
});

Example markup:

<button id="start-capture">Choose what to share</button>
<video id="capture-preview" autoplay playsinline></video>

The user must interact to initiate capture, choose a source, and grant permission again for each capture; permission cannot be persisted for reuse. Constraints cannot be used to silently pre-limit the user’s source choices. Consult MDN’s getDisplayMedia() documentation for API behavior and current browser requirements.

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

Cross-origin images: why canvas export fails

When a foreign image is drawn into a canvas without suitable CORS approval, the browser marks the canvas as tainted. Attempts to inspect its pixels or export it—including getImageData(), toBlob(), toDataURL(), and captureStream()—are blocked with a security error.

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

Setting an image element’s crossorigin attribute is not sufficient on its own. The image server must also return an appropriate CORS response. Client-side JavaScript cannot grant itself access to another origin’s image pixels. For the practical rules, see MDN’s guide to using cross-origin images in a canvas.

Common failures and how to fix them

Symptom Likely cause What to do
SecurityError when exporting The canvas includes a cross-origin image without valid CORS approval Serve the image with suitable CORS headers and load it with the appropriate crossorigin setting, or avoid drawing that resource into an exportable canvas.
toDataURL() returns data:, The canvas has zero dimensions or exceeds the browser’s maximum canvas size Check the canvas width and height; use a smaller output or split the content into smaller captures.
html2canvas omits an image or iframe Cross-origin policy blocks access to the resource or iframe Use resources served with appropriate CORS permission where possible; cross-origin iframe contents cannot be read by the library.
html2canvas looks different from the page The library reconstructs supported DOM features rather than photographing rendered pixels Check the project’s supported properties and simplify or adapt the target markup; choose another capture route if exact rendered output is necessary.
The display picker does not appear or capture fails The call was not initiated through the expected user interaction, or the user declined or canceled permission Call from a user action and handle cancellation as a normal outcome; explain that the user must choose a source.
A generated preview disappears or leaks memory An object URL was revoked too early, or not revoked after use Keep it alive while needed, then call URL.revokeObjectURL() when replacing or removing the preview.

Or skip the browser setup

If you need a screenshot of a public website rather than content in your app’s own browser session, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. Example cURL request, using the documented endpoint and parameter style:

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

See the ScreenshotNeo API documentation for the request options and output formats. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use screenshot tools. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. This is a website capture service, not a way to capture a user’s private display or bypass browser permissions. Sign up for 1,000 free screenshots a month with no card.

FAQ

Can I use html2canvas in a browser extension?

It depends on the extension’s execution context and its access to the page. html2canvas cannot bypass cross-origin iframe or resource restrictions, so extension permissions do not make every page element readable.

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.

Can I copy an html2canvas result to the clipboard?

The rendered result is a canvas, so clipboard handling is a separate step from capture. Browser clipboard permissions and support determine whether a web app can write an image; html2canvas itself does not grant clipboard access.

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.