diff --git a/.changeset/clean-brooms-drum.md b/.changeset/clean-brooms-drum.md new file mode 100644 index 0000000000..6dfef23823 --- /dev/null +++ b/.changeset/clean-brooms-drum.md @@ -0,0 +1,5 @@ +--- +"@astrojs/starlight": patch +--- + +Improves build performance slightly for bigger sites diff --git a/packages/starlight/user-components/FileTree.astro b/packages/starlight/user-components/FileTree.astro index 5331146c6a..1e079cf2cd 100644 --- a/packages/starlight/user-components/FileTree.astro +++ b/packages/starlight/user-components/FileTree.astro @@ -1,9 +1,10 @@ --- +import { stripLeadingAndTrailingSlashes } from '../utils/path'; import { slugToLocaleData } from '../utils/slugs'; import { useTranslations } from '../utils/translations'; import { processFileTree } from './rehype-file-tree'; -const slug = Astro.url.pathname.replace(/^\//, '').replace(/\/$/, ''); +const slug = stripLeadingAndTrailingSlashes(Astro.url.pathname); const t = useTranslations(slugToLocaleData(slug).locale); const fileTreeHtml = await Astro.slots.render('default'); diff --git a/packages/starlight/utils/localizedUrl.ts b/packages/starlight/utils/localizedUrl.ts index 95e35f9d98..e6df9068ec 100644 --- a/packages/starlight/utils/localizedUrl.ts +++ b/packages/starlight/utils/localizedUrl.ts @@ -1,4 +1,5 @@ import config from 'virtual:starlight/user-config'; +import { stripTrailingSlash } from './path'; /** * Get the equivalent of the passed URL for the passed locale. @@ -12,7 +13,7 @@ export function localizedUrl(url: URL, locale: string | undefined): URL { } if (locale === 'root') locale = ''; /** Base URL with trailing `/` stripped. */ - const base = import.meta.env.BASE_URL.replace(/\/$/, ''); + const base = stripTrailingSlash(import.meta.env.BASE_URL); const hasBase = url.pathname.startsWith(base); // Temporarily remove base to simplify if (hasBase) url.pathname = url.pathname.replace(base, ''); diff --git a/packages/starlight/utils/navigation.ts b/packages/starlight/utils/navigation.ts index 987e89e40c..43369be032 100644 --- a/packages/starlight/utils/navigation.ts +++ b/packages/starlight/utils/navigation.ts @@ -139,10 +139,10 @@ function linkFromInternalSidebarLinkItem( locale: string | undefined, currentPathname: string ) { - let slugWithLocale = locale ? locale + '/' + item.slug : item.slug; // Astro passes root `index.[md|mdx]` entries with a slug of `index` - slugWithLocale = slugWithLocale.replace(/\/?index$/, ''); - const entry = routes.find((entry) => slugWithLocale === entry.slug); + const slug = item.slug === 'index' ? '' : item.slug; + const localizedSlug = locale ? (slug ? locale + '/' + slug : locale) : slug; + const entry = routes.find((entry) => localizedSlug === entry.slug); if (!entry) { const hasExternalSlashes = item.slug.at(0) === '/' || item.slug.at(-1) === '/'; if (hasExternalSlashes) { @@ -410,4 +410,7 @@ function applyPrevNextLinkConfig( } /** Remove the extension from a path. */ -const stripExtension = (path: string) => path.replace(/\.\w+$/, ''); +function stripExtension(path: string) { + const periodIndex = path.lastIndexOf('.'); + return path.slice(0, periodIndex > -1 ? periodIndex : undefined); +} diff --git a/packages/starlight/utils/slugs.ts b/packages/starlight/utils/slugs.ts index 8a7cbd70ec..afe971ba3b 100644 --- a/packages/starlight/utils/slugs.ts +++ b/packages/starlight/utils/slugs.ts @@ -1,5 +1,6 @@ import config from 'virtual:starlight/user-config'; import { BuiltInDefaultLocale } from './i18n'; +import { stripTrailingSlash } from './path'; export interface LocaleData { /** Writing direction. */ @@ -52,7 +53,7 @@ export function slugToParam(slug: string): string | undefined { return slug === 'index' || slug === '' ? undefined : slug.endsWith('/index') - ? slug.replace(/\/index$/, '') + ? slug.slice(0, -6) : slug; } @@ -77,7 +78,7 @@ export function localizedSlug(slug: string, locale: string | undefined): string locale = locale || ''; if (slugLocale === slug) return locale; if (slugLocale) { - return slug.replace(slugLocale + '/', locale ? locale + '/' : '').replace(/\/$/, ''); + return stripTrailingSlash(slug.replace(slugLocale + '/', locale ? locale + '/' : '')); } return slug ? locale + '/' + slug : locale; } @@ -106,7 +107,7 @@ export function localizedId(id: string, locale: string | undefined): string { /** Extract the slug from a URL. */ export function urlToSlug(url: URL): string { let pathname = url.pathname; - const base = import.meta.env.BASE_URL.replace(/\/$/, ''); + const base = stripTrailingSlash(import.meta.env.BASE_URL); if (pathname.startsWith(base)) pathname = pathname.replace(base, ''); const segments = pathname.split('/'); const htmlExt = '.html';