From dbd769dc58b9fb5b57d8fcf2ad1b4c5549e64496 Mon Sep 17 00:00:00 2001 From: Florian Lefebvre Date: Thu, 17 Apr 2025 13:53:28 +0200 Subject: [PATCH] fix(fonts): do not filter sources --- .changeset/lucky-rocks-return.md | 5 +++ packages/astro/src/assets/fonts/load.ts | 59 +++++++++++++++---------- 2 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 .changeset/lucky-rocks-return.md diff --git a/.changeset/lucky-rocks-return.md b/.changeset/lucky-rocks-return.md new file mode 100644 index 000000000000..b1618d6e22f8 --- /dev/null +++ b/.changeset/lucky-rocks-return.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a case where extra font sources were removed when using the experimental fonts API diff --git a/packages/astro/src/assets/fonts/load.ts b/packages/astro/src/assets/fonts/load.ts index 3992ccf398c7..2fe6059d711d 100644 --- a/packages/astro/src/assets/fonts/load.ts +++ b/packages/astro/src/assets/fonts/load.ts @@ -53,11 +53,16 @@ export async function loadFonts({ // When going through the urls/filepaths returned by providers, // We save the hash and the associated original value so we can use // it in the vite middleware during development - const collect: ProxyURLOptions['collect'] = ({ hash, type, value }) => { + const collect = ( + { hash, type, value }: Parameters[0], + collectPreload: boolean, + ): ReturnType => { const url = base + hash; if (!hashToUrlMap.has(hash)) { hashToUrlMap.set(hash, value); - preloadData.push({ url, type }); + if (collectPreload) { + preloadData.push({ url, type }); + } } // If a family has fallbacks, we store the first url we get that may // be used for the fallback generation, if capsize doesn't have this @@ -90,7 +95,7 @@ export async function loadFonts({ } return hashString(v + content); }, - collect, + collect: (data) => collect(data, true), }); }, }); @@ -117,27 +122,33 @@ export async function loadFonts({ typeof font.meta?.priority === 'number' ? font.meta.priority === 0 : true, ) // Collect URLs - .map((font) => ({ - ...font, - src: font.src - // Limit src to 1 file (eg. if woff2 and woff are present, will only take woff2) to avoid - // downloading too many files - .slice(0, 1) - .map((source) => - 'name' in source - ? source - : { - ...source, - originalURL: source.url, - url: proxyURL({ - value: source.url, - // We only use the url for hashing since the service returns urls with a hash already - hashString, - collect, - }), - }, - ), - })); + .map((font) => { + // The index keeps track of encountered URLs. We can't use the index on font.src.map + // below because it may contain sources without urls, which would prevent preloading completely + let index = 0; + return { + ...font, + src: font.src.map((source) => { + if ('name' in source) { + return source; + } + const proxied = { + ...source, + originalURL: source.url, + url: proxyURL({ + value: source.url, + // We only use the url for hashing since the service returns urls with a hash already + hashString, + // We only collect the first URL to avoid preloading fallback sources (eg. we only + // preload woff2 if woff is available) + collect: (data) => collect(data, index === 0), + }), + }; + index++; + return proxied; + }), + }; + }); } for (const data of fonts) {