Skip to content

Commit e7b0e74

Browse files
HiDeoodelucis
andauthoredJan 7, 2025··
Fix translation issue for languages with a region subtag (#2757)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
1 parent d56bda7 commit e7b0e74

File tree

7 files changed

+47
-23
lines changed

7 files changed

+47
-23
lines changed
 

‎.changeset/brave-kings-vanish.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@astrojs/starlight': patch
3+
---
4+
5+
Fixes a UI string translation issue for languages with a region subtag.

‎packages/starlight/__tests__/test-utils.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ function mockDoc(
5252

5353
function mockDict(id: string, data: z.input<ReturnType<typeof i18nSchema>>) {
5454
return {
55-
id,
55+
id: project.legacyCollections ? id : id.toLocaleLowerCase(),
5656
data: i18nSchema().parse(data),
57+
filePath: project.legacyCollections ? undefined : `src/content/i18n/${id}.yml`,
5758
};
5859
}
5960

‎packages/starlight/utils/navigation.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ import type {
1313
import { createPathFormatter } from './createPathFormatter';
1414
import { formatPath } from './format-path';
1515
import { BuiltInDefaultLocale, pickLang } from './i18n';
16-
import { ensureLeadingSlash, ensureTrailingSlash, stripLeadingAndTrailingSlashes } from './path';
16+
import {
17+
ensureLeadingSlash,
18+
ensureTrailingSlash,
19+
stripExtension,
20+
stripLeadingAndTrailingSlashes,
21+
} from './path';
1722
import { getLocaleRoutes, routes, type Route } from './routing';
1823
import { localeToLang, localizedId, slugToPathname } from './slugs';
1924
import type { StarlightConfig } from './user-config';
@@ -510,12 +515,6 @@ function applyPrevNextLinkConfig(
510515
return paginationEnabled ? link : undefined;
511516
}
512517

513-
/** Remove the extension from a path. */
514-
function stripExtension(path: string) {
515-
const periodIndex = path.lastIndexOf('.');
516-
return path.slice(0, periodIndex > -1 ? periodIndex : undefined);
517-
}
518-
519518
/** Get a sidebar badge for a given item. */
520519
function getSidebarBadge(
521520
config: I18nBadgeConfig,

‎packages/starlight/utils/path.ts

+6
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,9 @@ export function ensureHtmlExtension(path: string) {
5050
}
5151
return ensureLeadingSlash(path);
5252
}
53+
54+
/** Remove the extension from a path. */
55+
export function stripExtension(path: string) {
56+
const periodIndex = path.lastIndexOf('.');
57+
return path.slice(0, periodIndex > -1 ? periodIndex : undefined);
58+
}

‎packages/starlight/utils/translations.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
11
import { getCollection, type CollectionEntry, type DataCollectionKey } from 'astro:content';
22
import config from 'virtual:starlight/user-config';
3+
import project from 'virtual:starlight/project-context';
34
import pluginTranslations from 'virtual:starlight/plugin-translations';
45
import type { i18nSchemaOutput } from '../schemas/i18n';
56
import { createTranslationSystem } from './createTranslationSystem';
67
import type { RemoveIndexSignature } from './types';
8+
import { getCollectionPathFromRoot } from './collection';
9+
import { stripExtension, stripLeadingSlash } from './path';
710

811
// @ts-ignore - This may be a type error in projects without an i18n collection and running
912
// `tsc --noEmit` in their project. Note that it is not possible to inline this type in
1013
// `UserI18nSchema` because this would break types for users having multiple data collections.
1114
type i18nCollection = CollectionEntry<'i18n'>;
1215

16+
const i18nCollectionPathFromRoot = getCollectionPathFromRoot('i18n', project);
17+
1318
export type UserI18nSchema = 'i18n' extends DataCollectionKey
1419
? i18nCollection extends { data: infer T }
1520
? i18nSchemaOutput & T
1621
: i18nSchemaOutput
1722
: i18nSchemaOutput;
1823
export type UserI18nKeys = keyof RemoveIndexSignature<UserI18nSchema>;
1924

20-
/** Get all translation data from the i18n collection, keyed by `id`, which matches locale. */
25+
/** Get all translation data from the i18n collection, keyed by `lang`, which are BCP-47 language tags. */
2126
async function loadTranslations() {
2227
// Briefly override `console.warn()` to silence logging when a project has no i18n collection.
2328
const warn = console.warn;
2429
console.warn = () => {};
2530
const userTranslations: Record<string, UserI18nSchema> = Object.fromEntries(
2631
// @ts-ignore — may be a type error in projects without an i18n collection
27-
(await getCollection('i18n')).map(({ id, data }) => [id, data] as const)
32+
(await getCollection('i18n')).map(({ id, data, filePath }) => {
33+
const lang =
34+
project.legacyCollections || !filePath
35+
? id
36+
: stripExtension(stripLeadingSlash(filePath.replace(i18nCollectionPathFromRoot, '')));
37+
return [lang, data] as const;
38+
})
2839
);
2940
// Restore the original warn implementation.
3041
console.warn = warn;

‎packages/starlight/virtual-internal.d.ts

-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
declare module 'virtual:starlight/project-context' {
2-
const ProjectContext: {
3-
root: string;
4-
srcDir: string;
5-
trailingSlash: import('astro').AstroConfig['trailingSlash'];
6-
build: {
7-
format: import('astro').AstroConfig['build']['format'];
8-
};
9-
legacyCollections: boolean;
10-
};
11-
export default ProjectContext;
12-
}
13-
141
declare module 'virtual:starlight/git-info' {
152
export function getNewestCommitDate(file: string): Date;
163
}

‎packages/starlight/virtual.d.ts

+15
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,18 @@ declare module 'virtual:starlight/plugin-translations' {
77
const PluginTranslations: import('./utils/plugins').PluginTranslations;
88
export default PluginTranslations;
99
}
10+
11+
// TODO: Move back to `virtual-internal.d.ts` when possible. For example, when dropping support for
12+
// legacy collections, `utils/translations.ts` would no longer need to import project context.
13+
declare module 'virtual:starlight/project-context' {
14+
const ProjectContext: {
15+
root: string;
16+
srcDir: string;
17+
trailingSlash: import('astro').AstroConfig['trailingSlash'];
18+
build: {
19+
format: import('astro').AstroConfig['build']['format'];
20+
};
21+
legacyCollections: boolean;
22+
};
23+
export default ProjectContext;
24+
}

0 commit comments

Comments
 (0)
Please sign in to comment.