From 4c771307e0be6e9d66057de28ebab4c7d132148a Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Fri, 8 May 2026 00:51:07 +0200 Subject: [PATCH] fix: fallback to "IBM Plex Serif" when unknown font encountered --- packages/pdf/src/document.tsx | 14 +++++--- packages/pdf/src/hooks/use-register-fonts.ts | 35 ++++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/pdf/src/document.tsx b/packages/pdf/src/document.tsx index b8a0b8601..019a32140 100644 --- a/packages/pdf/src/document.tsx +++ b/packages/pdf/src/document.tsx @@ -22,12 +22,18 @@ export type ResumeDocumentProps = { export const ResumeDocument = ({ data, template, resolveSectionTitle }: ResumeDocumentProps) => { const TemplatePageComponent = getTemplatePage(template); - registerFonts(data.metadata.typography); + const typography = registerFonts(data.metadata.typography); + const resumeData = + typography === data.metadata.typography ? data : { ...data, metadata: { ...data.metadata, typography } }; return ( - - - {data.metadata.layout.pages.map((page, index) => ( + + + {resumeData.metadata.layout.pages.map((page, index) => ( ))} diff --git a/packages/pdf/src/hooks/use-register-fonts.ts b/packages/pdf/src/hooks/use-register-fonts.ts index a42401334..ba70b4922 100644 --- a/packages/pdf/src/hooks/use-register-fonts.ts +++ b/packages/pdf/src/hooks/use-register-fonts.ts @@ -1,7 +1,7 @@ import type { FontWeight } from "@reactive-resume/fonts"; import type { Typography } from "@reactive-resume/schema/resume/data"; import { Font } from "@react-pdf/renderer"; -import { getWebFontSource, isStandardPdfFontFamily } from "@reactive-resume/fonts"; +import { getFont, getWebFontSource, isStandardPdfFontFamily } from "@reactive-resume/fonts"; type FontWeightRange = { lowest: number; @@ -9,6 +9,7 @@ type FontWeightRange = { }; const registeredFontVariants = new Set(); +const fallbackFontFamily = "IBM Plex Serif"; const getFontWeightRange = (fontWeights: string[]): FontWeightRange => { const numericWeights = fontWeights.map(Number).filter((weight) => Number.isFinite(weight)); @@ -33,13 +34,33 @@ const toFontWeight = (weight: number): FontWeight => { return "900"; }; -export const registerFonts = (typography: Typography) => { +const resolvePdfFontFamily = (family: string) => { + return getFont(family) ? family : fallbackFontFamily; +}; + +const resolvePdfTypography = (typography: Typography): Typography => { + const bodyFontFamily = resolvePdfFontFamily(typography.body.fontFamily); + const headingFontFamily = resolvePdfFontFamily(typography.heading.fontFamily); + + if (bodyFontFamily === typography.body.fontFamily && headingFontFamily === typography.heading.fontFamily) { + return typography; + } + + return { + ...typography, + body: { ...typography.body, fontFamily: bodyFontFamily }, + heading: { ...typography.heading, fontFamily: headingFontFamily }, + }; +}; + +export const registerFonts = (typography: Typography): Typography => { Font.registerHyphenationCallback((word) => [word]); - const bodyFontFamily = typography.body.fontFamily; - const headingFontFamily = typography.heading.fontFamily; - const bodyRange = getFontWeightRange(typography.body.fontWeights); - const headingRange = getFontWeightRange(typography.heading.fontWeights); + const pdfTypography = resolvePdfTypography(typography); + const bodyFontFamily = pdfTypography.body.fontFamily; + const headingFontFamily = pdfTypography.heading.fontFamily; + const bodyRange = getFontWeightRange(pdfTypography.body.fontWeights); + const headingRange = getFontWeightRange(pdfTypography.heading.fontWeights); const registerFont = (family: string, weight: number, italic = false) => { if (isStandardPdfFontFamily(family)) return; @@ -62,4 +83,6 @@ export const registerFonts = (typography: Typography) => { registerFont(headingFontFamily, headingRange.lowest, italic); registerFont(headingFontFamily, headingRange.highest, italic); } + + return pdfTypography; };