Recommended Free Tools
If an image appears on your page but disappears from an html2canvas capture, first check whether the image loaded and whether its final URL is cross-origin. With the default allowTaint: false, html2canvas skips images that would taint the canvas. Set useCORS: true only when the image server grants your page permission through CORS; otherwise, use a trusted same-origin proxy. Then check that you capture the correct parent, wait for image loads, and rule out clone exclusions, visibility, CSS support, and viewport clipping.
Why an image inside a child div can disappear
html2canvas does not take a literal screenshot of the browser’s already-painted pixels. It builds a representation of the DOM and renders supported CSS and content into a canvas. As a result, an image can be visible in the live page yet absent in the output because its request failed, its origin is not permitted for canvas use, the cloned element was excluded or changed, or a style/layout feature is not rendered as expected. The project describes the library as taking screenshots of webpages or parts of them in the user’s browser, but its output depends on what the library implements. html2canvas documentation
Being inside a child div is not by itself a reason for an image to fail. Confirm that the element you pass to html2canvas is the parent containing the child, and then trace the image request and cloned DOM.
Start by checking the target and image load
Run this in the page after it has rendered. It reports how many image elements are descendants of the target, the browser-selected URL, and whether each image has decoded dimensions.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
const target = document.querySelector('#capture');
console.log(target, target?.querySelectorAll('img').length);
for (const img of target.querySelectorAll('img')) {
console.log(img.currentSrc || img.src, img.complete, img.naturalWidth, img.naturalHeight);
}
If target is null, fix the selector or wait until the element exists. If an image’s naturalWidth is zero, html2canvas cannot render a successfully loaded image because the browser has not obtained usable image data. Open Developer Tools and inspect Network for that image: note its status, redirects, final request URL, and response headers. Check Console for blocked requests or decoding errors too.
Make sure you pass the containing element, rather than a sibling or a child that does not include the image:
const target = document.querySelector('#capture');
const canvas = await html2canvas(target);
Wait until image requests have completed
A capture started while a child image is still loading can race the browser. Waiting for the document’s image elements to either load or error avoids capturing too early. This waits for completion, not success: an image that errors still needs a separate fix.
await Promise.all(
[...document.images].map(img =>
img.complete ? Promise.resolve() : new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
})
)
);
const target = document.querySelector('#capture');
const canvas = await html2canvas(target, { logging: true });
For a page where only one capture region matters, you can apply the same wait to target.querySelectorAll('img') instead of every image in the document. html2canvas documents an imageTimeout default of 15000 milliseconds; set a different timeout if appropriate, or use imageTimeout: 0 to disable that timeout. A longer timeout cannot repair a failed request or grant CORS permission. html2canvas configuration
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsFix cross-origin image failures
Cross-origin restrictions are a frequent cause of visible images disappearing from a canvas. When allowTaint is false (the default), html2canvas avoids drawing an image that would make the resulting canvas tainted. A tainted canvas cannot be read back normally. html2canvas FAQ
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
When the image server supports CORS
Ask the image host to return an appropriate Access-Control-Allow-Origin response header for the origin running your page. Then request CORS mode in html2canvas while keeping tainting disallowed:
const target = document.querySelector('#capture');
const canvas = await html2canvas(target, {
useCORS: true,
allowTaint: false,
logging: true,
onError: error => console.warn('html2canvas resource failed:', error)
});
useCORS: true tells html2canvas to attempt a CORS-enabled image request. It does not add permission to the response: the image server must supply the header. The allowed origin must match the requesting page’s origin or use an applicable wildcard policy; credentials and server policy can affect which header is valid. If the server is not yours, you may need its operator to configure access or choose another delivery route. See the project’s CORS guidance in its FAQ.
When you cannot change the image server
Proxy the image through a server you control on the same origin as the page, and configure the proxy to fetch only permitted resources and return safe image responses. html2canvas supports a proxy option:
Free tools Windows power users keep installed
One-click scans. No signup required.
const target = document.querySelector('#capture');
const canvas = await html2canvas(target, {
proxy: 'https://your-origin.example/image-proxy',
logging: true
});
The configured endpoint must actually implement the proxy behavior; this option is not itself a proxy service. The html2canvas getting-started material describes proxying remote image resources for same-origin-safe use. html2canvas proxy documentation Avoid an untrusted public proxy, especially for private or authenticated images: URLs, headers, and image contents may be exposed, and a poorly controlled proxy can create server-side request risks. Prefer a narrowly scoped endpoint that validates allowed hosts and resource types.
When a local-looking URL redirects to a CDN
A URL that begins on your site may return a redirect to a different host. Inspect the final URL in Network, not just the value of img.src. A maintainer issue documents a case where a same-origin-looking URL redirected to a CDN and the current useCORS decision did not apply as expected to the final cross-origin request. html2canvas issue 3020
Rank #3
Where possible, serve the final image URL directly with suitable CORS headers, avoid the redirect, or proxy the resource through your own origin. Do not assume that setting useCORS fixes a redirect chain automatically.
Check whether the cloned element is excluded or altered
html2canvas works from a cloned document. Inspect whether the child image or an ancestor is removed, ignored, hidden, or restyled before rendering:
- Remove
data-html2canvas-ignorefrom the image or its ancestors if the image should appear. - Check whether
ignoreElementsreturns true for the image or a containing element. - Inspect any
onclonecallback for code that removes the node or changes its source, dimensions, or display styles. - Confirm that the target is attached to the document, has nonzero dimensions, and is not
display: noneor otherwise hidden in the captured state.
The library documents the ignore attribute, ignoreElements, and onclone in its configuration reference. html2canvas configuration Use onclone to inspect the rendered copy without changing the live page:
await html2canvas(target, {
onclone: clonedDoc => {
const clone = clonedDoc.querySelector('#capture img');
console.log('clone image', clone?.src, clone?.getBoundingClientRect());
}
});
If the clone lacks the image, trace the selector and exclusion logic. If it has the image but no useful dimensions, investigate the cloned styles and layout.
Test CSS support and capture dimensions
A browser may display CSS that html2canvas does not reproduce because the library implements CSS rendering itself. Temporarily simplify the child’s styles and recapture. In particular, test without complex positioning, transforms, clipping, masks, filters, or background effects. If the simplified image appears, reintroduce styles one at a time to identify the unsupported or interacting feature. The project’s documentation explains this DOM-and-CSS rendering limitation. html2canvas documentation
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
Also distinguish a missing image from an image outside the captured area. For a tall or horizontally clipped target, use a viewport matching its scroll dimensions:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →const canvas = await html2canvas(target, {
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight
});
Use width, height, x, y, scrollX, and scrollY when you need to control the capture area or scroll position. These options can address clipping, but they cannot fix a failed image request or CORS denial. html2canvas configuration
Common symptoms and fixes
| Symptom | Likely cause | What to do |
|---|---|---|
| Image box is blank and the image host differs from the page host | Cross-origin image would taint the canvas | Use useCORS: true only if the host grants CORS; otherwise use a controlled same-origin proxy or host the asset yourself. |
Console reports no Access-Control-Allow-Origin header |
The remote server did not grant permission to the page origin | Configure the server’s CORS response, use an authorized proxy, or choose a source you can serve with suitable headers. |
| The request starts on your site but ends at a CDN | A redirect changes the final resource origin | Inspect the final URL; provide CORS there, avoid the redirect, or proxy the resource. |
| The child is missing only in the capture | Clone exclusion, hidden/zero-size layout, or unsupported CSS | Inspect the clone; check the ignore attribute, callback, visibility, dimensions, and simplified styles. |
| The whole output is blank or cut off | Incorrect capture viewport or canvas dimensions | Set window and capture dimensions deliberately and test a smaller region. |
The image has naturalWidth === 0 |
The browser has not loaded or decoded a usable image | Fix the request first by checking its status, redirects, URL, and Console errors. |
A reliable debugging order
- Confirm the target. Select the actual parent and verify that its descendant image count is nonzero.
- Confirm browser loading. Check
complete,naturalWidth, Network status, redirects, and response headers. - Remove timing uncertainty. Wait for image load/error events, then capture with logging enabled.
- Resolve origin policy. Use server CORS when available; otherwise use a trusted, controlled proxy.
- Inspect the clone. Check ignore rules, callback changes, visibility, attachment, and nonzero dimensions.
- Simplify layout. Remove complex CSS temporarily and make the capture viewport large enough for the target.
This order separates a network problem from a canvas policy issue and from a clone/layout problem; changing random CSS or repeatedly toggling options obscures which one caused the failure.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need a clean website capture rather than an html2canvas canvas built from your page’s DOM, ScreenshotNeo is a website screenshot API and MCP server for developers. It captures the URL in a browser and returns PNG, JPEG, WebP, or PDF. It is useful when you do not control a page’s image host or want to avoid building a capture pipeline. For html2canvas-specific issues such as DOM behavior in your application, use the debugging steps above.
One GET request returns a screenshot. This cURL example saves a WebP capture of Stripe:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace YOUR_API_KEY with your key and the URL with the page you want. See the ScreenshotNeo API documentation for request parameters and response details.
- Cookie/consent banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off.
- Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status.
- An MCP server exposes
take_screenshot,get_page_info, andcapture_pdfto Claude, Cursor, and other MCP clients. - The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
Frequently Asked Questions
Does adding `crossorigin=”anonymous”` to an image always fix html2canvas?
No. The image server must still return a suitable `Access-Control-Allow-Origin` header. Without that permission, the browser blocks CORS access.
Can I set `allowTaint: true` to force the image into the capture?
That may allow tainting behavior, but a tainted canvas cannot be read back normally. For image output, use an origin-approved resource or a controlled proxy instead.
Why does html2canvas output differ from what I see in the browser?
It reconstructs the page from DOM and supported CSS rather than copying the browser’s painted pixels, so unsupported CSS and resource restrictions can produce differences.
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.

