diff --git a/packages/producer/src/services/deterministicFonts.ts b/packages/producer/src/services/deterministicFonts.ts index dcdab7b7..c9407d41 100644 --- a/packages/producer/src/services/deterministicFonts.ts +++ b/packages/producer/src/services/deterministicFonts.ts @@ -32,6 +32,136 @@ const GENERIC_FAMILIES = new Set([ "blinkmacsystemfont", ]); +/** + * Well-known OS system fonts that are pre-installed on Windows, macOS, and Linux. + * These do not need @font-face injection — the OS provides them directly. + * Without this list, font-family values like `'Courier New', Courier, monospace` + * cause the compiler to attempt Google Fonts resolution for "Courier New" and + * "Courier", which 404s in headless render environments and adds noise to output. + */ +const SYSTEM_FONTS = new Set([ + // Windows + "arial", + "arial black", + "arial narrow", + "bahnschrift", + "calibri", + "cambria", + "cambria math", + "candara", + "comic sans ms", + "consolas", + "constantia", + "corbel", + "courier", + "courier new", + "ebrima", + "franklin gothic medium", + "gabriola", + "gadugi", + "georgia", + "impact", + "javanese text", + "leelawadee ui", + "lucida console", + "lucida sans unicode", + "malgun gothic", + "marlett", + "microsoft himalaya", + "microsoft jheng hei", + "microsoft new tai lue", + "microsoft phagspa", + "microsoft sans serif", + "microsoft tai le", + "microsoft uighur", + "microsoft yahei", + "microsoft yi baiti", + "mingliu-extb", + "mongolian baiti", + "ms gothic", + "ms pgothic", + "ms ui gothic", + "mv boli", + "myanmar text", + "nirmala ui", + "palatino linotype", + "segoe mdl2 assets", + "segoe print", + "segoe script", + "segoe ui", + "segoe ui emoji", + "segoe ui historic", + "segoe ui symbol", + "simsun", + "sitka", + "sylfaen", + "symbol", + "tahoma", + "times new roman", + "trebuchet ms", + "verdana", + "webdings", + "wingdings", + "yu gothic", + // macOS / iOS + "helvetica", + "helvetica neue", + "sf pro", + "sf pro display", + "sf pro text", + "sf mono", + "sf compact", + "new york", + "lucida grande", + "monaco", + "menlo", + "optima", + "futura", + "gill sans", + "hoefler text", + "didot", + "baskerville", + "rockwell", + "american typewriter", + "apple chancery", + "apple color emoji", + "apple sd gothic neo", + "apple symbols", + "brush script mt", + "chalkboard", + "cochin", + "copperplate", + "papyrus", + "phosphate", + "marker felt", + "noteworthy", + "snell roundhand", + "zapf dingbats", + "zapfino", + // Linux / cross-platform + "dejavu sans", + "dejavu sans mono", + "dejavu serif", + "liberation mono", + "liberation sans", + "liberation serif", + "freemono", + "freesans", + "freeserif", + "nimbus mono ps", + "nimbus roman", + "nimbus sans", + "ubuntu", + "ubuntu mono", + "cantarell", + "droid sans", + "droid serif", + "droid sans mono", + "noto sans", + "noto serif", + "noto mono", +]); + const CANONICAL_FONTS: Record = { inter: { packageName: "@fontsource/inter", @@ -186,7 +316,7 @@ function extractRequestedFontFamilies(html: string): Map { .replace(/^['"]|['"]$/g, "") .trim(); const normalized = originalCase.toLowerCase(); - if (!normalized || GENERIC_FAMILIES.has(normalized)) { + if (!normalized || GENERIC_FAMILIES.has(normalized) || SYSTEM_FONTS.has(normalized)) { continue; } if (!requested.has(normalized)) {