HTML-to-image failures usually have a specific cause: html2canvas reconstructs pixels from the DOM rather than taking a native screenshot, browser security blocks some resources, the page is captured before it is ready, or the requested canvas exceeds an environment limit. Diagnose in that order. If you need browser-level fidelity or server-side rendering, use a real-browser capture service or automation instead of trying to force html2canvas to support features it cannot implement.
Start by identifying what is actually rendering the image
First determine whether your code runs html2canvas in a browser or a real browser controlled by Puppeteer, Playwright, or another automation tool. html2canvas depends on browser APIs and is not intended to run directly in Node.js (official getting-started guidance). A Node process that imports html2canvas without a browser environment will fail before page-specific debugging begins.
Also set the right expectation. html2canvas “builds the screenshot based on the information available on the page” and does not make an actual screenshot (documentation). It walks the DOM, reads styles and resources, and paints its own canvas. The result can therefore differ from the browser’s visible pixels.
When a different engine is the correct fix
Every CSS property must be implemented individually, so html2canvas will never have complete CSS support (FAQ). If a required effect is unsupported, changing width, height, or CORS settings will not reproduce it. For server-side, browser-faithful output, the FAQ points to Puppeteer or Playwright. Those tools still require a working browser installation, fonts, sandbox configuration, and host resources; Puppeteer’s troubleshooting guide covers missing browsers and cache setup.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Why are images missing?
Check the original image before changing options
- Open each image URL directly and confirm it returns a successful response.
- Inspect the page in the same browser context used for capture. A URL that fails, redirects, requires authentication, or is blocked by a content policy cannot be painted.
- For a different origin, inspect the response headers. The image server must permit the requesting origin with an appropriate CORS header.
When the server permits CORS, set useCORS: true. If it cannot, use a server-side proxy as documented in the configuration reference and the FAQ. A JavaScript option cannot override browser policy.
Do not confuse allowTaint with permission
allowTaint concerns whether cross-origin pixels may taint the canvas. It does not make a tainted canvas readable for ordinary export. If your call to toDataURL() or toBlob() throws a security error, remove or proxy the cross-origin resource and ensure valid CORS rather than relying on this flag.
Make resource failures visible
Use the documented onError callback to log failed resources, and set an appropriate imageTimeout. These options do not repair a bad URL or missing CORS header, but they turn silent omissions into actionable logs. Wait for your application’s own readiness condition—such as a data request completing, an image’s decode() promise resolving, or a web font becoming available—before invoking html2canvas. There is no universal readiness switch that knows when every application is finished.
Why is an iframe missing?
Same-origin iframe documents can be recursively rendered. A cross-origin iframe cannot be inspected because browser security prevents access to its document; a sandboxed iframe without allow-same-origin has the same practical limitation (documentation).
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
- Same origin: capture the frame after its content is loaded and verify that the frame is not being replaced asynchronously.
- Cross origin: capture the framed page separately from an environment that can access it, or have the frame’s owner provide a same-origin or server-side rendering path.
- Sandboxed: review the sandbox flags; adding a library option cannot grant DOM access that the browser withholds.
Why does CSS look different from the live page?
Compare the failing property with html2canvas’s supported behavior, not merely with the browser’s appearance. Unsupported or partially supported CSS can affect gradients, filters, blending, pseudo-elements, transforms, complex layout, and other effects. Reduce the page to a small reproduction and remove one property at a time. If the difference disappears when a property is removed, replace it with a supported equivalent or switch to a real-browser screenshot.
Remember that the capture is based on computed DOM information. Browser-only painting details, extensions, platform font rasterization, and content that has not yet entered the DOM will not necessarily match a native screenshot.
Fix blank, clipped, blurry, or wrongly cropped output
Blank or partly rendered canvas
Browsers impose canvas dimension limits that vary by browser, operating system, device, and graphics implementation. Exceeding a limit can produce a blank or partially rendered result without a useful exception (FAQ). Do not treat any published dimension as a universal threshold.
- Measure the target element’s
scrollWidthandscrollHeight. - Set
windowWidthandwindowHeightto dimensions appropriate for that content, as the FAQ suggests. - Capture a smaller region or split a very tall document into sections.
- Lower
scaleif the resulting pixel dimensions are excessive.
Wrong crop or viewport-dependent layout
The options x, y, width, and height define the capture box. windowWidth and windowHeight define the virtual viewport used while rendering; changing them can activate different media queries. Confirm that the element is in view and that no responsive breakpoint changes its layout.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
Blurry output
scale controls output resolution. The examples show setting it to window.devicePixelRatio for sharper output (examples):
const canvas = await html2canvas(element, {
scale: window.devicePixelRatio,
useCORS: true
});
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
Higher scale increases memory use and canvas dimensions. If a sharp capture becomes blank, reduce scale or divide the job into smaller captures.
A repeatable diagnostic procedure
- Record the environment: browser and version, operating system, capture library, target URL, viewport, and whether execution is local or server-side.
- Capture a plain local element: use a short same-origin page with text and one local image. This separates installation problems from page-specific resources.
- Verify readiness: wait for application data, images, and fonts; log the target’s dimensions immediately before capture.
- Add remote resources one at a time: inspect CORS responses and enable
useCORSonly where the server supports it. - Inspect frames: classify each iframe as same-origin, cross-origin, or sandboxed before expecting its contents.
- Test CSS features: remove suspicious properties in a minimal reproduction and check whether the mismatch remains.
- Control geometry: explicitly set viewport, crop coordinates, dimensions, and scale; compare output dimensions with the requested values.
- Stress-test size: lower scale or split the page if large captures are blank or truncated.
- Change architecture when appropriate: use Puppeteer or Playwright for a real-browser shot, or a hosted screenshot API when maintaining browser infrastructure is not practical.
Symptom-to-check map
| Symptom | First checks | Supported explanation |
|---|---|---|
| Remote image absent | URL response, origin, CORS header, useCORS or proxy |
Cross-origin restrictions and documented CORS/proxy paths (FAQ; configuration) |
| Export throws or canvas is unreadable | Whether cross-origin pixels were drawn and canvas became tainted | Browser policy limits access to tainted canvases |
| CSS differs | Whether the property is implemented by html2canvas | DOM reconstruction has incomplete CSS coverage |
| Iframe missing | Same-origin and sandbox status | Cross-origin documents are inaccessible; same-origin frames are supported |
| Blank or clipped | Canvas size, scroll dimensions, viewport, browser/device limits | Oversized canvases may fail silently and limits vary |
| Blurry or wrong crop | scale, crop box, viewport options |
These configuration controls affect resolution and geometry |
| Intermittent resources | onError, timeout, CORS/proxy, app readiness |
Loading and callback options expose failures but do not fix server responses |
Or skip the browser setup
ScreenshotNeo is a hosted website screenshot API and MCP server. It drives capture for you and removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; the response identifies the page verdict and billing status in headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
Use the API with one GET request (see the ScreenshotNeo documentation):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in 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)
And 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}`);
You can still control full-page lazy loading, CSS-selector elements, dark mode, device and viewport, retina scale, PDF settings, custom CSS or JavaScript, clicks, waits, blocked requests, headers, cookies, user agent, timezone, geolocation, transparency, resizing, caching, signed links, asynchronous webhooks, bulk capture, and usage reporting. Every feature is on every plan. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
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
Performance, reliability, and cost considerations
- Client-side html2canvas: no server browser to install, but it consumes the user’s CPU and memory and is constrained by that browser’s security policy and canvas limits.
- Puppeteer or Playwright: closer to visible browser output and suitable for server jobs, but you maintain browser binaries, fonts, sandbox settings, concurrency, and cache storage.
- Hosted capture: shifts browser operations to a service. Check its URL access, authentication, data handling, retention, geography, and failure reporting before sending private pages.
- Large pages: reduce scale, capture sections, wait only for required resources, and avoid unnecessary third-party assets. These choices reduce memory pressure and timeout risk regardless of engine.
Common errors and targeted fixes
“Document is not defined” or similar Node errors
html2canvas is being run outside a browser. Move the call into browser code or use a browser automation framework for server execution.
“Tainted canvases may not be exported”
A cross-origin resource was drawn without a readable CORS response. Configure the asset server, use a proxy, or remove the resource; allowTaint does not make export readable.
Capture resolves but content is incomplete
The application was still loading, a resource timed out, or a frame/resource is inaccessible. Add readiness checks, inspect onError, increase imageTimeout where appropriate, and verify origin policy.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsOnly the top portion appears
The target or canvas is too large for the runtime, or the capture dimensions describe the viewport rather than the full element. Compare scrollHeight with requested height, match window dimensions, lower scale, or split the capture.
Best Value
Looks right locally but fails on the server
Compare browser binaries, installed fonts, viewport, device scale factor, network access, sandbox permissions, and cache paths. The Puppeteer troubleshooting guide documents environment-specific browser setup failures.
Frequently Asked Questions
Can html2canvas capture a page exactly as Chrome displays it?
No. It reconstructs an image from DOM information, so unsupported CSS and browser-only painting can differ from a native screenshot.
Does setting useCORS bypass cross-origin restrictions?
No. It works only when the remote server supplies an appropriate CORS response; otherwise use a proxy or another capture architecture.
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 reinstallShould I increase scale to fix a blank canvas?
Usually not. Higher scale improves resolution but increases pixel dimensions and memory pressure; reduce scale or split the capture when size limits are suspected.
What should I use for server-side screenshots?
Use a real-browser tool such as Puppeteer or Playwright, or a hosted service such as ScreenshotNeo when you do not want to maintain browser infrastructure.
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.

