What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
To capture an inline SVG with html2canvas, pass the SVG element (or a container) to html2canvas(), wait for the returned promise, and export the canvas as a PNG. The result is a raster image reconstructed from the DOM, not editable SVG data or a pixel-perfect browser screenshot.
Minimal inline-SVG capture
Load html2canvas in your page, select the SVG, and await the promise. This example keeps transparency and uses the device-pixel ratio for sharper output.
const svg = document.querySelector('#chart');
if (!svg) {
throw new Error('SVG #chart was not found');
}
const canvas = await html2canvas(svg, {
backgroundColor: null,
scale: window.devicePixelRatio
});
const blob = await new Promise((resolve, reject) => {
canvas.toBlob(result => result ? resolve(result) : reject(new Error('PNG export failed')), 'image/png');
});
const imageUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = imageUrl;
link.download = 'chart.png';
link.click();
URL.revokeObjectURL(imageUrl);
Use canvas.toDataURL('image/png') instead when an inline data URL is more convenient:
const dataUrl = canvas.toDataURL('image/png');
The library runs in the browser and rebuilds a representation from DOM styles and elements. It does not preserve the SVG as vector paths, so text, filters, masks, and unsupported CSS can look different from the live page.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
Prepare the SVG before rendering
Give the element real dimensions
An SVG that is detached, hidden, or has zero computed width or height can produce a blank canvas. Attach it to the document and verify its layout before calling html2canvas:
const box = document.querySelector('#chart').getBoundingClientRect();
console.log({ width: box.width, height: box.height });
Set an explicit width and height, or ensure its CSS gives it a non-zero size. For a responsive chart, wait until its container has been laid out.
Wait for images and fonts
External images, web fonts, and dynamically drawn content must finish loading first. A practical browser-side wait is:
await document.fonts.ready;
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 canvas = await html2canvas(document.querySelector('#chart'));
This prevents capturing a font fallback or an image placeholder. It does not make a failed resource available; inspect the browser console and network panel for those failures.
Crashes, 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 minuteWindows 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 reinstallChange only the cloned document
onclone(documentClone) runs after html2canvas clones the page. Use it to adjust the copy used for the screenshot without changing what the user sees:
const canvas = await html2canvas(document.querySelector('#chart'), {
onclone(documentClone) {
const copy = documentClone.querySelector('#chart');
copy?.classList.add('capture-mode');
}
});
Options that matter for SVG
| Option | Use | Important qualification |
|---|---|---|
backgroundColor |
Set to null for transparent output. |
The documented default is white. |
scale |
Controls output pixel density; window.devicePixelRatio is a common choice. |
Higher values increase memory use and output dimensions. |
x, y, width, height |
Crop the capture region. | Use dimensions that match the rendered element, not only its SVG viewBox. |
foreignObjectRendering |
Requests the browser’s ForeignObject rendering path. | The documented default is false; support and visual parity vary by browser, so test every browser you ship. |
useCORS |
Attempts CORS-enabled loading for eligible resources. | It works only when the remote server sends an appropriate Access-Control-Allow-Origin header. |
onclone |
Modifies the cloned DOM for capture. | Changes do not apply to the live document. |
A transparent, high-density capture with a deliberate crop could look like this:
const el = document.querySelector('#chart');
const rect = el.getBoundingClientRect();
const canvas = await html2canvas(el, {
backgroundColor: null,
scale: Math.min(window.devicePixelRatio, 3),
x: 0,
y: 0,
width: rect.width,
height: rect.height,
foreignObjectRendering: true
});
Do not assume foreignObjectRendering is automatically better. It asks for a different browser path; unsupported elements or browser differences can make the result worse.
Cross-origin images, fonts, and canvas security
When an SVG references an image, font, stylesheet, or other resource on another origin, browser security rules apply. If the resource is not delivered with compatible CORS headers, the resulting canvas may be tainted and pixel export can throw a security error or fail.
Recommended Free Tools
Preferred fixes
- Serve the asset from the same origin as the page.
- Configure the asset server to return an appropriate
Access-Control-Allow-Originheader and then useuseCORS: true. - Proxy the resource through your own origin, subject to the asset’s license and your site’s security policy.
- Inline an image or other asset as data in the SVG when you are legally allowed to do so.
html2canvas cannot bypass content-policy restrictions. A proxy or inline data is a deployment choice, not an option that the library can secretly enable.
Iframes
Cross-origin iframes cannot be rendered because their contentDocument is inaccessible. Same-origin iframes can be traversed recursively. If the chart is inside a third-party iframe, capture code must run in that frame or the provider must offer an export.
Rank #3
Why the result is blank, clipped, or different
Blank image
- Zero dimensions: check
getBoundingClientRect()and make the SVG visible and attached before capture. - Capture ran too early: await fonts, images, chart data, and the framework’s render cycle.
- Resource failure: inspect console and network errors; a missing external image can leave an empty region.
- Cross-origin taint: fix CORS or use a same-origin proxy before exporting pixels.
Clipping or missing the bottom of a page
Compare the element’s scroll dimensions with the capture viewport. For a larger document, set suitable windowWidth and windowHeight values and capture the actual container rather than a viewport-sized wrapper. Very large canvases can exceed browser canvas limits; reduce scale, capture in sections, or resize after capture.
Fonts, filters, or CSS do not match
html2canvas supports only the browser features it can reconstruct. Wait for fonts, provide fallback styles in onclone, and test SVG filters, masks, blend modes, and complex CSS in every target browser. A successful promise does not guarantee pixel equality with the live page.
Export throws a security exception
That usually indicates a tainted canvas. Changing scale or background color cannot repair it; identify the cross-origin resource and correct its headers, proxy it, or inline it.
Export formats and practical limits
Use toBlob() for downloads, uploads, and memory-friendlier workflows. Use toDataURL() for small images that must be embedded immediately. PNG preserves transparency; JPEG does not and is unsuitable when transparent pixels matter. WebP support depends on the browser and your receiving system.
Output size is the rendered CSS size multiplied by scale. A large full-page SVG at a high device-pixel ratio can consume substantial memory. Set a deliberate maximum scale, crop to the required region, or process separate sections. Browser canvas maximum dimensions vary by engine and device, so treat giant captures as a compatibility case rather than a guaranteed capability.
When html2canvas is the right tool
Choose it when rendering must happen in the user’s browser, the source is accessible DOM, and a raster image is acceptable. Compare alternatives on vector fidelity, CSS and filter support, browser coverage, external-resource handling, output formats, latency, canvas-size limits, and whether server-side rendering is required. If you need editable SVG, serialize the SVG itself instead of converting it to a canvas; html2canvas is a screenshot-style rasterizer, not an SVG exporter.
Or skip the browser setup
For server-side website captures, ScreenshotNeo accepts one GET request and returns PNG, JPEG, WebP, or PDF. It handles 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, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.
Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. A basic call 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(`${res.status} ${res.statusText}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
ScreenshotNeo also supports element selectors, full-page lazy-image loading, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and PDF controls. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for 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; yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to try it without a card.
Frequently Asked Questions
Can html2canvas preserve my SVG as editable vector output?
No. It reconstructs the DOM into a raster canvas. Keep or serialize the original SVG when downstream editing is required.
Does setting useCORS: true bypass an image host’s restrictions?
No. The remote host must send compatible CORS headers; otherwise use same-origin delivery, a lawful proxy, or inline data.
Why does foreignObjectRendering work in one browser but not another?
It selects a browser-dependent ForeignObject path. Support and visual parity are not universal, so test the exact browsers and SVG features you support.
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.




