An “Uncaught TypeError” is not one html2canvas error. The useful fix starts with the complete exception text and stack trace, then follows the failing operation: browser runtime, resource loading, DOM/CSS cloning, canvas geometry, or export. Record the browser and version, html2canvas version, element being captured, and every option before changing code. Without that information, blaming CORS, CSS, or canvas size is guesswork.
What html2canvas is—and what it is not
html2canvas runs in a browser and reconstructs an image from the target element’s DOM and CSS. It does not take a native screenshot of the rendered tab. The library reads the document, clones relevant nodes, loads resources it is permitted to read, and paints an approximation onto a canvas. Its output therefore depends on browser APIs, same-origin rules, and which CSS properties the library implements.
The html2canvas project FAQ states: “Every CSS property must be manually implemented to render correctly, so html2canvas will never have full CSS support.” An unsupported style can produce an incorrect or blank result without throwing a TypeError, so a thrown exception should be diagnosed separately from visual fidelity.
1. Capture the exact failure before changing anything
Open DevTools, reproduce the capture once, and save:
Recommended Free Tools
#1 Best Overall
- The entire “Uncaught TypeError” message, including the expression that is undefined or not a function.
- The complete stack trace and the first frame in your own code.
- Browser name and version, operating system, html2canvas package version, and whether the page is local, deployed, or inside an iframe.
- The selected element’s tag, dimensions, and relevant options such as
useCORS,allowTaint,scale,windowWidth, andwindowHeight.
A generic headline cannot identify a unique throwing expression or a version regression. Do not apply a blanket “upgrade html2canvas” fix; first identify the installed dependency and then check that version’s release information.
2. Verify that the code is running in a browser
html2canvas is client-side code. Calling it directly in Node.js fails because Node does not provide the normal DOM, layout, image, and canvas browser APIs. If your stack trace contains missing window, document, or browser constructors, the runtime is the cause.
Run the capture after the page has loaded, or use a real browser controlled by Puppeteer or Playwright for server-side work. A minimal browser-side call is:
import html2canvas from 'html2canvas';
const element = document.querySelector('#invoice');
if (!element) throw new Error('Cannot find #invoice');
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
If you need a server-generated image, launch Chromium with Puppeteer or Playwright, navigate to the page, and execute this code in the page context—or use the automation library’s native screenshot function. Do not import html2canvas into a bare Node process and expect a DOM to appear.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems3. Separate rendering errors from export errors
Render the canvas first, inspect it, and only then export it. This distinguishes an html2canvas failure from a security exception raised by toDataURL() or another readback API.
const canvas = await html2canvas(document.querySelector('#invoice'), {
logging: true
});
console.log({ width: canvas.width, height: canvas.height });
if (!canvas.width || !canvas.height) {
throw new Error('html2canvas returned an empty canvas');
}
const png = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'invoice.png';
link.href = png;
link.click();
If html2canvas throws before the “canvas dimensions” log, investigate runtime, cloning, resources, and CSS. If the canvas exists but export raises a security error, investigate cross-origin images and tainting; that is not necessarily a TypeError inside html2canvas.
Rank #2
4. Diagnose cross-origin images correctly
Images, fonts, or other resources from another origin must be served with permission for your page to read them. Setting useCORS: true requests CORS-enabled loading; it cannot manufacture an Access-Control-Allow-Origin response on a server that does not send one.
const canvas = await html2canvas(document.querySelector('#gallery'), {
useCORS: true,
imageTimeout: 15000
});
Inspect the image request in DevTools Network and confirm that the response includes a suitable CORS header for your page’s origin. Also check that the image URL is not redirecting to a host with different policy. If you cannot change the image server, use a correctly configured proxy that fetches the image server-side and serves it from an origin your page may read.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →allowTaint is not an export workaround. With the documented default of false, html2canvas avoids resources that would taint the canvas. Allowing taint can let pixels be painted, but a tainted canvas remains unreadable to toDataURL(), toBlob(), and pixel APIs. Fix the server policy or proxy instead.
For a quick isolation test, temporarily replace external images with same-origin or data URLs. If the capture then works, restore resources one at a time and correct the failing response rather than changing unrelated CSS.
5. Reduce the DOM and CSS until the failing node is obvious
Start with a small element instead of the whole page. Remove one complex component at a time—filters, masks, blend modes, transformed containers, embedded frames, custom fonts, and large background images are useful suspects—but do not assume any one property is unsupported until the reduced case demonstrates it.
const canvas = await html2canvas(document.querySelector('.card'), {
onclone: (clonedDocument) => {
const cloned = clonedDocument.querySelector('.animated-widget');
cloned?.remove();
}
});
onclone receives the cloned document, so changes there do not modify the live page. The documented default is null. You can also mark unwanted nodes in the source with data-html2canvas-ignore:
<button data-html2canvas-ignore>Close</button>
Use a minimal reproduction containing one element, one stylesheet, and one resource. If the minimal version succeeds, add components back until one addition reproduces the exception. If it never succeeds, the stack trace and dependency version are more valuable than further random option changes.
6. Check capture coordinates, dimensions, and browser canvas limits
A blank or truncated result can be a geometry problem rather than a TypeError. Compare the requested rectangle with the element’s scroll dimensions:
const element = document.querySelector('#report');
const rect = element.getBoundingClientRect();
console.log({
client: [element.clientWidth, element.clientHeight],
scroll: [element.scrollWidth, element.scrollHeight],
rect: [rect.width, rect.height]
});
For a page whose content extends beyond the viewport, pass dimensions that match the document you intend to capture:
const canvas = await html2canvas(document.querySelector('#report'), {
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight,
scale: 1
});
The official FAQ gives rough, evergreen-browser guidance—not guarantees: Chrome/Chromium about 32,767 pixels maximum dimension and about 268 million pixels maximum area; Firefox about 32,767 pixels maximum dimension and about 472 million pixels maximum area; desktop Safari about 32,767 pixels maximum dimension. iOS Safari limits are lower and depend on device RAM. Values vary by browser, platform, GPU, and operating system.
If a large capture fails, reduce scale, capture sections separately, or lower the requested width and height. A high-DPI scale multiplies both dimensions and therefore multiplies pixel area. Test the same page on the target browser and device; there is no universal canvas threshold.
7. Use the options as diagnostic controls
| Option | Documented behavior | Useful diagnostic |
|---|---|---|
logging |
Defaults to true in the options reference. |
Leave it enabled while reducing the case; its messages show where loading or cloning stops. |
imageTimeout |
Defaults to 15,000 milliseconds. | Increase it only when a slow, permitted image is the demonstrated cause; it does not fix CORS. |
allowTaint |
Defaults to false. |
Do not use it to make a canvas exportable. Correct origin policy instead. |
onclone |
Defaults to null; edits the cloned document. |
Disable animations or remove one problematic node without changing the live UI. |
x, y, width, height |
Capture a region. | Use a small rectangle to determine whether the failure is tied to one area. |
scale |
Controls output resolution. | Set 1 while testing oversized captures, then increase deliberately. |
These settings are versioned library defaults and examples, not universal TypeError remedies. Record the package version whenever you report a result.
Rank #4
8. Choose the capture method that matches the job
- DOM reconstruction: use html2canvas when you need a canvas generated in the page and can accept its CSS and resource constraints.
- Browser extension: use the browser’s native extension screenshot API for a visible-tab capture; the html2canvas FAQ recommends this path.
- Server-side automation: use Puppeteer or Playwright to drive a real browser under Node.js when you need rendered pixels, authenticated navigation, or scheduled captures.
The deciding questions are whether you need DOM reconstruction or native pixels, whether execution must happen in an extension or on a server, whether browser security permits the resources, and whether incomplete CSS support is acceptable.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One request returns a PNG, JPEG, WebP, or PDF, so your code does not need to recreate the page with html2canvas:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →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}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));
See the ScreenshotNeo documentation for authentication and options. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed as clean shots, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Every plan includes the features. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Other available plans are Growth ($15/15,000), Pro ($39/60,000), Scale ($99/250,000), and Business ($249/1,000,000); yearly billing gives two months free. Create a free ScreenshotNeo account to try the 1,000 monthly shots without a card.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common symptoms and targeted fixes
“Cannot read properties of undefined” in html2canvas internals
Reproduce with one element and note the exact stack frame. Check that the call receives a real, attached element, that it runs after the DOM exists, and that the runtime is a browser. Then test the installed version against a minimal page.
The canvas is empty, but no exception appears
Log dimensions, inspect external images, and compare the element’s scroll size with the requested window size. Remove cross-origin resources and reduce the capture area to distinguish resource policy from canvas limits.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteExport fails after a successful render
Treat this as a tainted-canvas/readback problem. Verify CORS headers or use a proxy; do not rely on allowTaint to enable export.
Best Value
Only one component breaks the capture
Use onclone or data-html2canvas-ignore to omit it, then add its children and styles back incrementally. The result may be an unsupported CSS feature rather than a JavaScript TypeError.
The full-page result is cut off
Measure scroll dimensions, set suitable windowWidth and windowHeight, lower scale, or split the page into sections. Browser limits are device-dependent.
Final diagnostic checklist
- Save the exact exception, stack, browser, html2canvas version, element, and options.
- Confirm the call runs in a browser or in Puppeteer/Playwright—not bare Node.js.
- Log canvas dimensions before calling an export API.
- Verify CORS responses for every cross-origin image and avoid treating
allowTaintas a cure. - Reduce the DOM, remove resources and complex styles, and use
oncloneor ignore attributes to isolate the trigger. - Match window dimensions to scroll dimensions and account for browser canvas ceilings.
- Use a native extension API or real-browser automation when the requirement is an actual rendered screenshot rather than DOM reconstruction.
Frequently Asked Questions
Why does the title alone not identify my html2canvas error?
“Uncaught TypeError” describes a JavaScript exception class, not the failed expression. The message and stack trace are required to distinguish runtime, resource, cloning, geometry, and export failures.
Free tools Windows power users keep installed
One-click scans. No signup required.
Can html2canvas capture a cross-origin iframe?
Same-origin policy and iframe access rules still apply. If the document is on another origin, html2canvas cannot freely inspect and reconstruct it; use permitted resources or a browser automation/native screenshot approach.
Should I disable logging in production?
The options reference documents logging as enabled by default. Keep it enabled while diagnosing; disable it only after you have confirmed that the capture is stable and you no longer need diagnostic output.
Is a native browser screenshot always better than html2canvas?
Neither is universally better. Native screenshots reproduce rendered pixels, while html2canvas is useful when you need a canvas generated in the page and can accept its DOM, CSS, and security constraints.
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.

