Repository navigation
feat: expose resolveFamily in RenderSlideOptions to keep custom font families (textLayout: "svg") #461
Description
Problem
Our company templates use Lora and Inter. When we preview those decks in the browser with renderSlideToSvg(pres, slide, { textLayout: "svg" }), every text run comes out as font-family="Carlito": in svg mode each run's font goes through substituteFamily, which maps any family other than Calibri/Aptos, Cambria, Arial/Helvetica, Times and Courier/Consolas to Carlito. The original family name is lost before the SVG leaves the renderer, so the host has no way to supply the real font.
We render in svg mode because we sanitize the output and display it as an <img> (blob URL), with foreignObject forbidden. In that context the only fonts that load are @font-face rules embedded as data URIs inside the SVG — which we can do, as long as the family name survives.
Existing paths considered
RenderSlideOptions(0.15.0, latest) exposesmeasureText,textLayoutandbackground. None of them affects family resolution.textLayout: "foreignObject"keeps the name (browserFontFamily→"Lora", <default>), but it needsforeignObjectin the output, which our sanitizer removes for security, and it still depends on fonts installed on the viewer's machine.buildFontkitMeasurer({ fonts })from/noderegisters real font files, but only for measurement / the Node path; it doesn't change the family written to the SVG in the browser entry.- Post-processing the SVG can't recover the name: by then every unknown family is
Carlito.
Proposed solution
Expose the existing internal resolveFamily hook on RenderSlideOptions, so a host can keep the families it can supply:
interface RenderSlideOptions {
// …existing options
/** Maps a run's font (or theme face) to the family written to the SVG.
* Defaults to substituteFamily in svg mode. */
readonly resolveFamily?: (family: string | null) => string;
}
renderSlideToSvg(pres, slide, {
textLayout: 'svg',
resolveFamily: (f) => (f === 'Lora' || f === 'Inter' ? f : substituteFamily(f)),
measureText, // real metrics for those fonts, so wrapping matches
});We would then inject the @font-face data URIs ourselves.
Alternatives
- A
fonts: [{ family, src }]option that both keeps those families and emits the@font-facerules into the SVG. Friendlier, but it puts font loading/embedding inside the library;resolveFamilyis the smaller change and reuses a hook that already exists. - Patching
substituteFamilylocally (what we'll do in the meantime).
Scope and compatibility
Additive: the option is optional and the default stays substituteFamily, so current output is unchanged.
Confirmation
- I have read the project's "one way to do one thing" policy and confirmed
this proposal is not a parallel path to an existing capability. - I have searched existing issues (open and closed) and confirmed this is
not a duplicate. - I have a real, specific use case for this — not a hypothetical "could be
useful." - If I used an LLM to draft this issue, I have read and verified every
claim, including the "existing paths" section, and am willing to defend
the proposal in follow-up.
Activity
github-actions commentedon Oct 12, 2026
Hi @keurcien, thanks for the report.
This issue does not match the project's issue template, so it has been auto-closed. Specifically:
<!-- issue-template:bug:v1 -->or<!-- issue-template:feature:v1 -->). Please open this issue from the New issue page so the template is preserved.- [ ]items at the bottom of the template) has been removed. Please restore it.How to fix this
Please edit this issue and restore the template structure. Use the "New issue" page on this repository to start from the official form. When the template is restored, this workflow will reopen the issue automatically.
Why we enforce this
Templates exist so that maintainers can triage efficiently. Issues that omit the template — including reports generated by AI without verification — consume scarce maintainer time without producing actionable signal. Repeated low-effort or AI-slop submissions from the same account may result in being blocked from this repository.
If you believe this auto-close is in error, please leave a comment explaining and a maintainer will take a look.
[-]preview: expose font-family resolution / custom fonts in RenderSlideOptions (textLayout: "svg")[/-][+]feat: expose resolveFamily in RenderSlideOptions to keep custom font families (textLayout: "svg")[/+]github-actions commentedon Oct 12, 2026
Thanks for updating this — the template now looks valid. A maintainer will triage from here.
feat(preview): add resolveFamily to keep custom font families in svg …