Skip to content

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 ​

vue
<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 ​

js
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:

json
{
  "NavBar": {
    "home": "Home",
    "about": "About"
  },
  "HomePage": {
    "heading": "Welcome to {app}",
    "feature-text": "Features",
    "loading": "Loading..."
  }
}

Adding a New Language ​

  1. Create a new locale file in src/locales/:

    json
    // fr.json
    {
      "NavBar": {
        "home": "Accueil",
        "about": "À propos"
      }
    }
  2. Register the locale in src/i18n.js:

    js
    export const SUPPORT_LOCALES = ['en', 'zh', 'fr']

Advanced Features ​

1. Locale Switching ​

The template includes a LanguageSwitcher component that handles locale changes:

vue
<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:

js
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:

vue
<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:

js
const messages = await import(`@/locales/${locale}.json`)
i18n.global.setLocaleMessage(locale, messages.default)

Best Practices ​

  1. Use Namespaces

    json
    {
      "ProductList": {
        "title": "Products",
        "empty": "No products found"
      }
    }
  2. Handle Pluralization

    json
    {
      "cart": {
        "items": "no items | one item | {count} items"
      }
    }
  3. Provide Fallbacks

    js
    const i18n = createI18n({
      fallbackLocale: 'en'
      // ...
    })
  4. Use Translation Keys

    vue
    <!-- ❌ Don't -->
    {{ $t('Submit') }}
    
    <!-- ✅ Do -->
    {{ $t('Forms.submit') }}

Testing Translations ​

  1. Check Missing Keys

    bash
    npm run i18n:check
  2. 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:

  1. Add RTL detection:

    js
    const isRTL = ['ar', 'he'].includes(locale.value)
  2. Apply RTL styles:

    css
    [dir='rtl'] {
      /* RTL-specific styles */
    }

Common Issues ​

1. Missing Translations ​

Use the fallback locale and warn in development:

js
const i18n = createI18n({
  missingWarn: process.env.NODE_ENV === 'development',
  fallbackWarn: process.env.NODE_ENV === 'development'
})

2. Runtime Locale Changes ​

Handle dynamic imports correctly:

js
async function changeLocale(locale) {
  await loadLocaleMessages(i18n, locale)
  document.querySelector('html').setAttribute('lang', locale)
}

3. Date/Time Formatting ​

Import necessary date-fns locales:

js
import { format } from 'date-fns'
import { enUS, zhCN } from 'date-fns/locale'

Next Steps ​

  1. Review your app's internationalization needs
  2. Plan your locale structure
  3. Implement translations progressively
  4. Test with native speakers
  5. Consider automated translation workflows

Released under the MIT License.