diff options
author | HiDeoo | 2024-11-01 16:03:11 +0100 |
---|---|---|
committer | GitHub | 2024-11-01 16:03:11 +0100 |
commit | 07673c80114021a269065e451e660337237f76e1 (patch) | |
tree | 2671a70e392821287bcb480d8f5ed1b1357b530d | |
parent | bf42300e76241a2df888dc458c59a7478a8b2d61 (diff) | |
download | IT.starlight-07673c80114021a269065e451e660337237f76e1.tar.gz IT.starlight-07673c80114021a269065e451e660337237f76e1.tar.bz2 IT.starlight-07673c80114021a269065e451e660337237f76e1.zip |
Fix invalid locale issue (#2548)
* fix: fallback to default locale in project without a root locale for pages not matching the default locale slug
* Update changeset
* refactor: remove duplicated `slugToLocale()`
---------
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
-rw-r--r-- | .changeset/great-toys-train.md | 5 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts | 21 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/routing.test.ts | 10 | ||||
-rw-r--r-- | packages/starlight/integrations/shared/pathToLocale.ts | 14 | ||||
-rw-r--r-- | packages/starlight/integrations/shared/slugToLocale.ts | 18 | ||||
-rw-r--r-- | packages/starlight/utils/slugs.ts | 6 |
6 files changed, 49 insertions, 25 deletions
diff --git a/.changeset/great-toys-train.md b/.changeset/great-toys-train.md new file mode 100644 index 00000000..0bef54b1 --- /dev/null +++ b/.changeset/great-toys-train.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': patch +--- + +Fixes a URL localization edge case. In projects without a root locale configured, slugs without a locale prefix did not fall back to the default locale as expected. diff --git a/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts b/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts index 5eae14d8..fae14a98 100644 --- a/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts @@ -7,6 +7,7 @@ vi.mock('astro:content', async () => ['fr/index.mdx', { title: 'Accueil' }], // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Home page' }], + ['404.md', { title: '404' }], ], }) ); @@ -17,16 +18,16 @@ test('route slugs are normalized', () => { }); test('routes for the configured locale have locale data added', () => { - for (const route of routes) { - if (route.id.startsWith('fr')) { - expect(route.lang).toBe('fr-CA'); - expect(route.dir).toBe('ltr'); - expect(route.locale).toBe('fr'); - } else { - expect(route.lang).toBe('fr-CA'); - expect(route.dir).toBe('ltr'); - expect(route.locale).toBeUndefined(); - } + expect(routes[0]?.lang).toBe('fr-CA'); + expect(routes[0]?.dir).toBe('ltr'); + expect(routes[0]?.locale).toBe('fr'); +}); + +test('routes not matching the configured locale fall back to the default locale', () => { + for (const route of routes.slice(1)) { + expect(route.lang).toBe('fr-CA'); + expect(route.dir).toBe('ltr'); + expect(route.locale).toBe('fr'); } }); diff --git a/packages/starlight/__tests__/i18n/routing.test.ts b/packages/starlight/__tests__/i18n/routing.test.ts index b854794b..8c025e2c 100644 --- a/packages/starlight/__tests__/i18n/routing.test.ts +++ b/packages/starlight/__tests__/i18n/routing.test.ts @@ -14,6 +14,8 @@ vi.mock('astro:content', async () => ['en/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }], // @ts-expect-error — Using a slug not present in Starlight docs site ['en/404.md', { title: 'Page introuvable' }], + ['it/index.mdx', { title: 'Pagina iniziale' }], + ['404.md', { title: '404' }], ], }) ); @@ -42,6 +44,14 @@ test('routes have locale data added', () => { expect(lang).toBe('fr'); expect(dir).toBe('ltr'); expect(locale).toBe('fr'); + } else if (id.startsWith('pt-br')) { + expect(lang).toBe('pt-BR'); + expect(dir).toBe('ltr'); + expect(locale).toBe('pt-br'); + } else { + expect(lang).toBe('en-US'); + expect(dir).toBe('ltr'); + expect(locale).toBe('en'); } } }); diff --git a/packages/starlight/integrations/shared/pathToLocale.ts b/packages/starlight/integrations/shared/pathToLocale.ts index 5c229a47..2ecb997c 100644 --- a/packages/starlight/integrations/shared/pathToLocale.ts +++ b/packages/starlight/integrations/shared/pathToLocale.ts @@ -1,14 +1,6 @@ import type { AstroConfig } from 'astro'; import type { StarlightConfig } from '../../types'; - -function slugToLocale( - slug: string | undefined, - localesConfig: StarlightConfig['locales'] -): string | undefined { - const locales = Object.keys(localesConfig || {}); - const baseSegment = slug?.split('/')[0]; - return baseSegment && locales.includes(baseSegment) ? baseSegment : undefined; -} +import { slugToLocale } from './slugToLocale'; /** Get current locale from the full file path. */ export function pathToLocale( @@ -17,7 +9,7 @@ export function pathToLocale( starlightConfig, astroConfig, }: { - starlightConfig: { locales: StarlightConfig['locales'] }; + starlightConfig: Pick<StarlightConfig, 'defaultLocale' | 'locales'>; astroConfig: { root: AstroConfig['root']; srcDir: AstroConfig['srcDir'] }; } ): string | undefined { @@ -31,5 +23,5 @@ export function pathToLocale( // Strip docs path leaving only content collection file ID. // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md const slug = path?.replace(docsDir.pathname, ''); - return slugToLocale(slug, starlightConfig.locales); + return slugToLocale(slug, starlightConfig); } diff --git a/packages/starlight/integrations/shared/slugToLocale.ts b/packages/starlight/integrations/shared/slugToLocale.ts new file mode 100644 index 00000000..69e1f3bc --- /dev/null +++ b/packages/starlight/integrations/shared/slugToLocale.ts @@ -0,0 +1,18 @@ +import type { StarlightConfig } from '../../types'; + +/** + * Get the “locale” of a slug. This is the base path at which a language is served. + * For example, if French docs are in `src/content/docs/french/`, the locale is `french`. + * Root locale slugs will return `undefined`. + * @param slug A collection entry slug + */ +export function slugToLocale( + slug: string | undefined, + config: Pick<StarlightConfig, 'defaultLocale' | 'locales'> +): string | undefined { + const localesConfig = config.locales ?? {}; + const baseSegment = slug?.split('/')[0]; + if (baseSegment && localesConfig[baseSegment]) return baseSegment; + if (!localesConfig.root) return config.defaultLocale.locale; + return undefined; +} diff --git a/packages/starlight/utils/slugs.ts b/packages/starlight/utils/slugs.ts index afe971ba..e74d6841 100644 --- a/packages/starlight/utils/slugs.ts +++ b/packages/starlight/utils/slugs.ts @@ -1,6 +1,7 @@ import config from 'virtual:starlight/user-config'; import { BuiltInDefaultLocale } from './i18n'; import { stripTrailingSlash } from './path'; +import { slugToLocale as getLocaleFromSlug } from '../integrations/shared/slugToLocale'; export interface LocaleData { /** Writing direction. */ @@ -18,10 +19,7 @@ export interface LocaleData { * @param slug A collection entry slug */ function slugToLocale(slug: string): string | undefined { - const locales = Object.keys(config.locales || {}); - const baseSegment = slug.split('/')[0]; - if (baseSegment && locales.includes(baseSegment)) return baseSegment; - return undefined; + return getLocaleFromSlug(slug, config); } /** Get locale information for a given slug. */ |