Vue I18n Routing
vue-i18n-routing is a critical extension within the Intlify ecosystem, designed to seamlessly integrate internationalization capabilities (provided by `vue-i18n`) with client-side routing (provided by `vue-router`). It enhances `vue-router` by enabling locale-aware URL patterns, dynamic route parameter handling for locales, and helper functions for navigating between localized routes. The package is currently at version 1.2.0 and receives active maintenance, evidenced by recent bug fixes and feature additions. Its primary differentiator is providing a cohesive solution for managing multi-language URLs without boilerplate, supporting both Vue 2 (via `vue-i18n-bridge` and `@vue/composition-api`) and Vue 3 environments. It abstracts the complexity of locale prefixes and path resolution, making it easier to build SEO-friendly, internationalized Vue applications with consistent user experiences across different languages.
Common errors
-
Error: [vue-i18n] Not installed. Make sure to call `app.use(i18n)` before `app.mount()`.
cause The `vue-i18n` plugin or its routing wrapper was not properly installed into the Vue application instance before it was mounted.fixEnsure you call `app.use(i18n)` and `app.use(router)` (where `router` is the instance created by `vue-i18n-routing`) before `app.mount('#app')`. -
TypeError: Cannot read properties of undefined (reading 'locale')
cause Attempting to access `i18n.locale` or related properties before `vue-i18n` has been fully initialized or provided to the component context.fixVerify that `createI18n` is called correctly and its instance is passed to `app.use()`. Also, ensure that any components using i18n hooks or global properties are within the `app`'s scope after `app.use(i18n)` has been called. -
[vue-router] No match for current location: "/en/non-existent"
cause A route with a locale prefix was accessed, but no matching route definition exists for the path or the locale parameter is not correctly handled.fixConfirm that your `vue-router` routes are correctly defined with a dynamic `:locale` segment at the root. For example, `{ path: '/:locale', children: [...] }`. Also, ensure the route name is consistent if using named routes with `localePath`.
Warnings
- breaking The package has strict peer dependency requirements for `vue`, `vue-i18n`, and `vue-router`. Mismatched versions, especially between major versions (e.g., Vue 2 with Vue Router 4, or vue-i18n v8 with vue-i18n v9+ without `vue-i18n-bridge`), can lead to runtime errors or unexpected behavior. Always ensure your peer dependencies satisfy the `package.json` ranges.
- gotcha When migrating between versions or frameworks, inconsistencies in URL encoding and query parameter handling during locale switching have been reported and fixed. This could lead to malformed URLs or lost state if not on a patched version.
- gotcha The `createRouter` function exported by `vue-i18n-routing` is a wrapper around `vue-router`'s `createRouter`. Directly importing `createRouter` from `vue-router` will bypass the i18n integration provided by this package, leading to non-localized routes and navigation issues.
- gotcha The `legacy: false` option is crucial for `createI18n` from `vue-i18n` when using the Composition API. If `legacy` is set to `true` (or omitted, as the default can vary), Composition API hooks like `useI18n` will not function as expected, impacting `vue-i18n-routing`'s hooks which rely on it.
Install
-
npm install vue-i18n-routing -
yarn add vue-i18n-routing -
pnpm add vue-i18n-routing
Imports
- createRouter
import { createRouter } from 'vue-router' // For i18n-aware routing, use vue-i18n-routing's wrapperimport { createRouter } from 'vue-i18n-routing' - useLocalePath
import { useLocalePath } from 'vue-i18n'import { useLocalePath } from 'vue-i18n-routing' - useSwitchLocalePath
import { useSwitchLocalePath } from 'vue-i18n'import { useSwitchLocalePath } from 'vue-i18n-routing'
Quickstart
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { createI18n } from 'vue-i18n';
import { createRouter as createI18nRouter, useLocalePath, useSwitchLocalePath } from 'vue-i18n-routing';
// --- i18n setup ---
const messages = {
en: {
welcome: 'Welcome to our multi-language app!',
about: 'About Us',
home: 'Home',
greeting: 'Hello from home!',
switch_locale: 'Switch to {locale}'
},
fr: {
welcome: 'Bienvenue dans notre application multilingue !',
about: 'À Propos',
home: 'Accueil',
greeting: 'Bonjour de l\'accueil !',
switch_locale: 'Passer au {locale}'
}
};
const i18n = createI18n({
locale: 'en',
fallbackLocale: 'en',
messages,
legacy: false, // Must be false for Composition API
globalInjection: true
});
// --- Vue Router setup ---
const routes = [
{
path: '/:locale',
component: { template: '<router-view />' }, // A wrapper for localized routes
children: [
{ path: '', name: 'home', component: { template: `
<div>
<h1>{{ $t('greeting') }}</h1>
<router-link :to="localePath('about')">{{ $t('about') }}</router-link>
<p>
<button @click="switchLocale('fr')">{{ $t('switch_locale', { locale: 'fr' }) }}</button>
<button @click="switchLocale('en')">{{ $t('switch_locale', { locale: 'en' }) }}</button>
</p>
</div>
` } },
{ path: 'about', name: 'about', component: { template: `
<div>
<h1>{{ $t('about') }}</h1>
<p>{{ $t('welcome') }}</p>
<router-link :to="localePath('home')">{{ $t('home') }}</router-link>
</div>
` } }
]
}
];
const router = createI18nRouter({
router: createRouter({
history: createWebHistory(),
routes
}),
i18n,
defaultLocale: 'en' // Specify default locale to omit from path
});
// --- Vue App setup ---
const app = createApp({
setup() {
const localePath = useLocalePath();
const switchLocalePath = useSwitchLocalePath();
const switchLocale = (locale) => {
router.push(switchLocalePath(locale));
};
return { localePath, switchLocale };
}
});
app.use(i18n);
app.use(router);
app.mount('#app');