summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiDeoo2025-01-07 15:35:33 +0100
committerGitHub2025-01-07 15:35:33 +0100
commite7b0e742dffb7c4a8f4619297e4bd6e5a8015edb (patch)
treefad758ebd6721599e62f7687988cec795d69c23a
parentd56bda7cf754557a32926c617ff2c103208ae688 (diff)
downloadIT.starlight-e7b0e742dffb7c4a8f4619297e4bd6e5a8015edb.tar.gz
IT.starlight-e7b0e742dffb7c4a8f4619297e4bd6e5a8015edb.tar.bz2
IT.starlight-e7b0e742dffb7c4a8f4619297e4bd6e5a8015edb.zip
Fix translation issue for languages with a region subtag (#2757)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
-rw-r--r--.changeset/brave-kings-vanish.md5
-rw-r--r--packages/starlight/__tests__/test-utils.ts3
-rw-r--r--packages/starlight/utils/navigation.ts13
-rw-r--r--packages/starlight/utils/path.ts6
-rw-r--r--packages/starlight/utils/translations.ts15
-rw-r--r--packages/starlight/virtual-internal.d.ts13
-rw-r--r--packages/starlight/virtual.d.ts15
7 files changed, 47 insertions, 23 deletions
diff --git a/.changeset/brave-kings-vanish.md b/.changeset/brave-kings-vanish.md
new file mode 100644
index 00000000..22a63b76
--- /dev/null
+++ b/.changeset/brave-kings-vanish.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/starlight': patch
+---
+
+Fixes a UI string translation issue for languages with a region subtag.
diff --git a/packages/starlight/__tests__/test-utils.ts b/packages/starlight/__tests__/test-utils.ts
index d6e3a711..12ebc804 100644
--- a/packages/starlight/__tests__/test-utils.ts
+++ b/packages/starlight/__tests__/test-utils.ts
@@ -52,8 +52,9 @@ function mockDoc(
function mockDict(id: string, data: z.input<ReturnType<typeof i18nSchema>>) {
return {
- id,
+ id: project.legacyCollections ? id : id.toLocaleLowerCase(),
data: i18nSchema().parse(data),
+ filePath: project.legacyCollections ? undefined : `src/content/i18n/${id}.yml`,
};
}
diff --git a/packages/starlight/utils/navigation.ts b/packages/starlight/utils/navigation.ts
index 0944eb5d..37184627 100644
--- a/packages/starlight/utils/navigation.ts
+++ b/packages/starlight/utils/navigation.ts
@@ -13,7 +13,12 @@ import type {
import { createPathFormatter } from './createPathFormatter';
import { formatPath } from './format-path';
import { BuiltInDefaultLocale, pickLang } from './i18n';
-import { ensureLeadingSlash, ensureTrailingSlash, stripLeadingAndTrailingSlashes } from './path';
+import {
+ ensureLeadingSlash,
+ ensureTrailingSlash,
+ stripExtension,
+ stripLeadingAndTrailingSlashes,
+} from './path';
import { getLocaleRoutes, routes, type Route } from './routing';
import { localeToLang, localizedId, slugToPathname } from './slugs';
import type { StarlightConfig } from './user-config';
@@ -510,12 +515,6 @@ function applyPrevNextLinkConfig(
return paginationEnabled ? link : undefined;
}
-/** Remove the extension from a path. */
-function stripExtension(path: string) {
- const periodIndex = path.lastIndexOf('.');
- return path.slice(0, periodIndex > -1 ? periodIndex : undefined);
-}
-
/** Get a sidebar badge for a given item. */
function getSidebarBadge(
config: I18nBadgeConfig,
diff --git a/packages/starlight/utils/path.ts b/packages/starlight/utils/path.ts
index 68b1f5c2..cf30d038 100644
--- a/packages/starlight/utils/path.ts
+++ b/packages/starlight/utils/path.ts
@@ -50,3 +50,9 @@ export function ensureHtmlExtension(path: string) {
}
return ensureLeadingSlash(path);
}
+
+/** Remove the extension from a path. */
+export function stripExtension(path: string) {
+ const periodIndex = path.lastIndexOf('.');
+ return path.slice(0, periodIndex > -1 ? periodIndex : undefined);
+}
diff --git a/packages/starlight/utils/translations.ts b/packages/starlight/utils/translations.ts
index 499ded29..71ce6e72 100644
--- a/packages/starlight/utils/translations.ts
+++ b/packages/starlight/utils/translations.ts
@@ -1,15 +1,20 @@
import { getCollection, type CollectionEntry, type DataCollectionKey } from 'astro:content';
import config from 'virtual:starlight/user-config';
+import project from 'virtual:starlight/project-context';
import pluginTranslations from 'virtual:starlight/plugin-translations';
import type { i18nSchemaOutput } from '../schemas/i18n';
import { createTranslationSystem } from './createTranslationSystem';
import type { RemoveIndexSignature } from './types';
+import { getCollectionPathFromRoot } from './collection';
+import { stripExtension, stripLeadingSlash } from './path';
// @ts-ignore - This may be a type error in projects without an i18n collection and running
// `tsc --noEmit` in their project. Note that it is not possible to inline this type in
// `UserI18nSchema` because this would break types for users having multiple data collections.
type i18nCollection = CollectionEntry<'i18n'>;
+const i18nCollectionPathFromRoot = getCollectionPathFromRoot('i18n', project);
+
export type UserI18nSchema = 'i18n' extends DataCollectionKey
? i18nCollection extends { data: infer T }
? i18nSchemaOutput & T
@@ -17,14 +22,20 @@ export type UserI18nSchema = 'i18n' extends DataCollectionKey
: i18nSchemaOutput;
export type UserI18nKeys = keyof RemoveIndexSignature<UserI18nSchema>;
-/** Get all translation data from the i18n collection, keyed by `id`, which matches locale. */
+/** Get all translation data from the i18n collection, keyed by `lang`, which are BCP-47 language tags. */
async function loadTranslations() {
// Briefly override `console.warn()` to silence logging when a project has no i18n collection.
const warn = console.warn;
console.warn = () => {};
const userTranslations: Record<string, UserI18nSchema> = Object.fromEntries(
// @ts-ignore — may be a type error in projects without an i18n collection
- (await getCollection('i18n')).map(({ id, data }) => [id, data] as const)
+ (await getCollection('i18n')).map(({ id, data, filePath }) => {
+ const lang =
+ project.legacyCollections || !filePath
+ ? id
+ : stripExtension(stripLeadingSlash(filePath.replace(i18nCollectionPathFromRoot, '')));
+ return [lang, data] as const;
+ })
);
// Restore the original warn implementation.
console.warn = warn;
diff --git a/packages/starlight/virtual-internal.d.ts b/packages/starlight/virtual-internal.d.ts
index 3c4d5ef9..10292513 100644
--- a/packages/starlight/virtual-internal.d.ts
+++ b/packages/starlight/virtual-internal.d.ts
@@ -1,16 +1,3 @@
-declare module 'virtual:starlight/project-context' {
- const ProjectContext: {
- root: string;
- srcDir: string;
- trailingSlash: import('astro').AstroConfig['trailingSlash'];
- build: {
- format: import('astro').AstroConfig['build']['format'];
- };
- legacyCollections: boolean;
- };
- export default ProjectContext;
-}
-
declare module 'virtual:starlight/git-info' {
export function getNewestCommitDate(file: string): Date;
}
diff --git a/packages/starlight/virtual.d.ts b/packages/starlight/virtual.d.ts
index 17ed33d5..5ff0c53c 100644
--- a/packages/starlight/virtual.d.ts
+++ b/packages/starlight/virtual.d.ts
@@ -7,3 +7,18 @@ declare module 'virtual:starlight/plugin-translations' {
const PluginTranslations: import('./utils/plugins').PluginTranslations;
export default PluginTranslations;
}
+
+// TODO: Move back to `virtual-internal.d.ts` when possible. For example, when dropping support for
+// legacy collections, `utils/translations.ts` would no longer need to import project context.
+declare module 'virtual:starlight/project-context' {
+ const ProjectContext: {
+ root: string;
+ srcDir: string;
+ trailingSlash: import('astro').AstroConfig['trailingSlash'];
+ build: {
+ format: import('astro').AstroConfig['build']['format'];
+ };
+ legacyCollections: boolean;
+ };
+ export default ProjectContext;
+}