blob: a4960919fc851ff8df18c7f8485103e49e837679 [file] [view]
# 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)