diff --git a/.changeset/mean-lands-pull.md b/.changeset/mean-lands-pull.md new file mode 100644 index 000000000000..8e6e47d76270 --- /dev/null +++ b/.changeset/mean-lands-pull.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a case where font sources with relative protocol URLs would fail when using the experimental fonts API diff --git a/packages/astro/src/assets/fonts/logic/normalize-remote-font-faces.ts b/packages/astro/src/assets/fonts/logic/normalize-remote-font-faces.ts index c4689f0f77cd..80288feaa310 100644 --- a/packages/astro/src/assets/fonts/logic/normalize-remote-font-faces.ts +++ b/packages/astro/src/assets/fonts/logic/normalize-remote-font-faces.ts @@ -23,11 +23,14 @@ export function normalizeRemoteFontFaces({ if ('name' in source) { return source; } + // We handle protocol relative URLs here, otherwise they're considered absolute by the font + // fetcher which will try to read them from the file system + const url = source.url.startsWith('//') ? `https:${source.url}` : source.url; const proxied = { ...source, - originalURL: source.url, + originalURL: url, url: urlProxy.proxy({ - url: source.url, + url, // We only collect the first URL to avoid preloading fallback sources (eg. we only // preload woff2 if woff is available) collectPreload: index === 0, diff --git a/packages/astro/test/units/assets/fonts/logic.test.js b/packages/astro/test/units/assets/fonts/logic.test.js index 0fe637868bac..c99a1598efae 100644 --- a/packages/astro/test/units/assets/fonts/logic.test.js +++ b/packages/astro/test/units/assets/fonts/logic.test.js @@ -450,6 +450,54 @@ describe('fonts logic', () => { }, ]); }); + + it('turns relative protocols into https', () => { + const { collected, urlProxy } = createSpyUrlProxy(); + const fonts = normalizeRemoteFontFaces({ + urlProxy, + fonts: [ + { + weight: '400', + style: 'normal', + src: [{ url: '//example.com/font.woff2' }, { url: 'http://example.com/font.woff' }], + }, + ], + }); + + assert.deepStrictEqual( + fonts, + [ + { + src: [ + { + originalURL: 'https://example.com/font.woff2', + url: 'https://example.com/font.woff2', + }, + { + originalURL: 'http://example.com/font.woff', + url: 'http://example.com/font.woff', + }, + ], + style: 'normal', + weight: '400', + }, + ], + ); + assert.deepStrictEqual(collected, [ + { + url: 'https://example.com/font.woff2', + collectPreload: true, + data: { weight: '400', style: 'normal' }, + init: null, + }, + { + url: 'http://example.com/font.woff', + collectPreload: false, + data: { weight: '400', style: 'normal' }, + init: null, + }, + ]); + }); }); describe('optimizeFallbacks()', () => {