Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober 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 PC×
Skip to content
@font-face

How to Render SVG Text With @font-face in html2canvas (Version-Aware Guide)

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

Short answer: SVG supports web fonts declared with @font-face, but that capability does not guarantee that html2canvas will preserve the font in a canvas capture. The reliable way to diagnose a wrong or fallback font is to prove the font is loaded, reduce the page to one SVG text node, then compare html2canvas’s normal renderer with foreignObjectRendering: true on the exact browser and html2canvas version your application uses.

Why the browser can be right while html2canvas is wrong

An SVG <text> element can use a web font through CSS:

@font-face {
  font-family: "Acme Sans";
  src: url("/fonts/acme-sans.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}

svg text {
  font-family: "Acme Sans", sans-serif;
}

The browser’s live rendering engine resolves the font, lays out the SVG, and paints it on screen. html2canvas is a separate reconstruction and rasterization process. Its output can therefore differ even when the SVG looks correct in the page. A historical html2canvas issue reported an SVG text node displaying correctly in Chrome but using the wrong font in the captured image with html2canvas 1.0.0-alpha-12 and Chrome 70 on macOS Mojave. That report demonstrates a failure in that particular setup; it does not prove that every current release or browser has the same defect.

The distinction matters: @font-face is an SVG/CSS capability, while font fidelity in a screenshot library depends on resource loading, renderer implementation, browser support, and how the SVG reaches the library.

Build a minimal reproduction first

Remove frameworks, animations, multiple font weights, and unrelated page content. Use a font whose letterforms visibly differ from the fallback, and keep the SVG inline so you can distinguish SVG behavior from external-image behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<style>
  @font-face {
    font-family: "Acme Sans";
    src: url("/fonts/acme-sans.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: block;
  }
  #sample text {
    font-family: "Acme Sans", sans-serif;
    font-size: 42px;
  }
</style>

<svg id="sample" width="700" height="100" viewBox="0 0 700 100">
  <text x="10" y="60">SVG font capture test: 0OIl 123</text>
</svg>

<button id="capture">Capture</button>
<script type="module">
  import html2canvas from "html2canvas";

  document.querySelector("#capture").addEventListener("click", async () => {
    await document.fonts.ready;
    const canvas = await html2canvas(document.querySelector("#sample"), {
      onclone: (clonedDocument) => {
        // Keep the cloned SVG’s CSS explicit and deterministic.
        clonedDocument.querySelector("#sample text").style.fontFamily =
          '"Acme Sans", sans-serif';
      },
      onError: (error) => console.error("html2canvas resource error", error)
    });
    document.body.append(canvas);
  });
</script>

document.fonts.ready waits for the document’s font loading set to finish. It is a useful synchronization point, not a guarantee that every capture path will interpret the font identically. Also verify in DevTools that the WOFF2 request succeeds, that the expected face and weight are selected, and that the computed font-family on the SVG text is correct.

Use a version-aware comparison workflow

  1. Record the environment. Write down the html2canvas version, browser and browser version, operating system, font URL or provider, font weight/style, and whether the SVG is inline markup, an external SVG image, or content inside a foreignObject. A result from an old alpha release should not be generalized to a current package.
  2. Confirm the on-screen result. Inspect the SVG text and its computed style. In the browser console, check document.fonts.check('42px "Acme Sans"') and wait for document.fonts.ready before invoking html2canvas.
  3. Capture the smallest case with the default renderer. This gives you a baseline. Save the canvas as a PNG and compare distinctive glyphs, spacing, weight, and line breaks with the live SVG.
  4. Repeat with foreignObjectRendering: true. html2canvas documents this as an option to use foreignObject rendering where the browser supports it. It is a different path, not a documented font-repair switch.
  5. Log resource failures. html2canvas exposes an onError callback for failures involving resources such as images, SVGs, or backgrounds. Treat a callback message as evidence to investigate the resource URL, origin policy, response headers, and timing.
  6. Compare only like with like. Change one variable at a time: renderer option, font source, SVG delivery method, or browser. Keep the exact package lockfile and capture settings when you report a result.
  7. Escalate with a reproducible case. If the minimal example still fails, include the reduced HTML, font declaration, capture options, browser/version, html2canvas version, and whether the SVG is inline or loaded as an image when consulting the project issue tracker.

Default renderer versus foreignObjectRendering

Axis Default html2canvas path foreignObjectRendering
Meaning Normal html2canvas renderer. Uses browser foreignObject rendering when supported.
Diagnostic value Baseline for identifying the mismatch. Shows whether the result changes with an alternate rendering path.
Font guarantee A historical report recorded a wrong font in one old setup. No guarantee; another historical report described Google Fonts loading trouble with this option.
Implementation detail Reconstructs page content for canvas output. The project’s foreignObject renderer serializes content into SVG, loads it as an image, then draws that image to canvas. The source can change, so inspect the release you actually ship.

The useful conclusion is comparative, not prescriptive. If only one path fails, you have narrowed the problem. Neither option is universally correct.

Common causes and targeted fixes

The font request never succeeds

A 404, blocked cross-origin request, incorrect MIME configuration, or a content-security-policy rule can leave the browser using a fallback. Fix the URL and server response first. A CSS rule that names a font is not proof that the font bytes arrived.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

The capture starts before loading finishes

Call await document.fonts.ready immediately before capture, and avoid starting the screenshot while a route transition or font swap is still in progress. For a font loaded dynamically, explicitly await the promise returned by document.fonts.load('42px "Acme Sans"') as well.

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

The computed style is not inherited into the clone

Set font-family, weight, and style directly on the SVG text in the reproduction. If that works, inspect the cloned document and your selectors. CSS selectors depending on ancestor state, shadow DOM, or framework-generated attributes may not apply as expected.

The SVG is an external image

Inline SVG and an <img src="diagram.svg"> are different inputs. External images add URL, origin, response-header, and image-decoding considerations. Test the inline form first, then add the external delivery method and compare.

foreignObjectRendering changes the failure

That result is diagnostically useful, but it is not a fix you can assume will work everywhere. Browser support for foreignObject and the renderer’s SVG-image loading step introduce their own constraints. A historical report described Google Fonts failing with html2canvas 1.0.0-rc.3, Chrome 75, and Ubuntu 18.04 while this option was enabled.

The font is present but the wrong face is selected

Check that the declared font-weight and font-style match an available face. If only a 700 face is loaded but the SVG requests 400, the browser may synthesize or substitute a face; the canvas can make that difference more obvious.

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

Useful capture code for both renderer paths

import html2canvas from "html2canvas";

async function captureSvg(selector, foreignObjectRendering = false) {
  await document.fonts.ready;
  await document.fonts.load('42px "Acme Sans"');

  const element = document.querySelector(selector);
  if (!element) throw new Error(`No element matches ${selector}`);

  return html2canvas(element, {
    foreignObjectRendering,
    backgroundColor: "#ffffff",
    logging: true,
    onError: (error) => console.error("Capture resource error", error)
  });
}

const baseline = await captureSvg("#sample", false);
const alternate = await captureSvg("#sample", true);

Use the same viewport, device-pixel ratio, element dimensions, and font state for both calls. A visual difference can otherwise come from scaling or timing rather than font handling.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Performance, reliability, and deployment notes

  • Wait deliberately, not indefinitely. Font readiness should precede capture, but application code should still have an overall timeout and a user-visible failure path.
  • Prefer a self-contained test case. Local font files make network and provider behavior easier to separate from renderer behavior. Once the local case works, test the production font source.
  • Keep capture dimensions stable. Responsive breakpoints, late layout shifts, and device-pixel-ratio changes can alter text wrapping and make a font mismatch appear worse.
  • Expect browser variance. The foreignObject path depends on browser support, and the historical reports do not establish a current cross-browser matrix.
  • Preserve diagnostics in CI. Store the browser version, html2canvas version, font response status, computed style, and a reference image when visual regressions matter.
  • Do not treat cache success as font proof. A cached stylesheet can be present while the font face itself is unavailable or a different weight is selected.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a clean website screenshot rather than debugging html2canvas inside your page, ScreenshotNeo provides a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; bot checks, blank pages, failed loads, timeouts, 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 to Claude, Cursor, and other MCP clients.

See the parameter reference in the ScreenshotNeo documentation. A direct call looks like this:

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}`);

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account to try it.

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

What the historical reports do—and do not—tell you

The SVG mismatch report was opened in November 2018 for html2canvas 1.0.0-alpha-12, Chrome 70.0.3538.102, and macOS Mojave 10.14. The foreignObject Google Fonts report was opened in July 2019 for html2canvas 1.0.0-rc.3, Chrome 75.0.3770.80, and Ubuntu 18.04. They are valuable reproductions from those environments, not current release guarantees. Your own browser, package version, font source, and SVG delivery mode determine the result.

Frequently Asked Questions

Does adding @font-face guarantee the SVG font in html2canvas?

No. It enables the font for SVG/CSS in the browser; html2canvas still has to load and reproduce that font during capture.

Should I always enable foreignObjectRendering?

No. Compare it with the default renderer on your target browser and html2canvas version. It is a diagnostic alternative, not a universal font fix.

What should I include in a bug report?

Provide a minimal SVG, the font declaration and source, html2canvas version, browser/version, operating system, capture options, and whether the SVG is inline or external.

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

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.

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
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

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.