Vue i18n ist die Standard-Lösung für Internationalisierung (i18n) in Vue.js Anwendungen. In diesem Guide zeige ich dir, wie du Vue i18n in Vue 3, Nuxt 3 und mit verschiedenen Build-Tools einrichtest.

Was ist Vue i18n?#

Vue i18n ist ein Plugin, das von Intlify entwickelt wird und dir ermöglicht, deine Vue-Anwendung mehrsprachig zu gestalten. Es unterstützt:

  • Vue 2 und Vue 3
  • Composition API und Options API
  • Pluralisierung
  • Datums- und Zahlenformatierung
  • Lazy Loading von Übersetzungen

Vue 3 i18n Installation#

Mit npm/yarn installieren#

bash
npm install vue-i18n@9
# oder
yarn add vue-i18n@9

Basis-Setup in Vue 3#

javascript
// src/i18n/index.js
import { createI18n } from 'vue-i18n'

const messages = {
  de: {
    welcome: 'Willkommen',
    greeting: 'Hallo, {name}!'
  },
  en: {
    welcome: 'Welcome',
    greeting: 'Hello, {name}!'
  }
}

const i18n = createI18n({
  locale: 'de',
  fallbackLocale: 'en',
  messages
})

export default i18n
javascript
// 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')

Vue i18n im Template verwenden#

Die $t Funktion#

vue
<template>
  <h1>{{ $t('welcome') }}</h1>
  <p>{{ $t('greeting', { name: 'Max' }) }}</p>
</template>

Mit Composition API (useI18n)#

vue
<script setup>
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()

// Sprache wechseln
function changeLanguage(lang) {
  locale.value = lang
}
</script>

<template>
  <h1>{{ t('welcome') }}</h1>
  <button @click="changeLanguage('en')">English</button>
  <button @click="changeLanguage('de')">Deutsch</button>
</template>

Vue i18n Change Language#

Um die Sprache dynamisch zu wechseln, gibt es mehrere Ansätze:

Global#

javascript
import i18n from '@/i18n'

// Sprache ändern
i18n.global.locale.value = 'en'

In einer Komponente#

vue
<script setup>
import { useI18n } from 'vue-i18n'

const { locale, availableLocales } = useI18n()
</script>

<template>
  <select v-model="locale">
    <option v-for="lang in availableLocales" :key="lang" :value="lang">
      {{ lang }}
    </option>
  </select>
</template>

Nuxt i18n / Nuxt 3 i18n#

Für Nuxt-Projekte gibt es das offizielle @nuxtjs/i18n Modul.

Installation#

bash
npm install @nuxtjs/i18n

Nuxt 3 Konfiguration#

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],

  i18n: {
    locales: [
      { code: 'de', iso: 'de-DE', file: 'de.json' },
      { code: 'en', iso: 'en-US', file: 'en.json' }
    ],
    defaultLocale: 'de',
    lazy: true,
    langDir: 'locales/',
    strategy: 'prefix_except_default'
  }
})

Nuxt i18n mit Vue Router#

typescript
// locales/de.json
{
  "home": "Startseite",
  "about": "Über uns"
}
vue
<!-- pages/index.vue -->
<script setup>
const { t } = useI18n()
const localePath = useLocalePath()
</script>

<template>
  <nav>
    <NuxtLink :to="localePath('/')">{{ t('home') }}</NuxtLink>
    <NuxtLink :to="localePath('/about')">{{ t('about') }}</NuxtLink>
  </nav>
</template>

Vue i18n mit Vite#

Vite Plugin Vue i18n#

Für bessere Performance und Build-Optimierung:

bash
npm install @intlify/unplugin-vue-i18n
javascript
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
import { resolve } from 'path'

export default defineConfig({
  plugins: [
    vue(),
    VueI18nPlugin({
      include: resolve(__dirname, './src/locales/**')
    })
  ]
})

Übersetze deine Vue-i18n-Dateien

@:verlinkte Keys und {benannte} Platzhalter überstehen den Hin- und Rückweg.

Konto anlegenab 19 € im Monat

Übersetzungsdateien strukturieren#

Einzelne JSON-Dateien pro Sprache#

text
src/
  locales/
    de.json
    en.json
    fr.json
json
// locales/de.json
{
  "nav": {
    "home": "Startseite",
    "products": "Produkte",
    "contact": "Kontakt"
  },
  "auth": {
    "login": "Anmelden",
    "logout": "Abmelden",
    "register": "Registrieren"
  }
}

Lazy Loading (für große Projekte)#

javascript
// i18n/index.js
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  locale: 'de',
  fallbackLocale: 'en',
  messages: {}
})

export async function loadLocaleMessages(locale) {
  const messages = await import(`./locales/${'${locale}'}.json`)
  i18n.global.setLocaleMessage(locale, messages.default)
  return messages
}

export default i18n

Vue i18n Pluralisierung#

json
{
  "items": "keine Artikel | ein Artikel | {count} Artikel"
}
vue
<template>
  <p>{{ $t('items', 0) }}</p>  <!-- keine Artikel -->
  <p>{{ $t('items', 1) }}</p>  <!-- ein Artikel -->
  <p>{{ $t('items', 5) }}</p>  <!-- 5 Artikel -->
</template>

Vue i18n mit Vue Router#

Für mehrsprachige URLs:

javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import i18n from '@/i18n'

const routes = [
  {
    path: '/:locale',
    children: [
      { path: '', name: 'home', component: () => import('@/views/Home.vue') },
      { path: 'about', name: 'about', component: () => import('@/views/About.vue') }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

router.beforeEach((to, from, next) => {
  const locale = to.params.locale
  if (locale && i18n.global.availableLocales.includes(locale)) {
    i18n.global.locale.value = locale
  }
  next()
})

export default router

Vue i18next als Alternative#

Wenn du bereits i18next in anderen Projekten nutzt:

bash
npm install i18next i18next-vue
javascript
import i18next from 'i18next'
import I18NextVue from 'i18next-vue'

i18next.init({
  lng: 'de',
  resources: {
    de: { translation: { welcome: 'Willkommen' } }
  }
})

app.use(I18NextVue, { i18next })

Best Practices#

1. Übersetzungsschlüssel organisieren#

json
{
  "common": {
    "save": "Speichern",
    "cancel": "Abbrechen"
  },
  "pages": {
    "home": {
      "title": "Startseite"
    }
  }
}

2. TypeScript Support#

typescript
// i18n.d.ts
import { DefineLocaleMessage } from 'vue-i18n'
import de from './locales/de.json'

type MessageSchema = typeof de

declare module 'vue-i18n' {
  export interface DefineLocaleMessage extends MessageSchema {}
}

3. SEO für mehrsprachige Seiten#

vue
<script setup>
import { useI18n } from 'vue-i18n'
import { useHead } from '@vueuse/head'

const { t, locale } = useI18n()

useHead({
  htmlAttrs: { lang: locale.value },
  title: t('pages.home.title'),
  link: [
    { rel: 'alternate', hreflang: 'de', href: 'https://example.com/de/' },
    { rel: 'alternate', hreflang: 'en', href: 'https://example.com/en/' }
  ]
})
</script>

Häufig gestellte Fragen (FAQ)#

Wie wechsle ich die Sprache in Vue i18n?#

Mit locale.value = 'en' in der Composition API oder i18n.global.locale.value = 'en' global. Beide Methoden aktualisieren die Sprache reaktiv in der gesamten Anwendung.

Was ist der Unterschied zwischen Vue i18n und i18next?#

Vue i18n ist speziell für Vue entwickelt und bietet tiefe Integration mit Vue-Features wie Composition API und Reactivity. i18next ist framework-agnostisch und kann in React, Angular oder Vanilla JS verwendet werden. Für reine Vue-Projekte ist Vue i18n die bessere Wahl.

Unterstützt Vue i18n TypeScript?#

Ja, Vue i18n bietet volle TypeScript-Unterstützung. Mit dem DefineLocaleMessage Interface kannst du typisierte Übersetzungsschlüssel definieren, die Autovervollständigung und Typprüfung ermöglichen.

Wie lade ich Übersetzungen dynamisch (Lazy Loading)?#

Mit dynamischen Imports: const messages = await import('./locales/' + locale + '.json') und dann i18n.global.setLocaleMessage(locale, messages.default). Dies reduziert die initiale Bundle-Größe erheblich.

Fazit#

Vue i18n ist die beste Wahl für Internationalisierung in Vue.js Projekten. Mit Vue 3 und der Composition API ist das Setup noch einfacher geworden. Für Nuxt-Projekte bietet @nuxtjs/i18n eine nahtlose Integration mit zusätzlichen Features wie automatischem Routing.

Beim Übersetzen deiner Vue i18n JSON-Dateien ist es wichtig, dass Platzhalter wie {name} und ICU-Format erhalten bleiben. shipglobal.dev handhabt Vue i18n Dateiformate automatisch und bewahrt alle Variablen-Syntax.

Verwandte Artikel#