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 errorsonrendered no longer runs in current html2canvas releases because that callback was removed. The modern API returns a Promise<HTMLCanvasElement>, so put your code in .then() or use await:
html2canvas(document.querySelector('#capture')).then(canvas => {
document.body.appendChild(canvas);
});
If that still fails, verify the version your application actually loads, then check Promise errors, cross-origin images, unsupported CSS, and canvas-size limits.
Why onrendered stopped working
Older html2canvas examples (0.4 and earlier) accepted an onrendered option. The project’s rewritten API removed that option as a breaking change. Calling it today does not invoke your callback; html2canvas ignores the unknown option and returns a Promise instead.
The rendering call is asynchronous. This code is therefore wrong even without onrendered:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
const canvas = html2canvas(document.querySelector('#capture'));
console.log(canvas.toDataURL()); // canvas is a Promise, not an HTMLCanvasElement
Wait for the Promise to resolve before appending, exporting, reading dimensions, or passing the canvas to another function.
The direct fix: replace the callback with a Promise handler
Using .then()
const element = document.querySelector('#capture');
html2canvas(element).then(canvas => {
document.body.appendChild(canvas);
});
The callback parameter is the completed HTMLCanvasElement. Any operation that needs the rendered image belongs inside this handler.
Using async and await
async function renderCapture() {
const element = document.querySelector('#capture');
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
}
renderCapture();
Use await only inside an async function. If you need to handle a failure, surround it with try/catch.
Exporting the result
async function downloadCapture() {
const element = document.querySelector('#capture');
const canvas = await html2canvas(element);
const imageUrl = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = imageUrl;
link.download = 'capture.png';
link.click();
}
downloadCapture();
Calling toDataURL() before the Promise resolves is a common reason migration attempts fail.
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 minuteRank #2
Confirm which html2canvas version is loaded
First inspect the dependency that builds your application, not just the example code you copied. Legacy snippets can remain in documentation, blog posts, or old internal components after the project has moved to the Promise-based API.
- Run
npm ls html2canvas(or inspect the equivalent dependency entry in your package manager). - Check the lockfile to see the resolved version, especially when multiple packages can install html2canvas.
- Inspect the browser’s loaded JavaScript bundle or Network panel if a CDN script or separately bundled copy may be overriding your dependency.
- Make sure the code path you are testing imports the same copy whose version you checked.
If your application deliberately uses a 0.4-era build, its callback-based examples may still match that build. For the rewritten API and current releases, migrate to the Promise pattern rather than adding another onrendered option.
Make failures visible instead of silently losing them
Promise rejection handling
html2canvas(document.querySelector('#capture'))
.then(canvas => {
document.body.appendChild(canvas);
})
.catch(error => {
console.error('html2canvas failed:', error);
});
try/catch with await
async function renderSafely() {
try {
const canvas = await html2canvas(document.querySelector('#capture'));
return canvas;
} catch (error) {
console.error('Unable to render the element:', error);
return null;
}
}
renderSafely();
Read the browser console when the rejection occurs. A missing callback and a rejected Promise are different problems: the first is an API-version mismatch, while the second usually involves an image, browser security policy, unsupported content, or resource limits.
Cross-origin images can break export even after the callback fix
html2canvas reconstructs a canvas from the DOM. Images loaded from another origin are subject to the browser’s same-origin and CORS rules. The Promise can resolve while the canvas is unusable for reading, or an external image can be omitted, depending on the resource and response headers.
Check the failing resource
- Open the browser console and identify the image or font request that reports a CORS or security error.
- Verify that the image server sends an appropriate
Access-Control-Allow-Originresponse for your page. - Use URLs that are actually reachable from the browser, rather than URLs that work only from your server.
- Test the page with external images removed. If the capture then works, the problem is resource policy rather than
onrendered.
Ask html2canvas to attempt CORS loading
html2canvas(document.querySelector('#capture'), {
useCORS: true
}).then(canvas => {
document.body.appendChild(canvas);
});
useCORS requests CORS-enabled loading; it cannot override a server that does not grant access. A proxy option is also available for cross-origin images when your deployment provides a suitable proxy. Browser policy still controls whether the resulting canvas can be read.
Do not expect a pixel-perfect browser screenshot
html2canvas creates a representation from DOM information; it does not take a screenshot of the browser’s already-composited pixels. CSS support is selective, and every CSS property must be implemented individually. Unsupported or partially supported properties can produce a result that differs from what you see on screen.
When the Promise resolves but the image looks wrong:
- Compare the styles used by the target element with html2canvas’s supported-features documentation.
- Temporarily remove filters, complex blend modes, unusual backgrounds, or other effects that may have limited support.
- Capture a smaller, simpler element to isolate the first unsupported style.
- Confirm that web fonts and external images finished loading before starting the capture.
A successful Promise means the rendering operation completed; it does not promise full CSS fidelity.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #4
Fix blank, clipped, or unexpectedly small canvases
Render the element’s complete scroll area
If a long element is clipped, provide dimensions based on its scrollable content:
const element = document.querySelector('#capture');
html2canvas(element, {
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight
}).then(canvas => {
document.body.appendChild(canvas);
});
Use this when the visible viewport is smaller than the element’s full content. It does not remove browser canvas limits.
Check browser canvas limits
Maximum dimensions vary by browser, operating system, hardware, and device memory. The html2canvas FAQ lists these implementation limits as guidance, not universal guarantees:
| Environment | Maximum width/height listed | Maximum area listed |
|---|---|---|
| Chrome | 32,767 pixels | 268,435,456 pixels |
| Firefox | 32,767 pixels | 472,907,776 pixels |
| Internet Explorer | 8,192 pixels | Not stated |
| iOS devices with less than 256 MB RAM | Not stated | 3 megapixels |
| iOS devices with at least 256 MB RAM | Not stated | 5 megapixels |
These figures can change with the target browser and device. If a large capture is blank or truncated, reduce the capture area, render sections separately, or verify limits on the browsers you support.
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 →Best Value
A practical troubleshooting sequence
- Identify the API generation. Confirm the resolved html2canvas version and remove the obsolete
onrenderedoption. - Wait for completion. Move append, export, and post-processing code into
.then(canvas => ...)or afterawait html2canvas(...). - Log rejection details. Add
.catch()ortry/catchand inspect the console. - Test same-origin content. Temporarily remove remote images and canvases to separate CORS failures from rendering failures.
- Check fidelity. Compare the target CSS with supported features and simplify unsupported effects.
- Check dimensions. Inspect
canvas.widthandcanvas.height; usescrollWidth/scrollHeightfor full content and stay below device limits. - Retest the smallest case. Capture a plain element containing local text and a solid background, then add images and styling back one piece at a time.
Common symptoms and precise fixes
| Symptom | Likely cause | Fix |
|---|---|---|
Code inside onrendered never runs |
The option was removed from the loaded API. | Use the returned Promise with .then() or await. |
toDataURL is not a function |
You called it on the unresolved Promise. | Call it on canvas inside the resolved handler. |
| Remote images are missing or export fails | CORS or same-origin restrictions. | Configure image response headers, try useCORS, or use a properly configured proxy. |
| Styles differ from the page | The CSS property is unsupported or partially supported. | Check supported features and simplify or replace the affected styling. |
| Large capture is blank or clipped | Viewport sizing or browser canvas limits. | Set window dimensions from scroll dimensions, reduce the area, and test device-specific limits. |
Or skip the browser setup
If your goal is a clean website image rather than a DOM reconstruction inside the user’s browser, ScreenshotNeo makes one server request and returns a PNG, JPEG, WebP, or PDF. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn those steps off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; the response identifies the result with X-Page-Verdict and X-Billed headers.
Use the API documentation at https://screenshotneo.com/docs/ for all parameters. A basic cURL request is:
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,
)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await require('node:fs').promises.writeFile('shot.webp', data);
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, PDF paper and page-range controls, custom CSS and JavaScript, pre-capture clicks, hidden selectors, selector/delay/network-idle waits, request and resource blocking, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Its parameter names are compatible with those used by many screenshot APIs, which can simplify migration.
An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots, and every feature is available on every plan. Create a free ScreenshotNeo account.
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 →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.

