If html2canvas produces a blank export for a base64 image or inline SVG, first determine whether the resource is truly a data: URI or a normal URL that redirects elsewhere. Then wait for images to finish loading, keep the canvas untainted with allowTaint:false, enable useCORS:true only when the final response sends the required CORS header, and use same-origin hosting or a trusted proxy when it does not. Inline SVGs additionally need valid encoding, escaping, and non-zero intrinsic dimensions.
What html2canvas is (and why a live image can disappear)
html2canvas does not take a browser screenshot. It walks the DOM, rebuilds a scene, downloads image resources, and paints an approximation onto a canvas. Unsupported CSS, browser differences, and resource-security rules can therefore make the export differ from the page you see. A successful on-screen render is not proof that toDataURL() will succeed.
The browser marks a canvas as tainted when script draws an image fetched from another origin without CORS approval. A tainted canvas cannot be read with toDataURL() or similar APIs. html2canvas cannot bypass that browser policy.
1. Classify the failing URI
Inspect the actual src attribute and every CSS background-image used by the captured node.
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 minute#1 Best Overall
- Raster data URI:
data:image/png;base64,..., JPEG, GIF, or WebP. It is embedded in the document and normally has no network CORS request. - SVG data URI:
data:image/svg+xml,...or a base64-encoded SVG. Encoding, quoting, intrinsic dimensions, CSP, and nested resources all matter. - Normal URL: an
https://or relative URL. It may be cross-origin even when the page URL looks same-origin, because redirects can send it to a CDN. - Nested SVG resource: an SVG that contains an
<image>, external stylesheet, font, or filter URL. The outer SVG being a data URI does not make those inner requests safe.
2. Check the resource the browser actually fetched
- Open DevTools and select the Network panel.
- Reload the page, then find the image request (or the request made by an SVG’s nested resource).
- Follow redirects and record the final URL. Check the final response headers, not only the original URL.
- For a cross-origin image, verify that the final response includes an
Access-Control-Allow-Originvalue that permits the page’s origin (or the appropriate wildcard policy for a non-credentialed request). - Look for a 404, blocked request, certificate error, CSP violation, or a response that is HTML instead of an image.
If a normal URL redirects from your site to a CDN, html2canvas may decide too early that it is same-origin and omit the CORS mode. A documented project issue reports this redirect edge case; it is not a guarantee that every release behaves identically. Prefer a stable final URL, configure CORS on the CDN, or proxy the asset through an origin you control.
3. Use the options that match your security situation
| Situation | Settings | Why |
|---|---|---|
| Export must be readable and all images are same-origin or embedded | allowTaint:false |
Prevents an unsafe image from silently producing an unreadable canvas. |
| Remote server supports CORS | allowTaint:false, useCORS:true |
Requests images in a way that can be approved by the final response’s CORS header. |
| Remote server cannot add CORS | allowTaint:false, proxy:"/your-proxy" |
A same-origin or trusted proxy fetches the image and returns it from your origin. |
| You only need to display pixels, not export them | allowTaint:true may render |
The canvas can be painted, but reading it with toDataURL() remains unsafe. This is not a fix for exports. |
The documented html2canvas defaults are allowTaint:false, useCORS:false, proxy:null, and imageTimeout:15000. Set options deliberately rather than assuming a flag can override browser policy.
4. Wait for images before capturing
Calling html2canvas immediately after changing src, inserting a data URI, or revealing a lazy image can race the image decoder. Wait for every image to finish loading or fail, then call html2canvas.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
const node = document.querySelector('#capture');
await Promise.all([...node.querySelectorAll('img')].map(img =>
img.complete
? img.decode?.().catch(() => {})
: new Promise(resolve => {
img.onload = img.onerror = resolve;
})
));
const canvas = await html2canvas(node, {
allowTaint: false,
useCORS: true,
imageTimeout: 15000,
logging: true,
onError: err => console.error('html2canvas resource error', err)
});
const png = canvas.toDataURL('image/png');
Use useCORS:true in this example only when the final image response is CORS-enabled. Otherwise remove it and use same-origin hosting or configure proxy. For CSS backgrounds, wait for the stylesheet and resource requests as well; waiting only for <img> elements does not guarantee that a background image is ready.
Free tools Windows power users keep installed
One-click scans. No signup required.
5. Repair SVG data URIs
Encode consistently
Choose either percent-encoding or base64 and apply it consistently. In a non-base64 URI, characters such as #, ?, quotes, parentheses, angle brackets, and whitespace can terminate a CSS URL or alter an attribute. Quote CSS URLs and escape characters required by the context. A malformed URI can look like a transparent or missing image even though the SVG markup itself is valid.
Give the SVG usable dimensions
Set explicit width and height, and provide a matching viewBox. An SVG with a zero or missing intrinsic height can reach the image-pattern code with no drawable area; a reported project issue shows this failure mode. CSS dimensions on the surrounding element do not always supply intrinsic dimensions to the decoded image.
Rank #3
Audit nested content
An SVG can reference external images, stylesheets, fonts, or filters. Each nested request must load successfully and satisfy CORS rules. For a portable export, inline those resources or serve them from the same origin. Test the SVG by opening its decoded URL directly and by placing it in a minimal page before adding transforms or filters.
Account for browser and CSP differences
Safari and other browsers have had edge cases involving escaped non-base64 SVG data URIs and canvas tainting. A restrictive Content-Security-Policy must permit the scheme you actually use in img-src (for example, data: or blob:). A policy that blocks the URI can produce a missing image before html2canvas runs.
6. Reduce the problem to a minimal case
- Create a same-origin page containing one ordinary PNG and one failing URI.
- Capture only that element with
logging:true. - Replace the failing SVG with a simple rectangle and explicit dimensions.
- Add CSS backgrounds, transforms, masks, filters, and nested resources one at a time.
- Test the same case in each supported browser, with special attention to Safari.
This sequence separates URI parsing and intrinsic-size bugs from CORS, CSP, timing, and unsupported-CSS problems. Once the minimal case works, reintroduce the page’s resources in small groups.
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
Common symptoms and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Blank image or missing background | Malformed data URI, image not decoded, CSP block, or unsupported CSS | Inspect the URI, wait for decoding, check console/CSP messages, and test a minimal page. |
SecurityError from toDataURL() |
Canvas was tainted by a cross-origin image without CORS approval | Keep allowTaint:false; enable useCORS:true only with a correct final response header, or use same-origin hosting/proxy. |
useCORS:true changes nothing |
The server omits CORS, a redirect lands on a CDN without CORS, or the request is blocked before loading | Inspect the final response, configure the CDN, use its stable URL, or proxy the asset. |
| SVG throws a pattern or zero-size error | Missing or zero intrinsic dimensions | Add positive width/height and a valid viewBox. |
| Works in Chrome but not Safari | Browser-specific SVG data-URI or tainting behavior | Try base64, simplify escaping, inline nested resources, set dimensions, and retest under Safari’s CSP. |
| Intermittent blank exports | Capture starts before lazy images, fonts, or backgrounds finish | Wait for image load/decode, use a selector or delay appropriate to your page, and keep diagnostic logging enabled. |
Performance, privacy, and reliability choices
- Same-origin hosting is usually the simplest and fastest, but requires control of the asset host.
- CORS avoids a relay, yet every redirect and cached response must preserve the correct header. Credentialed requests require a compatible, non-wildcard policy.
- A proxy handles servers you cannot change, at the cost of an extra hop, cache design, privacy review, and protection against proxying arbitrary private URLs.
- Inlining removes a network dependency for small assets, but increases HTML size and does not solve nested external resources automatically.
- Large full-page captures consume memory. Capture a smaller element, reduce scale, or split long documents when the browser struggles.
Keep logging enabled while diagnosing, then turn it off for normal operation. Set imageTimeout to a value appropriate for your network rather than treating 15 seconds as a universal guarantee.
Or skip the browser setup
If you need a server-side screenshot rather than a DOM reconstruction, ScreenshotNeo accepts one GET request and returns PNG, JPEG, WebP, or PDF. It removes cookie/consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Read the option reference in the ScreenshotNeo documentation. cURL:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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}`);
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Create a free ScreenshotNeo account.
Best Value
Frequently Asked Questions
Can a data URI still be blocked by CSP?
Yes. The policy must allow the URI scheme used by the image, such as data: or blob:, in the applicable img-src directive.
Should I set allowTaint to true to make the export work?
Only when you do not need to read the canvas. A tainted canvas may display pixels but cannot safely produce a data URL.
Does html2canvas support every CSS property?
No. It reconstructs supported DOM and CSS rather than capturing the browser compositor, so unsupported properties can differ even when all images load.
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 →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.

