From cf12beb91b4cb2f212dbcc0cc1ed56e79d055ff0 Mon Sep 17 00:00:00 2001 From: techfg Date: Wed, 4 Dec 2024 12:12:41 -0800 Subject: Fix favicon support for query and fragment in URLs (#2645) Co-authored-by: Chris Swithinbank --- .changeset/neat-deers-pretend.md | 5 ++++ packages/starlight/__tests__/basics/schema.test.ts | 27 ++++++++++++++++++++++ packages/starlight/schemas/favicon.ts | 4 +++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .changeset/neat-deers-pretend.md diff --git a/.changeset/neat-deers-pretend.md b/.changeset/neat-deers-pretend.md new file mode 100644 index 00000000..cec30a8c --- /dev/null +++ b/.changeset/neat-deers-pretend.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': patch +--- + +Fixes support for favicon URLs that contain a search query and/or hash diff --git a/packages/starlight/__tests__/basics/schema.test.ts b/packages/starlight/__tests__/basics/schema.test.ts index c3bd3530..29e870fd 100644 --- a/packages/starlight/__tests__/basics/schema.test.ts +++ b/packages/starlight/__tests__/basics/schema.test.ts @@ -12,6 +12,33 @@ describe('FaviconSchema', () => { expect(favicon.type).toBe('image/jpeg'); }); + test('returns the proper href and type attributes when contains query', () => { + const icon = '/custom-icon.gif?v=123456&x=987654'; + + const favicon = FaviconSchema().parse(icon); + + expect(favicon.href).toBe(icon); + expect(favicon.type).toBe('image/gif'); + }); + + test('returns the proper href and type attributes when contains fragment', () => { + const icon = '/custom-icon.png#favicon'; + + const favicon = FaviconSchema().parse(icon); + + expect(favicon.href).toBe(icon); + expect(favicon.type).toBe('image/png'); + }); + + test('returns the proper href and type attributes when contains query and fragment', () => { + const icon = '/custom-icon.ico?v=123456&x=987654#favicon'; + + const favicon = FaviconSchema().parse(icon); + + expect(favicon.href).toBe(icon); + expect(favicon.type).toBe('image/x-icon'); + }); + test('throws on invalid favicon extensions', () => { expect(() => FaviconSchema().parse('/favicon.pdf')).toThrow(); }); diff --git a/packages/starlight/schemas/favicon.ts b/packages/starlight/schemas/favicon.ts index 7f599099..b3b6a570 100644 --- a/packages/starlight/schemas/favicon.ts +++ b/packages/starlight/schemas/favicon.ts @@ -15,7 +15,9 @@ export const FaviconSchema = () => .string() .default('/favicon.svg') .transform((favicon, ctx) => { - const ext = extname(favicon).toLowerCase(); + // favicon can be absolute or relative url + const { pathname } = new URL(favicon, 'https://example.com'); + const ext = extname(pathname).toLowerCase(); if (!isFaviconExt(ext)) { ctx.addIssue({ -- cgit