Skip to content

Commit 76b2824

Browse files
feat(navigation): localize nav labels and header routes for all locales
Replace the labelEn field with a translations record covering all ten docs locales. Update StarlightHeader to resolve locale via parseDocsLocale and build home/blog links with buildDocsRoutePath. Add a test asserting every locale receives localized nav links. Co-Authored-By: Hagicode <noreply@hagicode.com> Signed-off-by: newbe36524 <newbe36524@qq.com>
1 parent 1f614e5 commit 76b2824

3 files changed

Lines changed: 70 additions & 15 deletions

File tree

src/components/StarlightHeader.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ import { getLocalizedNavLinks } from '@/config/navigation';
1414
import InstallButton from './InstallButton';
1515
import DocsContentLayoutToggle from './DocsContentLayoutToggle.astro';
1616
import type { SidebarEntry } from '@astrojs/starlight/sidebar';
17-
import { resolveDocsLocale, toInstallButtonLocale } from '@/lib/i18n';
17+
import { buildDocsRoutePath, resolveDocsLocale, parseDocsLocale, toInstallButtonLocale } from '@/lib/i18n';
1818
1919
/**
2020
* 获取当前语言区域
2121
*/
22-
const localeFromPath = Astro.url.pathname.startsWith('/en/') ? 'en' : 'root';
22+
const localeFromPath = parseDocsLocale(Astro.url.pathname.split('/').filter(Boolean)[0] ?? null);
2323
const docsLocale = resolveDocsLocale(
2424
Astro.currentLocale,
2525
Astro.locals?.starlightRoute?.locale,
2626
localeFromPath
2727
);
2828
const installButtonLocale = toInstallButtonLocale(docsLocale);
29-
const homeHref = docsLocale === 'en' ? '/en/' : '/';
29+
const homeHref = buildDocsRoutePath(docsLocale, '/');
3030
const localizedNavLinks = getLocalizedNavLinks(docsLocale);
3131
3232
/**

src/components/StarlightHeader.navigation.test.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, it } from 'vitest';
22
import { getLink } from '@shared/links';
33
import { getLocalizedNavLinks } from '@/config/navigation';
4+
import { DOCS_LOCALE_METADATA, buildDocsRoutePath } from '@/lib/i18n';
45

56
describe('docs navigation support entry', () => {
67
it('localizes the unified support label while keeping the canonical about link', () => {
@@ -45,4 +46,18 @@ describe('docs navigation support entry', () => {
4546
displayLabel: 'Builder',
4647
});
4748
});
49+
50+
it('provides localized header labels for every supported docs locale', () => {
51+
const locales = DOCS_LOCALE_METADATA.map((locale) => locale.code);
52+
53+
for (const locale of locales) {
54+
const localizedLinks = getLocalizedNavLinks(locale);
55+
56+
expect(localizedLinks).toHaveLength(4);
57+
expect(localizedLinks.every((link) => link.displayLabel.trim().length > 0)).toBe(true);
58+
expect(localizedLinks.find((link) => link.linkKey === 'blog')?.href).toBe(
59+
buildDocsRoutePath(locale, '/blog/'),
60+
);
61+
}
62+
});
4863
});

src/config/navigation.ts

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 支持中英文双语显示
66
*/
77
import { getLink, getLinkTarget, getLinkRel, type PublicLinkKey } from '@shared/links';
8-
import { resolveDocsLocale, type DocsLocale } from '@/lib/i18n';
8+
import { buildDocsRoutePath, resolveDocsLocale, type DocsLocale } from '@/lib/i18n';
99

1010
/**
1111
* 导航链接接口
@@ -15,8 +15,8 @@ export interface NavLink {
1515
/** 链接显示文本 */
1616
label: string;
1717

18-
/** 英文版显示文本 */
19-
labelEn?: string;
18+
/** 非默认语言显示文本 */
19+
translations?: Partial<Record<Exclude<DocsLocale, 'root'>, string>>;
2020

2121
/** 链接地址 (支持相对路径和绝对 URL) */
2222
href: string;
@@ -44,24 +44,64 @@ export interface LocalizedNavLink extends NavLink {
4444
export const navLinks: NavLink[] = [
4545
{
4646
label: "首页",
47-
labelEn: "Home",
47+
translations: {
48+
en: 'Home',
49+
'zh-Hant': '首頁',
50+
'ja-JP': 'ホーム',
51+
'ko-KR': '홈',
52+
'de-DE': 'Startseite',
53+
'fr-FR': 'Accueil',
54+
'es-ES': 'Inicio',
55+
'pt-BR': 'Início',
56+
'ru-RU': 'Главная',
57+
},
4858
href: getLink('website'),
4959
linkKey: 'website',
5060
},
5161
{
5262
label: "部署生成器",
53-
labelEn: "Builder",
63+
translations: {
64+
en: 'Builder',
65+
'zh-Hant': '部署產生器',
66+
'ja-JP': 'デプロイビルダー',
67+
'ko-KR': '배포 빌더',
68+
'de-DE': 'Deployment-Builder',
69+
'fr-FR': 'Générateur de déploiement',
70+
'es-ES': 'Generador de despliegue',
71+
'pt-BR': 'Gerador de implantação',
72+
'ru-RU': 'Генератор развертывания',
73+
},
5474
href: 'https://builder.hagicode.com/',
5575
},
5676
{
5777
label: "博客",
58-
labelEn: "Blog",
78+
translations: {
79+
en: 'Blog',
80+
'zh-Hant': '部落格',
81+
'ja-JP': 'ブログ',
82+
'ko-KR': '블로그',
83+
'de-DE': 'Blog',
84+
'fr-FR': 'Blog',
85+
'es-ES': 'Blog',
86+
'pt-BR': 'Blog',
87+
'ru-RU': 'Блог',
88+
},
5989
href: getLink('blog'),
6090
linkKey: 'blog',
6191
},
6292
{
6393
label: "获取技术支持",
64-
labelEn: "Get Support",
94+
translations: {
95+
en: 'Get Support',
96+
'zh-Hant': '獲取技術支援',
97+
'ja-JP': 'サポート',
98+
'ko-KR': '기술 지원',
99+
'de-DE': 'Support',
100+
'fr-FR': 'Assistance',
101+
'es-ES': 'Soporte',
102+
'pt-BR': 'Suporte',
103+
'ru-RU': 'Поддержка',
104+
},
65105
href: getLink('about'),
66106
icon: "comment",
67107
linkKey: 'about',
@@ -72,16 +112,16 @@ export const navLinks: NavLink[] = [
72112
* 按 locale 解析导航显示文案,缺失时回退到中文标签。
73113
*/
74114
export function getNavLinkLabel(link: NavLink, locale: DocsLocale): string {
75-
if (locale === 'en' && link.labelEn) {
76-
return link.labelEn;
115+
if (locale !== 'root' && link.translations?.[locale]) {
116+
return link.translations[locale];
77117
}
78118

79119
if (link.label) {
80120
return link.label;
81121
}
82122

83-
if (link.labelEn) {
84-
return link.labelEn;
123+
if (link.translations?.en) {
124+
return link.translations.en;
85125
}
86126

87127
// Keep navigation labels non-empty even when upstream config is incomplete.
@@ -97,7 +137,7 @@ export function getLocalizedNavLinks(localeInput?: string | null): LocalizedNavL
97137
...link,
98138
href:
99139
link.linkKey === 'blog'
100-
? (locale === 'en' ? '/en/blog/' : '/blog/')
140+
? buildDocsRoutePath(locale, '/blog/')
101141
: link.href,
102142
displayLabel: getNavLinkLabel(link, locale),
103143
}));

0 commit comments

Comments
 (0)