| # Internationalization (i18n) Implementation |
| |
| TsFile Viewer supports multiple languages with Vue I18n. |
| |
| ## Supported Languages |
| |
| - **Chinese (zh-CN)** - Default language |
| - **English (en-US)** |
| |
| ## Features |
| |
| - Automatic language detection from browser settings |
| - Language preference saved in localStorage |
| - Language switcher in the top-right corner |
| - All UI text translated |
| - Documentation available in both languages |
| |
| ## File Structure |
| |
| ``` |
| frontend/src/i18n/ |
| ├── index.ts # i18n configuration |
| └── locales/ |
| ├── zh-CN.json # Chinese translations |
| └── en-US.json # English translations |
| ``` |
| |
| ## Usage in Components |
| |
| ### Composition API |
| |
| ```vue |
| <script setup lang="ts"> |
| import { useI18n } from "vue-i18n"; |
| |
| const { t, locale } = useI18n(); |
| |
| // Use translation |
| const title = t("app.title"); |
| |
| // Switch language |
| locale.value = "en-US"; |
| </script> |
| |
| <template> |
| <h1>{{ $t("app.title") }}</h1> |
| <p>{{ $t("app.description") }}</p> |
| </template> |
| ``` |
| |
| ### Options API |
| |
| ```vue |
| <script> |
| export default { |
| computed: { |
| title() { |
| return this.$t("app.title"); |
| }, |
| }, |
| methods: { |
| switchLanguage(lang) { |
| this.$i18n.locale = lang; |
| }, |
| }, |
| }; |
| </script> |
| |
| <template> |
| <h1>{{ $t("app.title") }}</h1> |
| </template> |
| ``` |
| |
| ## Translation Keys |
| |
| ### Common Keys |
| |
| ```json |
| { |
| "common": { |
| "loading": "Loading...", |
| "error": "Error", |
| "success": "Success", |
| "cancel": "Cancel", |
| "confirm": "Confirm" |
| } |
| } |
| ``` |
| |
| ### Feature-specific Keys |
| |
| ```json |
| { |
| "file": { |
| "title": "File Management", |
| "uploadFile": "Upload File", |
| "selectFile": "Select File" |
| }, |
| "metadata": { |
| "title": "Metadata", |
| "version": "Version", |
| "timeRange": "Time Range" |
| }, |
| "data": { |
| "title": "Data Preview", |
| "filters": "Filters", |
| "exportCsv": "Export CSV" |
| }, |
| "chart": { |
| "title": "Chart Visualization", |
| "exportPng": "Export PNG" |
| } |
| } |
| ``` |
| |
| ## Adding a New Language |
| |
| 1. Create a new locale file: |
| |
| ```bash |
| touch frontend/src/i18n/locales/ja-JP.json |
| ``` |
| |
| 2. Add translations: |
| |
| ```json |
| { |
| "app": { |
| "title": "TsFileビューア", |
| "description": "Apache TsFile形式データの表示と分析ツール" |
| } |
| } |
| ``` |
| |
| 3. Import in `i18n/index.ts`: |
| |
| ```typescript |
| import jaJP from "./locales/ja-JP.json"; |
| |
| const i18n = createI18n({ |
| messages: { |
| "zh-CN": zhCN, |
| "en-US": enUS, |
| "ja-JP": jaJP, // Add new language |
| }, |
| }); |
| ``` |
| |
| 4. Update LanguageSwitcher component: |
| ```vue |
| const languageItems = computed(() => [ [ { label: '中文', click: () => |
| switchLanguage('zh-CN') }, { label: 'English', click: () => |
| switchLanguage('en-US') }, { label: '日本語', click: () => |
| switchLanguage('ja-JP') }, ], ]) |
| ``` |
| |
| ## Documentation |
| |
| ### Available Documentation |
| |
| - **English**: |
| - [README.md](../README.md) |
| - [USER_GUIDE.md](USER_GUIDE.md) |
| - [DEPLOYMENT.md](DEPLOYMENT.md) |
| - [API.md](API.md) |
| |
| - **Chinese**: |
| - [README.zh-CN.md](../README.zh-CN.md) |
| - [USER_GUIDE.zh-CN.md](USER_GUIDE.zh-CN.md) |
| - [DEPLOYMENT.zh-CN.md](DEPLOYMENT.zh-CN.md) |
| |
| ### Adding Documentation in a New Language |
| |
| 1. Copy existing documentation: |
| |
| ```bash |
| cp README.md README.ja-JP.md |
| cp USER_GUIDE.md USER_GUIDE.ja-JP.md |
| cp DEPLOYMENT.md DEPLOYMENT.ja-JP.md |
| ``` |
| |
| 2. Translate the content |
| |
| 3. Add links in main README: |
| ```markdown |
| [中文文档](../README.zh-CN.md) | [English](../README.md) | [日本語](README.ja-JP.md) |
| ``` |
| |
| ## Best Practices |
| |
| 1. **Use Namespaces**: Organize translations by feature |
| |
| ```json |
| { |
| "file": { ... }, |
| "metadata": { ... }, |
| "data": { ... } |
| } |
| ``` |
| |
| 2. **Consistent Keys**: Use the same key structure across languages |
| |
| ```json |
| // zh-CN.json |
| { "common": { "save": "保存" } } |
| |
| // en-US.json |
| { "common": { "save": "Save" } } |
| ``` |
| |
| 3. **Pluralization**: Use Vue I18n pluralization |
| |
| ```json |
| { |
| "items": "no items | one item | {count} items" |
| } |
| ``` |
| |
| ```vue |
| {{ $t("items", 0) }} // "no items" {{ $t("items", 1) }} // "one item" |
| {{ $t("items", 5) }} // "5 items" |
| ``` |
| |
| 4. **Interpolation**: Use variables in translations |
| |
| ```json |
| { |
| "welcome": "Welcome, {name}!" |
| } |
| ``` |
| |
| ```vue |
| {{ $t("welcome", { name: "John" }) }} // "Welcome, John!" |
| ``` |
| |
| 5. **Date/Time Formatting**: Use locale-aware formatting |
| ```typescript |
| const date = new Date(); |
| const formatted = date.toLocaleString(locale.value); |
| ``` |
| |
| ## Testing |
| |
| Test translations in different languages: |
| |
| ```typescript |
| import { createI18n } from "vue-i18n"; |
| import zhCN from "@/i18n/locales/zh-CN.json"; |
| import enUS from "@/i18n/locales/en-US.json"; |
| |
| describe("i18n", () => { |
| it("should have all keys in both languages", () => { |
| const zhKeys = Object.keys(zhCN); |
| const enKeys = Object.keys(enUS); |
| expect(zhKeys).toEqual(enKeys); |
| }); |
| }); |
| ``` |
| |
| ## Configuration |
| |
| ### Vite Configuration |
| |
| ```typescript |
| import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite"; |
| |
| export default defineConfig({ |
| plugins: [ |
| VueI18nPlugin({ |
| include: resolve(__dirname, "./src/i18n/locales/**"), |
| }), |
| ], |
| }); |
| ``` |
| |
| ### TypeScript Support |
| |
| ```typescript |
| import type { MessageSchema } from '@/i18n' |
| |
| // Type-safe translations |
| const i18n = createI18n<[MessageSchema], 'zh-CN' | 'en-US'>({ |
| legacy: false, |
| locale: 'zh-CN', |
| messages: { ... }, |
| }) |
| ``` |
| |
| ## Browser Support |
| |
| - Modern browsers with ES6+ support |
| - localStorage for language preference |
| - Automatic fallback to English if translation missing |
| |
| ## Performance |
| |
| - Translations are pre-compiled at build time |
| - Lazy loading for large translation files (if needed) |
| - Minimal runtime overhead |
| |
| ## Troubleshooting |
| |
| ### Missing Translations |
| |
| If a translation key is missing: |
| |
| 1. Check the console for warnings |
| 2. Verify the key exists in both language files |
| 3. Ensure the key path is correct |
| |
| ### Language Not Switching |
| |
| 1. Check localStorage for saved preference |
| 2. Verify locale value is being set correctly |
| 3. Clear browser cache and reload |
| |
| ### Build Errors |
| |
| If you encounter build errors: |
| |
| 1. Ensure all JSON files are valid |
| 2. Check that all imports are correct |
| 3. Verify VueI18nPlugin configuration |
| |
| ## Resources |
| |
| - [Vue I18n Documentation](https://vue-i18n.intlify.dev/) |
| - [Intlify Unplugin](https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n) |
| - [i18n Best Practices](https://vue-i18n.intlify.dev/guide/essentials/syntax.html) |