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

JavaScript can capture either a reconstruction of page content or the actual pixels of a browser tab, window, or monitor. Use html2canvas when you need an element or document rendered from readable DOM and CSS; use navigator.mediaDevices.getDisplayMedia() when the user must choose a display surface. Neither method is a universal replacement for the other, and both have important security and fidelity limits.

Choose the right kind of screenshot

Start by defining what “screenshot” means in your application:

Requirement Best fit What it captures Important limitation
An element, component, or page content html2canvas A canvas reconstruction of readable DOM and supported CSS It is not a pixel-level browser screenshot; unsupported CSS, cross-origin images, and cross-origin iframes can differ or fail
A selected tab, window, monitor, or other display surface getDisplayMedia() Video frames from the surface the user selects Requires a secure context, user interaction, permission, and a browser chooser; browser support is limited
A server-side image or PDF from a URL ScreenshotNeo A clean rendered page returned by an API Requires an API key and an HTTP request rather than running entirely in the visitor’s browser

The choice affects permissions, cross-origin behavior, fidelity, performance, and whether browser chrome or another application can appear in the result.

Capture an HTML element with html2canvas

html2canvas walks the target DOM, reads styles and resources available to the page, and paints a representation into a canvas. Load it in your page, select an element, and wait for the returned promise.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Basic element capture

<button id="save-card">Save card</button>
<article id="capture">
  <h1>Monthly report</h1>
  <p>Revenue increased 18% this quarter.</p>
</article>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<script>
document.querySelector('#save-card').addEventListener('click', async () => {
  const element = document.querySelector('#capture');
  const canvas = await html2canvas(element);
  canvas.toBlob((blob) => {
    if (!blob) throw new Error('The canvas could not be exported.');
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'monthly-report.png';
    link.click();
    URL.revokeObjectURL(url);
  }, 'image/png');
});
</script>

The promise resolves to an HTMLCanvasElement. Appending that canvas to the document is a useful debugging step:

html2canvas(document.querySelector('#capture')).then((canvas) => {
  document.body.appendChild(canvas);
});

Capture the entire document

Passing document.body captures the body’s rendered content as reconstructed by the library. For long pages, explicitly provide the document dimensions so the canvas is not limited to the current viewport:

const width = Math.max(
  document.body.scrollWidth,
  document.documentElement.scrollWidth,
  document.documentElement.clientWidth
);
const height = Math.max(
  document.body.scrollHeight,
  document.documentElement.scrollHeight,
  document.documentElement.clientHeight
);

const canvas = await html2canvas(document.body, {
  width,
  height,
  windowWidth: width,
  windowHeight: height,
  scale: window.devicePixelRatio
});

canvas.toBlob((blob) => {
  if (!blob) return;
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = 'full-page.png';
  link.click();
}, 'image/png');

Very large pages can consume substantial memory. Consider capturing sections separately, lowering scale, or exporting with toBlob() rather than creating a giant data URL.

Region, scale, and image options

  • x, y, width, and height restrict rendering to a region.
  • scale: window.devicePixelRatio makes output sharper on high-density displays, but increases pixel count and memory use. A fixed value such as 1 is more predictable for large exports.
  • useCORS: true allows images that explicitly grant cross-origin access through CORS headers. It cannot bypass the browser’s same-origin policy.
  • Use onclone when you need to alter the cloned document—for example, hide a button or reveal a print-only section without changing the live page.
const canvas = await html2canvas(document.querySelector('#invoice'), {
  backgroundColor: '#ffffff',
  scale: 2,
  useCORS: true,
  x: 0,
  y: 0,
  width: 900,
  height: 700,
  onclone: (clonedDocument) => {
    clonedDocument.querySelector('.download-button')?.remove();
  }
});

Export the canvas as PNG, JPEG, or WebP

Use toBlob() for downloads and uploads

toBlob() avoids turning the entire image into a large in-memory string. The callback receives a Blob, or null if encoding fails.

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.
Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
function downloadCanvas(canvas, filename, type = 'image/png', quality) {
  canvas.toBlob((blob) => {
    if (!blob) {
      console.error('Canvas encoding failed');
      return;
    }
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.download = filename;
    link.href = url;
    link.click();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }, type, quality);
}

// PNG is lossless; quality is ignored by most browsers.
downloadCanvas(canvas, 'capture.png', 'image/png');
// JPEG and WebP accept a quality number from 0 to 1 where supported.
downloadCanvas(canvas, 'capture.jpg', 'image/jpeg', 0.9);

Use toDataURL() only when a data URL is useful

canvas.toDataURL() returns a data URL and defaults to PNG when the type is omitted or unsupported:

const dataUrl = canvas.toDataURL('image/png');
previewImage.src = dataUrl;

Because the complete encoded image is held in a JavaScript string, toDataURL() can create memory and URL-length problems for large captures. Prefer toBlob() for downloads, uploads, and storage.

Capture the actual screen, window, or tab

The Screen Capture API’s navigator.mediaDevices.getDisplayMedia() asks the user to choose a monitor, window, or tab. It returns a MediaStream, not an image. Draw one video frame to a canvas after metadata is available, then export it.

Complete still-image example

<button id="share-screen">Choose a surface</button>
<video id="preview" autoplay muted playsinline hidden></video>
<script>
const button = document.querySelector('#share-screen');
const video = document.querySelector('#preview');

button.addEventListener('click', async () => {
  let stream;
  try {
    stream = await navigator.mediaDevices.getDisplayMedia({
      video: { displaySurface: 'browser' },
      audio: false
    });

    video.srcObject = stream;
    await video.play();
    await new Promise((resolve) => {
      if (video.readyState >= 2) resolve();
      else video.addEventListener('loadeddata', resolve, { once: true });
    });

    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0);

    canvas.toBlob((blob) => {
      if (!blob) return;
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'display-capture.png';
      link.click();
      URL.revokeObjectURL(url);
    }, 'image/png');
  } catch (error) {
    if (error.name === 'NotAllowedError') {
      console.warn('The user denied capture or cancelled the chooser.');
    } else {
      console.error('Display capture failed:', error);
    }
  } finally {
    stream?.getTracks().forEach((track) => track.stop());
    video.srcObject = null;
  }
});
</script>

Requirements and permission behavior

  • Serve the page from a secure context (normally HTTPS; localhost is treated specially during development).
  • Start the call from a recent user interaction such as a button click. Do not trigger it silently on page load.
  • The browser displays its own chooser and permission UI. JavaScript cannot select a particular monitor or window without the user.
  • Always stop the stream’s tracks after taking the still image, especially in a long-lived single-page application.
  • Test your target browser matrix: MDN marks getDisplayMedia() as limited availability, and some widely used browsers do not support it.

The selected surface can include content outside your page, but browser chrome and protected content may be excluded by the browser. The exact choices and restrictions are browser-controlled.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Why html2canvas misses images or styles

Cross-origin images

An image hosted on another origin must send suitable CORS headers for the browser to expose its pixels. Set useCORS: true only when the image server permits it. If a cross-origin image is drawn without permission, the canvas becomes tainted and calls such as toBlob() or toDataURL() can fail with a security error. A server-side proxy that fetches and serves the image from your origin is the usual alternative, subject to that site’s policies.

Cross-origin iframes

Scripts on your page cannot inspect or reconstruct the DOM of an iframe from another origin. html2canvas therefore cannot reliably render its contents. Capture the iframe’s own page from code running there, obtain cooperation through an appropriate postMessage design, or use a server-side browser capture.

Unsupported or complex CSS

html2canvas implements a renderer for many common properties; it does not ask the browser for its final pixels. Filters, blend modes, pseudo-elements, video frames, fonts that have not loaded, and newer CSS features can therefore differ from the visible page. Wait for fonts and images before capturing:

await document.fonts.ready;
await Promise.all([...document.images].map((image) => {
  if (image.complete) return Promise.resolve();
  return new Promise((resolve) => {
    image.addEventListener('load', resolve, { once: true });
    image.addEventListener('error', resolve, { once: true });
  });
}));
const canvas = await html2canvas(document.querySelector('#capture'));

Performance, fidelity, and reliability decisions

  • Pixel fidelity: display capture records the selected surface’s video frame. html2canvas is a DOM/CSS reconstruction and can be visually different even when the page looks correct.
  • Permissions: element capture normally needs no prompt; display capture always depends on user selection and permission.
  • Output size: increasing scale improves detail but multiplies canvas pixels. Use toBlob() and release object URLs.
  • Timing: capture after fonts, images, lazy-loaded content, animations, and data updates have settled. Disable animations in a cloned document when deterministic output matters.
  • Security: same-origin policy protects cross-origin images and frames. No JavaScript option can legitimately override it.
  • Browser coverage: canvas export is broadly available; Screen Capture API support varies substantially, so feature-detect it before showing the control.
const canShareDisplay = !!navigator.mediaDevices?.getDisplayMedia;
shareButton.hidden = !canShareDisplay;

Troubleshooting checklist

“Permission denied” or no chooser appears

  • Move the call into a click or keyboard handler.
  • Use HTTPS (or localhost for local development).
  • Check that the user did not cancel the chooser and that browser or enterprise policy does not disable screen sharing.

“SecurityError” when exporting

Find cross-origin images in the target tree. Configure the image host for CORS and use useCORS: true, remove the image from the capture, or render through a permitted proxy. Cross-origin iframe content cannot be read by the parent page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

The screenshot is blank or only partly rendered

  • Wait for document.fonts.ready, image completion, and asynchronous data.
  • Ensure the target is not display:none and has non-zero dimensions.
  • For a long document, set explicit dimensions and inspect for fixed-position elements or lazy loading that only occurs after scrolling.

The result looks different from the page

That is expected when unsupported CSS, web fonts, video, filters, or cross-origin resources are involved. Use getDisplayMedia() when the requirement is the visible display, or move rendering to a browser automation/API service.

The display image has the wrong dimensions

Use the video’s intrinsic videoWidth and videoHeight for the canvas, not CSS dimensions. Drawing before loadeddata or before a frame is available can produce an empty image.

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

Or skip the browser setup

For a URL you control or need to capture from a backend, ScreenshotNeo provides a single HTTP request that returns PNG, JPEG, WebP, or PDF. It accepts the cookie or consent banner like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status.

It also offers an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. Features include full-page captures with lazy images loaded, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, PDF paper and page controls, custom CSS and JavaScript, pre-capture clicks, selector or network-idle waits, ad/tracker/request blocking, custom headers and cookies, user-agent and Authorization support, timezone and geolocation, transparent backgrounds, resizing, selectable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs.

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

One-call examples

See the ScreenshotNeo documentation for the complete option reference.

Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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 with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan, and yearly billing provides two months free. Sign up free for ScreenshotNeo and start with the no-card allowance.

Which method should you ship?

  • Choose html2canvas for user-requested snapshots of your own DOM when a close reconstruction is acceptable.
  • Choose getDisplayMedia() for a user-selected tab, window, or monitor and design around its permission and compatibility requirements.
  • Choose ScreenshotNeo when you need repeatable URL capture, server-side processing, clean pages, PDFs, automation controls, or AI-agent access without building a browser-capture flow.

Frequently Asked Questions

Can JavaScript capture browser tabs without asking the user?

No. A browser must show the getDisplayMedia() chooser and obtain permission. Silent tab or monitor capture is intentionally blocked.

Can html2canvas capture a cross-origin iframe?

Not from the parent page. Same-origin policy prevents reading another origin’s iframe DOM; the iframe application or a server-side capture must handle 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.

Should I use PNG or JPEG for a screenshot?

PNG is lossless and the default. JPEG can be smaller for photographic content and accepts a quality value, while text-heavy UI usually remains clearer in PNG.

Why does my canvas export throw a security error?

A cross-origin image without successful CORS authorization likely tainted the canvas. Configure CORS, use an approved proxy, or omit that resource.

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.