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 problemsShort 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.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
<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
- 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. - 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 fordocument.fonts.readybefore invoking html2canvas. - 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.
- 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. - Log resource failures. html2canvas exposes an
onErrorcallback 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. - 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.
- 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
- 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.
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.
Rank #3
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.
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
- 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.
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.
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.
Best Value
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.
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.




