← Blog

SVG fonts — system, web, embedded

SVG references fonts; the rendering server needs them physically present to draw glyphs System font font-family: Arial font-family: Helvetica font-family: serif render server has it → embedded in PDF, text selectable, prints right Web font (CDN) @import url(googleapis…); font-family: "Inter" render server can't fetch → falls back to default, layout may differ Embedded (data URI) @font-face { src: url(data:font/woff2; base64,…) } font travels with file, always rendered correctly, file is bigger

Text in SVG is one of the trickier conversion topics. The SVG XML references a font by name, but a name is not a font — actual glyph data lives in font files installed on the rendering machine. Whether the PDF renders correctly depends on whether the right font is available. The conversion server has a fixed set of fonts available; if your SVG references something else, the result has visible substitution.

How text rendering works at conversion time

For each <text> element, the renderer:

  1. Resolves the CSS font-family property to a list of font names.
  2. Searches the font cache for the first available match. The fallback chain is: requested family → next requested family → generic family (sans-serif/serif/monospace) → default font.
  3. Loads glyph data for the matched font.
  4. Lays out characters according to font-size, kerning rules, ligatures, etc.
  5. Emits PDF text operators with the matched font embedded in the PDF.

The key step is "first available match". If the SVG asks for font-family: "Inter" and Inter isn't installed, the renderer doesn't fail — it silently falls back to the next option, often a generic system sans-serif. Glyphs draw, but they have different metrics: text widths, line heights, and kerning differ from the design.

What fonts the render server has access to

The conversion server uses whatever fonts happen to be installed on the host. The set typically includes the common Linux open-source families — generic sans-serif, serif, and monospace coverage with broad multilingual scripts — but it is not curated by the converter and isn't user-controllable. References to common Microsoft fonts ("Arial", "Times New Roman") may resolve to look-alike open replacements when those are present; brand-specific or webfont-only families (Inter, Roboto, Open Sans, custom corporate fonts, anything from Adobe Fonts) typically don't exist on the server and fall back to a generic default.

If your SVG references one of these brand fonts, expect substitution. Layout differences are typically subtle but visible in side-by-side comparison: line widths shift slightly, kerning differs, ligatures may not match.

Solving the fallback problem: embed the font

The reliable solution is to embed the font into the SVG as a data URI. This makes the font travel with the file, no network or system dependency:

<svg ...>
  <defs>
    <style type="text/css">
      @font-face {
        font-family: "Inter";
        src: url(data:font/woff2;base64,d09GMgABAAA…) format("woff2");
      }
    </style>
  </defs>
  <text font-family="Inter">Hello</text>
</svg>

The base64 blob is the woff2 (or woff or ttf) file's bytes encoded as text. Modern font-subsetting tools can produce subset embedded fonts containing only the glyphs your SVG actually uses, keeping the data URI small.

Support for @font-face with embedded data URIs is partial in most server-side SVG renderers — it works for some font formats and not others. WOFF2 generally works; for maximum compatibility, test the resulting PDF in a viewer to confirm text renders correctly. If embedded fonts don't take, the safer alternative is to convert text to paths in your SVG editor before uploading (most editors expose a "Convert text to path" command).

What the PDF actually stores

For each font used by visible text, the PDF carries:

Font subsetting is critical for size: a typical Latin font is 100–500 KB whole, but only a few KB if you keep just the glyphs your SVG uses. The conversion library typically produces subsetted output, keeping the embedded font streams compact.

Text as paths — guaranteed reproduction

An alternative to embedding fonts: convert each text element to a <path> with the glyph outline data, before uploading. Most desktop SVG editors (Inkscape, Illustrator, Affinity Designer, Figma) expose this as "Object → Convert text to path" or "Outline text" — select all text, run the command, save. Every letter becomes a vector shape; the file no longer needs the font.

Pros:

Cons:

For brochure-style print output where layout fidelity is paramount, paths-not-text is the right choice. For documents where text searchability matters, embed fonts as data URIs instead.

Multilingual text

For multilingual text — Cyrillic, Greek, Arabic, Hebrew, Devanagari, CJK — the safest approach is the same as for any other potentially-unavailable typeface: convert text to paths, or embed the font as a data URI. The conversion server's coverage of unusual scripts is not something the user can rely on; some scripts are present, some aren't, and there is no way to inspect what's available before uploading.

Right-to-left and complex script shaping (Arabic, Indic) work in the renderer when the script's font is present. Without an appropriate font, glyphs fall back to boxes or generic shapes.

Checking what fonts an SVG uses

Open the SVG in a desktop editor and select a piece of text — the font panel reports the family name. For a quick survey, opening the SVG in a plain text editor and searching for font-family shows every font reference in the file. Font names like "Inter", "Roboto", or any custom branded font are clues that the result might fall back to a default; "Arial", "Helvetica", "Times", "sans-serif", "serif" are usually safe.