Internationalization
The template comes with built-in internationalization support using Vue I18n. This guide will help you understand and implement multi-language support in your app.
How It Works
The internationalization system is preconfigured with:
- Dynamic locale loading
- Route-based language switching
- Persistent language preferences
- Runtime locale changes
Project Structure
src/
├── i18n.js # i18n configuration
└── locales/ # Translation files
├── en.json # English translations
└── zh.json # Chinese translations
Basic Usage
1. Using Translations in Templates
<template>
<!-- Simple text -->
<p>{{ $t('HomePage.heading') }}</p>
<!-- With parameters -->
<i18n-t keypath="HomePage.welcome" tag="p">
<template #name>{{ username }}</template>
</i18n-t>
<!-- Pluralization -->
<p>{{ $tc('Products.count', productCount) }}</p>
</template>
2. Using Translations in JavaScript
import { useI18n } from 'vue-i18n'
export default {
setup() {
const { t, locale } = useI18n()
// Get translation
console.log(t('HomePage.heading'))
// Change locale
locale.value = 'zh'
}
}
Translation Files
Structure
Each locale file (e.g., en.json
, zh.json
) follows a nested structure:
{
"NavBar": {
"home": "Home",
"about": "About"
},
"HomePage": {
"heading": "Welcome to {app}",
"feature-text": "Features",
"loading": "Loading..."
}
}
Adding a New Language
Create a new locale file in
src/locales/
:json// fr.json { "NavBar": { "home": "Accueil", "about": "À propos" } }
Register the locale in
src/i18n.js
:jsexport const SUPPORT_LOCALES = ['en', 'zh', 'fr']
Advanced Features
1. Locale Switching
The template includes a LanguageSwitcher
component that handles locale changes:
<template>
<select v-model="currentLocale">
<option v-for="locale in availableLocales" :key="locale" :value="locale">
{{ locale }}
</option>
</select>
</template>
2. Route-Based Localization
URLs automatically include the current locale:
- English:
/en/products
- Chinese:
/zh/products
The router handles this through navigation guards:
router.beforeEach(async (to, _from, next) => {
const paramsLocale = to.params.locale
// Load locale if needed
await loadLocaleMessages(i18n, paramsLocale)
// Set i18n language
setI18nLanguage(i18n, paramsLocale)
return next()
})
3. Number and Date Formatting
Use Vue I18n's number and date formatting:
<template>
<p>{{ $n(price, 'currency') }}</p>
<p>{{ $d(date, 'long') }}</p>
</template>
<script setup>
const price = 99.99
const date = new Date()
</script>
4. Lazy Loading Translations
For large applications, you can lazy load translations:
const messages = await import(`@/locales/${locale}.json`)
i18n.global.setLocaleMessage(locale, messages.default)
Best Practices
Use Namespaces
json{ "ProductList": { "title": "Products", "empty": "No products found" } }
Handle Pluralization
json{ "cart": { "items": "no items | one item | {count} items" } }
Provide Fallbacks
jsconst i18n = createI18n({ fallbackLocale: 'en' // ... })
Use Translation Keys
vue<!-- ❌ Don't --> {{ $t('Submit') }} <!-- ✅ Do --> {{ $t('Forms.submit') }}
Testing Translations
Check Missing Keys
bashnpm run i18n:check
Visual Testing
- Test UI in all supported languages
- Verify text wrapping and layout
- Check RTL support if needed
RTL Support
For right-to-left languages:
Add RTL detection:
jsconst isRTL = ['ar', 'he'].includes(locale.value)
Apply RTL styles:
css[dir='rtl'] { /* RTL-specific styles */ }
Common Issues
1. Missing Translations
Use the fallback locale and warn in development:
const i18n = createI18n({
missingWarn: process.env.NODE_ENV === 'development',
fallbackWarn: process.env.NODE_ENV === 'development'
})
2. Runtime Locale Changes
Handle dynamic imports correctly:
async function changeLocale(locale) {
await loadLocaleMessages(i18n, locale)
document.querySelector('html').setAttribute('lang', locale)
}
3. Date/Time Formatting
Import necessary date-fns locales:
import { format } from 'date-fns'
import { enUS, zhCN } from 'date-fns/locale'
Next Steps
- Review your app's internationalization needs
- Plan your locale structure
- Implement translations progressively
- Test with native speakers
- Consider automated translation workflows