refactor(downloadFont): handle generic families and multi-family strings

Strips generic CSS families (serif, monospace, etc.) before building
the font API URL, and correctly parses comma-separated font stacks.
This commit is contained in:
Julien Calixte
2026-04-27 10:12:12 +02:00
parent 78de5e280f
commit d50adc72e9

View File

@@ -1,33 +1,48 @@
import FontFaceObserver from "fontfaceobserver"
const assembleFontLink = (font: string) => {
return `https://api.fonts.coollabs.io/css2?display=swap&family=${font
.replaceAll(",", "&family=")
.replaceAll(" ", "+")}`
const GENERIC_FAMILIES = new Set([
"serif", "sans-serif", "monospace", "cursive", "fantasy",
"system-ui", "ui-serif", "ui-sans-serif", "ui-monospace", "ui-rounded",
])
const parseWebFontFamilies = (font: string): string[] =>
font
.split(",")
.map(f => f.trim().replace(/^["']|["']$/g, ""))
.filter(f => f && !GENERIC_FAMILIES.has(f))
const assembleFontLink = (families: string[]): string | null => {
if (families.length === 0) return null
return `https://api.fonts.coollabs.io/css2?display=swap&${
families.map(f => `family=${f.replaceAll(" ", "+")}`).join("&")
}`
}
export const downloadFont = async (
font: string,
cssVar = "--font-family"
): Promise<void> => {
const href = assembleFontLink(font)
const families = parseWebFontFamilies(font)
const href = assembleFontLink(families)
// check if the href already exists
const existingLink = document.querySelector(`link[href="${href}"]`)
if (href) {
const alreadyLoaded = Array.from(
document.head.querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]')
).some(link => link.href === href)
if (!existingLink) {
const link = document.createElement("link")
link.href = href
link.rel = "stylesheet"
if (!alreadyLoaded) {
const link = document.createElement("link")
link.href = href
link.rel = "stylesheet"
document.head.appendChild(link)
}
document.head.appendChild(link)
try {
await new FontFaceObserver(families[0]).load()
} catch {
console.warn("error when loading font")
}
}
try {
await new FontFaceObserver(font).load()
document.documentElement.style.setProperty(cssVar, font)
} catch (error) {
console.warn("error when loading font")
}
document.documentElement.style.setProperty(cssVar, font)
}