Skip to content

Commit 30f6e7f

Browse files
authored
Fix support for using an absolute URL for favicons (#3603)
1 parent eb9a7a8 commit 30f6e7f

6 files changed

Lines changed: 40 additions & 6 deletions

File tree

.changeset/giant-worms-help.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@astrojs/starlight': patch
3+
---
4+
5+
Fixes support for providing an absolute URL to Starlight’s `favicon` configuration option
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { expect, test, vi } from 'vitest';
2+
import { routes } from '../../utils/routing';
3+
import { generateRouteData } from '../../utils/routing/data';
4+
import { getRouteDataTestContext } from '../test-utils';
5+
6+
vi.mock('astro:content', async () =>
7+
(await import('../test-utils')).mockedAstroContent({
8+
docs: [['index.mdx', { title: 'Home Page' }]],
9+
})
10+
);
11+
12+
test('places the default favicon below any user provided icons', () => {
13+
const { head } = generateRouteData({
14+
props: { ...routes[0]!, headings: [] },
15+
context: getRouteDataTestContext(),
16+
});
17+
const faviconEntry = head.find((tag) => tag.tag === 'link' && tag.attrs?.rel === 'shortcut icon');
18+
19+
expect(faviconEntry?.attrs?.href).toBe('https://example.com/favicon.ico');
20+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { defineVitestConfig } from '../test-config';
2+
3+
export default defineVitestConfig({
4+
title: 'Docs With Absolute favicon',
5+
favicon: 'https://example.com/favicon.ico',
6+
});

packages/starlight/utils/head.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { PageProps, RouteDataContext } from './routing/data';
66
import { fileWithBase } from './base';
77
import { formatCanonical } from './canonical';
88
import { localizedUrl } from './localizedUrl';
9+
import { isAbsoluteUrl } from './url';
910

1011
const HeadSchema = HeadConfigSchema({ source: 'content' });
1112

@@ -46,7 +47,7 @@ export function getHead(
4647
tag: 'link',
4748
attrs: {
4849
rel: 'shortcut icon',
49-
href: fileWithBase(config.favicon.href),
50+
href: isAbsoluteUrl(config.favicon.href) ? config.favicon.href : fileWithBase(config.favicon.href),
5051
type: config.favicon.type,
5152
},
5253
},

packages/starlight/utils/navigation.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import type {
2929
SidebarEntry,
3030
} from './routing/types';
3131
import { localeToLang, localizedId, slugToPathname } from './slugs';
32+
import { isAbsoluteUrl } from './url';
3233
import type { StarlightConfig } from './user-config';
3334

3435
const DirKey = Symbol('DirKey');
@@ -124,13 +125,10 @@ function groupFromAutogenerateConfig(
124125
};
125126
}
126127

127-
/** Check if a string starts with one of `http://` or `https://`. */
128-
const isAbsolute = (link: string) => /^https?:\/\//.test(link);
129-
130128
/** Create a link entry from a manual link item in user config. */
131129
function linkFromSidebarLinkItem(item: SidebarLinkItem, locale: string | undefined) {
132130
let href = item.link;
133-
if (!isAbsolute(href)) {
131+
if (!isAbsoluteUrl(href)) {
134132
href = ensureLeadingSlash(href);
135133
// Inject current locale into link.
136134
if (locale) href = '/' + locale + href;
@@ -186,7 +184,7 @@ function makeSidebarLink(
186184
badge?: Badge,
187185
attrs?: LinkHTMLAttributes
188186
): SidebarLink {
189-
if (!isAbsolute(href)) {
187+
if (!isAbsoluteUrl(href)) {
190188
href = formatPath(href);
191189
}
192190
return makeLink({ label, href, badge, attrs });

packages/starlight/utils/url.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const HTTPProtocolRegEx = /^https?:\/\//;
2+
3+
/** Check if a string starts with one of `http://` or `https://`. */
4+
export const isAbsoluteUrl = (link: string) => HTTPProtocolRegEx.test(link);

0 commit comments

Comments
 (0)