October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
html2canvas

How to Capture SVG Elements With html2canvas (and Fix Blank Results)

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Change 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Preferred fixes

  • Serve the asset from the same origin as the page.
  • Configure the asset server to return an appropriate Access-Control-Allow-Origin header and then use useCORS: 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.