feat(i18n): implement internationalization support for en and zh

Add i18n infrastructure with translation files and utility functions
Update components to use translations and language switching
Create localized pages for en and zh languages
Add language detection and path localization utilities
This commit is contained in:
joyzhao
2025-06-15 09:08:41 +08:00
parent 4ab809ed94
commit ee0fbcceb2
9 changed files with 470 additions and 450 deletions

32
src/i18n/ui.ts Normal file
View File

@@ -0,0 +1,32 @@
// src/i18n/ui.ts
export const languages = {
en: 'English',
zh: '简体中文',
} as const;
export const defaultLang = 'en';
export const ui = {
en: {
'nav.home': 'Home',
'nav.projects': 'Projects',
'nav.experience': 'Experience',
'nav.skills': 'Skills',
'nav.awards': 'Awards',
'nav.education': 'Education',
'footer.rights': 'All rights reserved.',
'site.title': 'My Portfolio',
// 根据您的项目实际情况添加更多翻译键值对
},
zh: {
'nav.home': '首页',
'nav.projects': '项目经历',
'nav.experience': '工作经历',
'nav.skills': '专业技能',
'nav.awards': '奖项荣誉',
'nav.education': '教育背景',
'footer.rights': '版权所有。',
'site.title': '我的作品集',
// 根据您的项目实际情况添加更多翻译键值对
},
} as const;

41
src/i18n/utils.ts Normal file
View File

@@ -0,0 +1,41 @@
// src/i18n/utils.ts
import { ui, defaultLang, languages } from './ui';
export type Lang = keyof typeof languages;
export type UiKeys = keyof typeof ui[typeof defaultLang];
export function getLangFromUrl(url: URL): Lang {
const [, lang] = url.pathname.split('/');
if (lang in languages) return lang as Lang;
return defaultLang;
}
export function useTranslations(lang: Lang | undefined) {
const currentLang = lang || defaultLang;
return function t(key: UiKeys, ...args: any[]): string {
let translation: string = ui[currentLang][key] || ui[defaultLang][key];
if (args.length > 0) {
args.forEach((arg, index) => {
translation = translation.replace(`{${index}}`, arg);
});
}
return translation;
};
}
export function getLocalizedPath(path: string, lang: Lang | undefined): string {
const currentLang = lang || defaultLang;
const basePath = import.meta.env.BASE_URL === '/' ? '' : import.meta.env.BASE_URL;
// If the current language is the default language, do not add a language prefix.
if (currentLang === defaultLang) {
const fullPath = `${basePath}${path.startsWith('/') ? path : `/${path}`}`;
return fullPath.replace(/\/\/+/g, '/');
}
// Otherwise, add the language prefix.
const langPrefix = `/${currentLang}`;
const fullPath = `${basePath}${langPrefix}${path.startsWith('/') ? path : `/${path}`}`;
// Remove any double slashes that might occur.
return fullPath.replace(/\/\/+/g, '/');
}