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 problemsiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
An empty dom-to-image download does not identify one universal bug. A large capture can fail while the library clones the DOM, loads styles and images, builds its SVG, rasterizes that SVG on a canvas, exports a PNG or JPEG, or hands the result to your download code. Browser canvas dimensions are one documented possibility, but they are not proven to explain every blank dom-to-image file.
What happens before a file is downloaded
The original tsayen/dom-to-image project converts a DOM node into an SVG representation. For PNG, JPEG, or pixel data, that representation is then drawn through an off-screen canvas. The final download is a separate step performed by your application. Consequently, an empty file can originate in any of these stages:
- Clone and style processing: the selected node or its computed styles may not be copied correctly.
- Resource loading: external images, fonts, or stylesheets can fail or be inaccessible.
- SVG generation: the intermediate SVG can be empty or incomplete.
- Canvas rasterization and export: the requested bitmap may exceed browser limits or contain a tainted canvas.
- Caller-side download: an unresolved promise, empty data URL, or zero-byte Blob may still be passed to an anchor element.
A large DOM makes several of these risks more likely because it increases the measured width and height, the amount of cloned content, the number of resources, and the final pixel count.
First check: measure the real output size
Record the target element’s dimensions, the capture scale (often called a multiplier), and window.devicePixelRatio. The effective raster dimensions are approximately:
#1 Best Overall
pixelWidth = CSS width × scale × devicePixelRatiopixelHeight = CSS height × scale × devicePixelRatio
Area matters too: a modest increase in both dimensions can multiply the number of pixels. Canvas limits vary by browser and device. The html2canvas FAQ documents blank or partially rendered output when canvas limits are exceeded; that is useful evidence for browser canvas workflows, but html2canvas is a different implementation and its behavior must not be treated as a guaranteed diagnosis for dom-to-image.
const node = document.querySelector('#report');
const rect = node.getBoundingClientRect();
const scale = 2; // use the value passed to your capture code
const dpr = window.devicePixelRatio || 1;
console.table({
cssWidth: rect.width,
cssHeight: rect.height,
scale,
devicePixelRatio: dpr,
pixelWidth: Math.ceil(rect.width * scale * dpr),
pixelHeight: Math.ceil(rect.height * scale * dpr)
});
This calculation is a diagnostic, not a universal maximum. Browser, operating-system, GPU, and available memory all affect the practical limit.
A reproducible troubleshooting sequence
1. Reduce dimensions as a controlled test
Capture a smaller region or set a lower scale. If the result becomes non-empty, size pressure is plausible. It is not conclusive proof: the smaller run may also avoid a problematic resource or expose a timing difference. Keep the measured dimensions and options for both attempts.
Rank #2
2. Inspect the intermediate SVG
If your installed dom-to-image version exposes an SVG or data-URL method, call it before PNG/JPEG conversion and inspect the returned string. An empty or nearly empty SVG points toward cloning, computed-style copying, or resource processing. A correct SVG followed by a blank bitmap shifts attention to canvas rasterization or export.
domtoimage.toSvg(document.querySelector('#report'), options)
.then(svgUrl => {
console.log('SVG URL length:', svgUrl.length);
if (!svgUrl || svgUrl.length === 0) throw new Error('Empty SVG result');
const preview = document.createElement('a');
preview.href = svgUrl;
preview.target = '_blank';
preview.textContent = 'Open captured SVG';
document.body.appendChild(preview);
})
.catch(console.error);
The exact method names and options depend on the package and version, so verify them against the code you installed.
3. Check the browser console and network panel
Look for rejected image, font, and stylesheet requests, security exceptions, and serialization errors. Test with one simple local image and without web fonts to isolate the failing resource. The original project’s cautions specifically include a tainted embedded canvas and a Firefox issue involving some external stylesheets.
4. Investigate nested canvases
A canvas inside the selected node can taint the rendering path when it contains pixels from an origin the browser does not permit the exporting script to read. Remove the nested canvas temporarily or replace it with a same-origin image. Do not assume that an option from another library, such as html2canvas’s useCORS, is a universal dom-to-image fix.
5. Validate the result before downloading
Do not create the download link until the promise has fulfilled and the result has content. For a data URL, check that it has a non-empty payload. For a Blob, check size > 0 and inspect its MIME type.
domtoimage.toPng(node, options)
.then(dataUrl => {
if (typeof dataUrl !== 'string' || dataUrl.length < 32) {
throw new Error('dom-to-image returned an empty data URL');
}
const a = document.createElement('a');
a.download = 'capture.png';
a.href = dataUrl;
a.click();
})
.catch(err => {
console.error('Capture failed:', err);
});
This caller-side check does not repair a failed render, but it prevents an empty response from being mistaken for a successful download.
6. Record the environment
Write down the exact package name and version, browser version, operating system, device-pixel ratio, node dimensions, scale, and console errors. A fork can behave differently from the original package. The dom-to-image-more documentation describes clamping a multiplier when requested canvas dimensions exceed browser limits and logging a warning. That behavior is fork-specific; do not attribute it to the original dom-to-image package without checking your installed version.
Recommended Free Tools
Common symptoms and likely branches
| Symptom | Most useful next check | Interpretation |
|---|---|---|
| Blank only at high scale | Repeat at scale 1 and calculate pixel dimensions | Canvas size or memory pressure is plausible, not proven |
| SVG intermediate is empty | Test a smaller, text-only node; inspect styles and resources | Investigate cloning, style copying, or resource loading |
| SVG looks correct but PNG is blank | Check canvas dimensions, export errors, and nested canvases | Focus on rasterization, tainting, or browser limits |
| Only Firefox fails | Remove external stylesheets and retry | The original project documents a Firefox stylesheet issue |
| Downloaded file is zero bytes | Log the fulfilled value and Blob/data-URL size before creating the link | The final download path may be receiving an empty result |
| Images disappear while text works | Inspect image origins, response headers, and failed requests | Cross-origin or unavailable resources are candidates |
Practical fixes and trade-offs
- Lower the scale: reduces pixel dimensions and memory use, at the cost of output detail.
- Capture in sections: split a very tall report into independently rendered regions, then assemble them in your application. This avoids one huge canvas but requires alignment and stitching logic.
- Simplify the capture node: remove animations, video, large shadows, and unnecessary off-screen content while diagnosing.
- Make resources capture-safe: serve images and stylesheets from an origin your page can access, and wait until required fonts and images have loaded.
- Use the correct package behavior: if you rely on multiplier clamping or other fork-specific handling, pin and document that fork and version.
Do not silently treat a successful low-resolution retry as a complete solution. Compare the visual output and decide whether reduced quality or tiled capture is acceptable.
Rank #4
Or skip the browser setup
For a publicly reachable page, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Use the API documentation at https://screenshotneo.com/docs/ for all options, including full-page lazy-image loading, CSS-selector element capture, device presets, custom viewport and retina scale, PDF settings, custom CSS or JavaScript, waits, request blocking, headers and cookies, timezone and geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous webhooks, bulk capture, and usage reporting.
cURL
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(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to try it.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →FAQ
Is an empty file proof that the canvas limit was exceeded?
No. It is one plausible explanation, especially when lowering scale fixes the result, but the failure may have occurred earlier in SVG generation or later in your download code.
Should I switch immediately to dom-to-image-more?
Not automatically. Confirm the installed package and version first, then decide whether its documented dimension clamping fits your requirements.
Best Value
Why does a screenshot work for text but not images?
Images can fail independently because of origin restrictions, unavailable responses, or resource timing. Test with a same-origin image and inspect network failures.
Frequently Asked Questions
Can increasing browser memory remove the problem?
It may change the practical limit on some devices, but it does not fix tainted canvases, missing resources, empty SVG output, or an invalid download path.
Free tools Windows power users keep installed
One-click scans. No signup required.
What information should I include in a bug report?
Include package and version, browser and operating system, node dimensions, scale, device-pixel ratio, a minimal DOM, console and network errors, and whether the intermediate SVG is populated.
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.

