Internationalization (i18n) solution implementation translates this sentence into English.
Internationalization (i18n) Implementation Solutions
Internationalization (i18n) is an essential feature in modern frontend application development. As a next-generation build tool, Vite.js offers multiple ways to implement internationalization. From simple JSON files to complex dynamic loading, developers can choose the most suitable solution based on project requirements.
Basic JSON File Solution
The simplest way to implement internationalization is by using JSON files to store translations for different languages. Create a locales
folder in a Vite project to store translation files for various languages:
// locales/en.json
{
"welcome": "Welcome",
"about": "About Us",
"contact": "Contact"
}
// locales/zh.json
{
"welcome": "欢迎",
"about": "关于我们",
"contact": "联系我们"
}
Then import and use the JSON files in components:
import en from './locales/en.json'
import zh from './locales/zh.json'
const messages = {
en,
zh
}
const currentLocale = ref('en')
function t(key) {
return messages[currentLocale.value][key]
}
Using the vue-i18n Plugin
For Vue projects, vue-i18n
is the most popular internationalization solution. First, install the dependency:
npm install vue-i18n@9
Then configure it in the Vite project:
// src/i18n.js
import { createI18n } from 'vue-i18n'
import en from './locales/en.json'
import zh from './locales/zh.json'
const messages = {
en,
zh
}
export default createI18n({
legacy: false,
locale: 'en',
fallbackLocale: 'en',
messages
})
Import it in main.js:
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'
const app = createApp(App)
app.use(i18n)
app.mount('#app')
Usage in components:
<template>
<p>{{ $t('welcome') }}</p>
</template>
Dynamic Language Pack Loading
For large applications, language packs can be loaded on demand to reduce initial loading size:
// src/i18n.js
export async function loadLocaleMessages(i18n, locale) {
const messages = await import(`./locales/${locale}.json`)
i18n.global.setLocaleMessage(locale, messages.default)
return nextTick()
}
Call when switching languages:
async function changeLocale(locale) {
if (!i18n.global.availableLocales.includes(locale)) {
await loadLocaleMessages(i18n, locale)
}
i18n.global.locale.value = locale
}
Handling Plural Forms and Interpolation
Internationalization involves more than simple text replacement; it also requires handling plural forms and variable interpolation:
// locales/en.json
{
"cart": {
"items": "{count} item | {count} items"
}
}
Usage in components:
<template>
<p>{{ $tc('cart.items', itemCount, { count: itemCount }) }}</p>
</template>
Date and Number Formatting
Internationalization also includes localized display of dates and numbers:
const i18n = createI18n({
// ...other configurations
datetimeFormats: {
en: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
},
zh: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
}
},
numberFormats: {
en: {
currency: {
style: 'currency',
currency: 'USD'
}
},
zh: {
currency: {
style: 'currency',
currency: 'CNY'
}
}
}
})
Usage:
<template>
<p>{{ $d(new Date(), 'short') }}</p>
<p>{{ $n(1000, 'currency') }}</p>
</template>
Route Internationalization
For multilingual websites, routes also need internationalization:
// router.js
const routes = [
{
path: '/:locale',
component: Layout,
children: [
{
path: 'about',
component: About,
name: 'about'
}
]
},
{
path: '/',
redirect: '/en'
}
]
Handle language switching in navigation guards:
router.beforeEach((to) => {
const locale = to.params.locale || 'en'
if (!supportedLocales.includes(locale)) {
return '/en' + to.fullPath
}
i18n.global.locale.value = locale
})
SEO Optimization
Multilingual websites require hreflang tags for SEO:
<template>
<head>
<link
v-for="locale in availableLocales"
:key="locale"
rel="alternate"
:hreflang="locale"
:href="`https://example.com/${locale}${$route.path}`"
>
</head>
</template>
Testing Internationalized Applications
When writing tests, consider multilingual scenarios:
import { mount } from '@vue/test-utils'
import Component from './Component.vue'
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
locale: 'en',
messages: {
en: {
welcome: 'Welcome'
}
}
})
const wrapper = mount(Component, {
global: {
plugins: [i18n]
}
})
expect(wrapper.text()).toContain('Welcome')
Performance Optimization Tips
- Load language packs on demand
- Use CDN to host language files
- Implement language caching
- Preload languages the user is likely to use
// Preload adjacent languages
function preloadAdjacentLocales(locale) {
const localesToPreload = getAdjacentLocales(locale)
localesToPreload.forEach(l => {
import(`./locales/${l}.json`)
})
}
Common Problem Solutions
Problem 1: Dynamic key translation
// Use computed properties
const translatedKey = computed(() => $t(`page.${currentPage}.title`))
Problem 2: Mixed content translation
// Use arrays and v-for
const mixedContent = computed(() => [
{ text: $t('part1'), isHtml: false },
{ html: '<strong>HTML content</strong>', isHtml: true }
])
Problem 3: Handling missing translations
// Custom missing handler
const i18n = createI18n({
// ...other configurations
missing: (locale, key) => {
console.warn(`Missing translation for ${key} in ${locale}`)
return key
}
})
Advanced Custom Requirements
For projects requiring high customization, extend i18n functionality:
// Custom directive
app.directive('t', {
mounted(el, binding) {
el.textContent = i18n.global.t(binding.value)
},
updated(el, binding) {
el.textContent = i18n.global.t(binding.value)
}
})
// Usage
<p v-t="'welcome'"></p>
Integration with Other Tools
Integration with Pinia state management:
// stores/i18n.js
export const useI18nStore = defineStore('i18n', {
state: () => ({
locale: 'en'
}),
actions: {
setLocale(locale) {
this.locale = locale
i18n.global.locale.value = locale
}
}
})
Integration with TailwindCSS for RTL support:
// Switch HTML direction based on language
watch(() => i18n.global.locale.value, (locale) => {
document.documentElement.dir = locale === 'ar' ? 'rtl' : 'ltr'
})
Build Optimization
Optimize internationalization resources in Vite configuration:
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('locales')) {
return 'locales'
}
}
}
}
}
})
Practical Application Scenarios
Multilingual product display for e-commerce websites:
<template>
<div v-for="product in products" :key="product.id">
<h3>{{ $t(`products.${product.id}.name`) }}</h3>
<p>{{ $t(`products.${product.id}.description`) }}</p>
<p>{{ $n(product.price, 'currency') }}</p>
</div>
</template>
Multilingual form validation:
// Validation rules
const rules = {
required: value => !!value || i18n.global.t('validation.required'),
email: value => /.+@.+\..+/.test(value) || i18n.global.t('validation.email')
}
Continuous Maintenance Strategy
- Establish translation key naming conventions
- Automate extraction of untranslated text
- Integrate translation management systems
- Regularly review translation quality
# Example script to extract untranslated text
grep -r "\$t(" src/ | awk -F"\$t\\('" '{print $2}' | awk -F"'" '{print $1}' | sort | uniq > keys.txt
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn