.ttf) font file.
Registered fonts are automatically subsetted — only glyphs used in the document are embedded, keeping file sizes small.
Font.register()
Register fonts globally. Works like react-pdf’sFont.register().
Options
Font.clear()
Remove all globally registered fonts. Useful in tests.Multiple weights in one call
You can register multiple weights for the same family using thefonts array syntax:
Google Fonts
You can register fonts directly from a URL. Google Fonts.woff2 URLs work:
Font fallback chains
Specify multiple font families separated by commas. Forme tries each family in order per character, so mixed-script text (e.g., English + Arabic) works automatically:Inter, Forme tries Noto Sans. If no font in the chain covers the character, the builtin Noto Sans is used as a final fallback.
Document fonts prop
Register fonts per-document instead of globally:Font sources
Thesrc option accepts three formats:
File paths are resolved relative to the template file in the CLI dev server (
forme dev), or relative to the working directory in renderDocument().
Standard fonts
The 14 built-in standard fonts (Helvetica, Times, Courier) are not embedded in the output PDF — viewers substitute metrically-identical system fonts. That’s fine for everyday documents, but PDF/UA and PDF/A require every font to be embedded: to use standard-font styling in compliance modes, register @formepdf/fonts-standard — metric-compatible TrueType replacements, so layout is identical. See Standard fonts for PDF/UA and PDF/A below.
Automatic fallback: When a character is not covered by your chosen font (e.g., Cyrillic or Greek text with Helvetica), Forme automatically falls back to Noto Sans. This means non-Latin text works out of the box without registering any fonts.
If a
fontFamily is not found, Forme falls back to Helvetica.
Example: Multiple weights
Troubleshooting
Text renders in Helvetica instead of my custom font
ThefontFamily in your style must exactly match the family you passed to Font.register(). Font names are case-sensitive.
Bold or italic text falls back to Helvetica
You need to register each weight and style variant separately. If you register only the regular weight and usefontWeight: 700, Forme will look for a bold variant, not find one, and fall back.
Non-Latin characters show as boxes or question marks
The font you’re using doesn’t cover those characters. Either:- Register a font that covers them (e.g., Noto Sans for broad Unicode support)
- Use a font fallback chain:
fontFamily: 'Inter, Noto Sans' - Do nothing — Forme’s builtin Noto Sans provides automatic fallback for most scripts
Standard fonts for PDF/UA and PDF/A
Accessible (PDF/UA) and archival (PDF/A) PDFs require every font embedded. The 14 standard PDF fonts (Helvetica, Times, Courier) are not embedded — viewers substitute them — so a document that relies on them cannot conform, and it also renders differently across machines.@formepdf/fonts-standard provides the Liberation family (Sans/Serif/Mono), which is metric-compatible with Helvetica/Times/Courier. Register it and enable pdfUa, and Forme embeds Liberation in place of the standard fonts — with the standard fonts’ own metrics, so layout does not change:
pdfUa is set and a standard font is used but the package isn’t registered, Forme still emits the PDF but warns by name with the remedy — it never silently ships a non-conforming file.
The fonts are redistributed unmodified under the SIL Open Font License 1.1.