Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
html2canvas turns a DOM element into a <canvas> asynchronously. Install the browser package, pass an element such as document.querySelector('#capture'), await the returned Promise, and then export or display the canvas. It reconstructs the image from the DOM and styles; it does not copy the browser’s already-rendered pixels, so unsupported CSS, cross-origin images and very large elements can produce differences or incomplete output.
What html2canvas actually does
html2canvas walks the selected element, reads its computed styles and child nodes, and paints a new canvas. The project documentation describes this limitation directly: “The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.”
This distinction determines when to use it. It is useful when code running in a page needs an image of a component, report, receipt or dashboard. It is not a pixel-level browser screenshot API. Every CSS property must be implemented by the library; the project FAQ therefore says html2canvas “will never have full CSS support.”
Install and capture an element
Install the package
The official getting-started guide shows the package named html2canvas and installation through npm, Yarn or pnpm:
#1 Best Overall
npm install html2canvas
# or
yarn add html2canvas
# or
pnpm add html2canvas
Use it from browser code bundled by your application:
import html2canvas from 'html2canvas';
const element = document.querySelector('#capture');
if (!element) throw new Error('Capture element was not found');
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
The function accepts a DOM element and an optional options object. It returns a Promise resolving to a canvas, so do not call toDataURL(), append the result or inspect dimensions until the Promise has resolved.
Display, download or obtain bytes
const canvas = await html2canvas(document.querySelector('#capture'));
// Display it somewhere else
preview.replaceChildren(canvas);
// Download a PNG
const link = document.createElement('a');
link.download = 'capture.png';
link.href = canvas.toDataURL('image/png');
link.click();
For JPEG, pass an image type and quality to toDataURL():
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallconst jpeg = canvas.toDataURL('image/jpeg', 0.9);
Keep the export step on the client. A canvas containing inaccessible cross-origin image data may be tainted and refuse pixel-reading operations.
Capture options you will commonly need
Start with the default call, then add only the options that solve a demonstrated problem. The exact option behavior depends on browser support and the library version.
backgroundColor: Set a color when the captured element’s transparent background should become opaque. Usenullwhen you need transparency and the rest of the rendering path supports it.scale: Controls the pixel density of the output canvas. A larger value can improve detail but increases memory use and may hit browser canvas limits sooner.windowWidthandwindowHeight: Define the viewport dimensions used while rendering. They are especially useful when responsive CSS changes the layout or when a long element needs its scroll dimensions.useCORS: Requests images with CORS enabled. It works only when the image server sends a suitableAccess-Control-Allow-Originheader; it does not bypass browser security.proxy: Points to a server-side proxy that retrieves remote resources and returns them in a browser-usable form. The proxy must be configured correctly and must respect the resource owner’s security policy.allowTaint: Changes how cross-origin images are handled, but allowing taint does not make a tainted canvas readable. If you need PNG or JPEG bytes, solve the CORS or proxy issue instead.ignoreElements: Excludes matching nodes through a predicate, useful for buttons, live controls or animated overlays that should not appear in the exported image.logging: Enables diagnostic messages while reducing a reproduction case.
Check the project’s supported-features documentation for a CSS property that renders differently. An option cannot add support for a property the renderer does not implement.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Build a reliable capture workflow
- Capture a stable state. Wait until data, fonts and images needed by the element have loaded. Pause animations or apply a temporary class if movement makes output inconsistent.
- Choose the element, not the page. Select the smallest container that contains the content you need. Smaller canvases are less likely to exceed device limits.
- Set the intended viewport. If responsive breakpoints matter, pass matching
windowWidthandwindowHeightvalues and test each target browser. - Render and inspect. Await the Promise, check
canvas.widthandcanvas.height, and verify the result visually before uploading or downloading it. - Export only after success. Call
toBlob()for a Blob when possible; it avoids keeping a large base64 string in memory.
const target = document.querySelector('#capture');
const canvas = await html2canvas(target, {
backgroundColor: '#ffffff',
scale: Math.min(window.devicePixelRatio || 1, 2),
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight,
useCORS: true
});
canvas.toBlob((blob) => {
if (!blob) throw new Error('The browser could not encode the canvas');
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'element.png';
a.click();
URL.revokeObjectURL(url);
}, 'image/png');
The useCORS setting in this example is appropriate only when every remote image involved is served with compatible CORS headers. Remove it or fix the image server when that condition is not true.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteImages, fonts and cross-origin content
Why images disappear
An image hosted on another origin is subject to normal browser security rules. If the response lacks an appropriate Access-Control-Allow-Origin header, the browser may prevent html2canvas from reading it, or may taint the resulting canvas so pixel export fails.
Fixes that are actually valid
- Serve the image from the same origin as the page.
- Configure the image host to send a suitable CORS response header, then use
useCORS: true. - Fetch the resource through a properly configured proxy that returns it in a form the page is allowed to use.
Neither useCORS nor a proxy is a method for evading browser policy. If you do not control the remote host, replacing the image or omitting it may be the only dependable choice. Web fonts and late-loading assets should also be ready before capture; otherwise text can fall back to a different font or appear before the final layout settles.
Why the canvas differs from the live page
Differences are expected when a CSS feature is unsupported or only partly implemented. Complex filters, blending, generated content, form controls, pseudo-elements, SVG details and browser-native widgets can require a minimal test case to identify the exact limitation. Compare a reduced element against the project’s supported-features list rather than assuming a browser screenshot should match.
For a true view of browser-rendered pixels, use an actual browser screenshot mechanism instead. The official FAQ points extension authors to native extension screenshot APIs and server-side users to Puppeteer or Playwright driving a headless browser. Those tools solve a different problem: they control a browser and capture its rendered view, while html2canvas runs in the page and reconstructs a canvas.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Long pages, blank output and performance limits
Canvas dimensions are limited by the browser and device. A very tall report can therefore be blank, clipped or partially painted. There is no universal safe maximum: limits vary by browser, operating system, GPU and available memory.
Rank #3
- Capture a smaller element or split a long document into sections.
- Lower
scalebefore increasing dimensions. - Use
windowWidthandwindowHeightthat match the element’s scroll dimensions when a full element capture is required. - Remove unnecessary images and animations from the capture.
- Test on the least capable browser and device you support.
Large canvases consume memory both while painting and while encoding. Prefer toBlob() over a large data URL, release object URLs after download, and avoid running several full-page captures concurrently.
Browser and runtime support
The current official guide describes modern evergreen browsers, including Chrome or Chromium-based browsers, Firefox and Safari. html2canvas depends on window, document and computed styles, so it is client-side browser software, not a Node.js renderer.
Node.js applications
Importing html2canvas in a plain Node.js process will not provide the DOM and browser APIs it needs. For server-side screenshots, the FAQ names Puppeteer or Playwright with a headless browser. If your server receives a URL and must capture the page as a user would see it, use one of those browser-controlled approaches or a screenshot API.
Browser extensions
For an extension, the FAQ recommends the browser’s native extension screenshot APIs as the more reliable choice for that context. They capture browser-rendered pixels rather than rebuilding the page from DOM information.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF, without adding html2canvas to the page:
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 documentation for all parameters. The equivalent Python and Node.js requests are:
Rank #4
- 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
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}`);
Before capture, ScreenshotNeo accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Every plan includes features such as full-page lazy-image loading, CSS-selector element capture, device presets, custom CSS and JavaScript, waits, request blocking, cookies and headers, geolocation, PDFs, signed links, async webhooks, bulk capture and a usage API. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Create a free ScreenshotNeo account to try those 1,000 monthly screenshots without a card.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting checklist
“document is not defined” or import errors
You are running browser-only code in Node.js, during server-side rendering, or before the page environment exists. Move the call into client-side code after the target element is mounted, or use Puppeteer, Playwright or a screenshot API on the server.
Remote images are missing
Inspect the image response headers. Add useCORS: true only after the host sends a suitable CORS header; otherwise use same-origin assets or a properly configured proxy.
toDataURL() throws a security error
The canvas is tainted by inaccessible image data. Fix the resource’s CORS configuration or remove that asset; html2canvas cannot override the browser’s rule.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Styles or controls look different
Reduce the page to the smallest element that shows the difference, check whether the CSS property is supported, and replace unsupported effects with simpler styles for the export version.
The result is blank or cut off
Reduce the capture area or scale, split long content, and set viewport dimensions to the element’s scroll dimensions. Test on the target browser and device because canvas limits differ.
Best Value
The capture is inconsistent
Wait for data, fonts and images; stop animations; capture one element at a time; and avoid changing layout while html2canvas is walking the DOM.
FAQ
Does html2canvas take a screenshot of the screen?
No. It reconstructs a canvas from DOM and styles, so it can differ from pixels visible in the browser.
Is html2canvas suitable for a server-rendered image service?
Not by itself. It requires browser APIs; use a headless browser or a screenshot service for server-side work.
Can it bypass a CAPTCHA or cross-origin restriction?
No. Browser security and the target site’s bot controls still apply.
Where can I see a visual comparison?
The project’s official examples page provides a side-by-side HTML/CSS editor and html2canvas output for experimenting with supported and unsupported behavior.
Frequently Asked Questions
Can I capture an element that is currently off-screen?
html2canvas can render an element outside the visible viewport, but the resulting dimensions still must fit browser canvas limits. For very large content, split the capture or reduce its scale.
Recommended Free Tools
Should I use the scoped @html2canvas package instead?
The available package listings do not establish that it is an official replacement for html2canvas. Follow the current project installation guidance and verify release and maintainer information before changing package names.
The Bottom Line
Use html2canvas when you need a client-side, DOM-based rendering of a manageable element and can accept differences from a real browser screenshot. Use a headless browser, extension API or ScreenshotNeo when you need browser-pixel fidelity, server-side operation or a managed capture workflow.
Quick Recap
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.

