Short answer: html2canvas can render many inline and embedded SVG elements, and it has an optional foreignObjectRendering path. Neither mode is a literal browser screenshot or a guarantee that every SVG feature and CSS rule will match the screen. html2canvas rebuilds the image from DOM data, so validate the exact SVG, styles, resources, and browsers your application supports.
How html2canvas renders SVG
html2canvas runs in the browser, clones the target DOM, reads the properties it understands, and paints a representation onto a canvas. It does not ask the browser for a pixel-for-pixel screenshot of the already-composited page. That distinction explains why an SVG can look correct in the page but differ in the canvas output.
The library has separate feature detection for SVG drawing and for foreign-object drawing. The ordinary renderer handles supported SVG structures as part of its DOM reconstruction. The optional foreign-object renderer serializes the cloned element inside an SVG <foreignObject>, loads that serialized image, and draws it onto the canvas when the browser supports the required APIs.
Because support is based on implemented properties and browser behavior, the existence of SVG or foreign-object detection is not a compatibility promise for every filter, mask, paint server, linked image, font, or CSS declaration.
#1 Best Overall
Basic SVG capture
Install or load html2canvas, place an inline SVG in the document, and capture its containing element:
<div id="artboard">
<svg width="640" height="360" viewBox="0 0 640 360" role="img" aria-label="Sample chart">
<rect width="640" height="360" fill="#101828"/>
<circle cx="180" cy="170" r="90" fill="#7f56d9"/>
<text x="320" y="190" fill="white" font-size="32">SVG chart</text>
</svg>
</div>
<script src="/path/to/html2canvas.min.js"></script>
<script>
html2canvas(document.querySelector('#artboard'), {
backgroundColor: null,
scale: window.devicePixelRatio,
onclone: clonedDocument => {
// Make any capture-only style changes in the clone, not the live page.
clonedDocument.querySelector('#artboard').style.display = 'block';
},
onerror: error => console.error('html2canvas resource error', error)
}).then(canvas => {
document.body.appendChild(canvas);
const link = document.createElement('a');
link.download = 'svg-capture.png';
link.href = canvas.toDataURL('image/png');
link.click();
});
</script>
Use the documented option name and callback spelling provided by the html2canvas version you load. In current releases, the error callback is commonly exposed as onerror in examples and as onError in configuration documentation; check your installed build if the callback is not invoked.
Capture the SVG itself
If surrounding layout is irrelevant, pass the svg element rather than its parent. Capturing a parent is usually safer when CSS inheritance, backgrounds, or external layout affect the artwork.
Increase output resolution
scale controls canvas density. A value of 2 produces a larger raster than 1, but it also increases memory use and can hit browser canvas limits. Use the smallest value that meets your print or export requirement.
Recommended Free Tools
Using foreignObjectRendering
Enable the optional path explicitly:
html2canvas(document.querySelector('#artboard'), {
foreignObjectRendering: true,
backgroundColor: '#ffffff',
imageTimeout: 15000,
useCORS: true
}).then(canvas => {
document.querySelector('#output').replaceChildren(canvas);
});
The option defaults to false. It asks html2canvas to use browser foreign-object support when available; it does not turn unsupported CSS or SVG constructs into supported ones. Browser differences can therefore produce different results even with identical markup.
| Decision point | Ordinary html2canvas rendering | foreignObjectRendering: true |
|---|---|---|
| How pixels are produced | Reconstructs supported DOM, CSS, and SVG data. | Serializes cloned content in an SVG foreign object, then draws it as an image. |
| Default | Yes | No |
| Best fit | Predictable, supported primitives and controlled styles. | Cases where browser foreign-object behavior improves CSS or mixed HTML/SVG output. |
| Guarantee | No universal SVG or CSS fidelity. | No universal fidelity; browser support and resource policy still apply. |
| Validation | Test each target browser and SVG construct. | Test each target browser; feature detection alone is insufficient. |
SVG features that commonly differ
Inline versus external SVG
Inline markup is available to the DOM parser. An external <img src="diagram.svg">, CSS background, or SVG reference such as <use href="sprite.svg#icon"> introduces a resource request and browser security rules. A linked asset may fail even when the inline equivalent works.
Filters, masks, gradients, and clipping
These constructs rely on detailed SVG and CSS behavior. The reviewed project documentation does not provide a complete version-by-version compatibility matrix, so do not infer support from a successful simple path or circle. Build a small test case for every filter, mask, gradient, clip path, blend mode, and text treatment your design depends on.
SVG text and fonts
Text can change when the web font has not loaded, when a font is unavailable in the capture browser, or when CSS font properties are not implemented by the renderer. Wait for fonts before capture and compare the output in each supported browser.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsCSS around the SVG
html2canvas states that every CSS property must be implemented manually and therefore it will never have full CSS support. A difference may come from a parent layout rule, pseudo-element, transform, shadow, or blend mode rather than from SVG itself.
Cross-origin images and resource loading
Browser content policies apply to SVG-linked images just as they do to ordinary images. Setting useCORS: true only helps when the remote server sends an appropriate Access-Control-Allow-Origin response. It cannot bypass a missing or restrictive CORS header.
Rank #3
html2canvas(document.querySelector('#artboard'), {
useCORS: true,
proxy: '/same-origin-image-proxy',
imageTimeout: 20000,
onError: error => console.error(error)
});
Use a same-origin proxy only when you control and trust the proxy. Do not copy credentials or private response data into a public proxy. If the remote server cannot provide CORS and no safe proxy is available, inline the asset as a data URL or redesign the capture path.
A repeatable debugging procedure
- Reduce the case. Create a page containing only the failing SVG, its required styles, and one capture button.
- Separate SVG from CSS. Replace complex effects with a solid fill and a simple path. If that works, reintroduce filters, masks, text, and layout rules one at a time.
- Compare modes. Capture once with the default renderer and once with
foreignObjectRendering: truein every target browser. - Inspect resources. Open the browser network panel and use the configured error callback. Check status codes, CORS headers, redirects, fonts, and SVG references.
- Check timing. Wait for images and fonts before calling html2canvas. Use
imageTimeoutto prevent an indefinitely pending resource from blocking the capture. - Check dimensions. Confirm the element has non-zero width and height. For blank or clipped output, test smaller dimensions and inspect the browser’s canvas-size limits.
- Record the environment. Keep the browser name, version, device pixel ratio, viewport, and SVG markup with the reproduction. Rendering is environment-dependent.
Common failures and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| SVG is blank | Zero-sized target, failed resource, unsupported construct, or canvas limit. | Inspect dimensions and network errors, simplify the SVG, and try a smaller capture. |
| External image disappears | Missing CORS response or a cross-origin canvas. | Use useCORS only with server permission and correct headers; otherwise use a same-origin proxy or inline the asset. |
| Styles are partly missing | The CSS property is not implemented or differs in the selected renderer. | Replace the property, add a capture-only style, or use a browser capture API when exact pixels matter. |
| Output is clipped | Incorrect element dimensions, scroll area, or browser canvas maximum. | Set explicit width and height, capture the intended element, and reduce scale or dimensions. |
| Text looks wrong | Font has not loaded or is unavailable in the browser. | Wait for font loading, confirm the computed font, and test the same browser used in production. |
| Foreign-object mode fails | Browser lacks required support or rejects serialized content/resources. | Fall back to the ordinary renderer, simplify markup, or use native/browser automation capture. |
Performance, reliability, and when to choose another tool
Capturing a large, high-density page consumes CPU and memory because html2canvas clones and paints the DOM in the browser. Limit the target element, avoid unnecessary scale, and remove animated or continuously changing content in a capture-only clone. Cache stable assets and wait for network activity to settle before starting.
Free tools Windows power users keep installed
One-click scans. No signup required.
For a true browser screenshot, html2canvas is the wrong abstraction: it reconstructs rather than captures the compositor output. The project’s FAQ points browser-extension authors toward native extension screenshot APIs and server-side users toward browser automation tools such as Puppeteer or Playwright. Choose those paths when you need exact browser pixels, server-side execution, or behavior html2canvas cannot represent.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
When you need a rendered page image rather than a client-side canvas reconstruction, ScreenshotNeo provides a single HTTP request. It accepts the cookie or consent banner 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 result with X-Page-Verdict and X-Billed headers. An MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
See the complete parameter list and output details in the ScreenshotNeo documentation. A basic 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)
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 buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));
Every feature is available on every plan: 1,000 screenshots per month free with no card, then Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; annual billing provides two months free. Start with the free ScreenshotNeo account.
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 →FAQ
Does html2canvas support SVG files served as images?
It can process supported image resources, but external files remain subject to loading, CORS, and browser-policy requirements. Inline SVG is easier to diagnose because its markup is already in the DOM.
Is foreignObjectRendering more accurate than the default?
It can improve particular mixed HTML/SVG cases in browsers that support it, but there is no universal winner. Test both paths with your actual effects, fonts, linked resources, and target browsers.
Can html2canvas run on a server without a browser?
No. It depends on browser APIs and runs in the browser. For server-side screenshots, use a browser automation service or a hosted screenshot API.
Frequently Asked Questions
Does html2canvas preserve SVG vector quality?
No. The result is a raster canvas. Increase scale for sharper output, but verify memory and canvas-size limits.
Why does the page look right while the canvas differs?
The page is compositor-rendered by the browser, while html2canvas rebuilds the scene from supported DOM, CSS, SVG, and resource data.
Where should I report an unsupported SVG or CSS case?
Create a minimal reproduction containing the SVG and surrounding styles, then use the project’s issue process; a reduced case makes it possible to distinguish an unsupported property from a resource or browser problem.
The Bottom Line
html2canvas offers useful SVG rendering and an opt-in foreign-object path, but neither promises full SVG or CSS fidelity. Treat every complex SVG as a browser-tested case, solve CORS and timing issues explicitly, and switch to native browser capture or a screenshot service when you need the actual rendered pixels.
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.
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 →

