Setting Up Internationalization (i18n) in Vue 3

Note: This guide is based on the current best practices and tools available for Vue 3 as of my last update. Always refer to the official Vue 3 and vue-i18n@9 documentation for the most up-to-date practices and features.

In this tutorial, we will be walking through the process of setting up vue-i18n@9. If you are just starting your project, you can use my starter template Vite Ultra to get up and running quickly.

Step 1: Install Vue i18n

Vue I18n is a library that allows you to define and manage locales for your application. to Install it run the following command in your terminal:

npm i -D vue-i18n@9 @intlify/unplugin-vue-i18n

Step 2: Configure Vue i18n for Vue 3

In this step, we will configure Vue i18n to be used by Vue 3.

First, open the file in the root of your project called vite.config.js or vite.config.ts and add the following code:

import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
export default defineConfig({
  plugins: [
      include: [path.resolve(__dirname, './src/locales/**')],
      defaultLocale: 'en',
      fallbackLocale: 'en',
      // escapeHtml: true,
      jitCompilation: true,
      dropMessageCompiler: true,
      strictMessage: false,

now we need to create a file called i18n.ts in the src folder of our project and add the following code:

import { createI18n } from 'vue-i18n'
import { nextTick } from 'vue'
import messages from '@intlify/unplugin-vue-i18n/messages'
export const SUPPORT_LOCALES = ['en', 'es', 'sv']  // add more locales

// Create an instance of I18n with configuration
const i18n = createI18n({
  legacy: false,            // Use the Composition API
  locale: 'en',             // Default locale
  fallbackLocale: 'en',     // Fallback locale if no translation found
  globalInjection: true,    // Allows global usage of $t() in templates
  messages                  // Locales messages

// Function to change the locale dynamically and load messages
export async function changeLocale(newLocale) {
  if (!SUPPORT_LOCALES.includes(newLocale)) {
    console.warn(`The locale ${newLocale} is not supported`);

  // Avoid loading the same locale messages if they're already active
  if ( === newLocale) return;

  try {
    const messages = await import(`./locales/${newLocale}.json`);, messages.default); = newLocale;
    document.querySelector('html').setAttribute('lang', newLocale);
  } catch (error) {
    console.error(`Failed to load ${newLocale} messages`, error);

export default i18n

we need to also create a folder called locales in the src folder of our project and add a file called en.json with the following code:

  "hello": "Hello world!"

You can add more locales by creating a file with the locale name for example es.json

  "hello": "¡Hola Mundo!"

remember to add all your locales to the SUPPORT_LOCALES array in the i18n.ts file.

and finally we add the following code to our main.ts or main.js file:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import i18n from '@/i18n' // Import i18n instance 👈
import './css/style.css'

.use(i18n) // Use i18n instance 👈

Step 3: Use Vue i18n in your Vue 3 project

Now that we have set up Vue i18n, we can use it in our Vue 3 project.

Open the App.vue file in the src folder of your project and add the following code:

  <h1 class="text-3xl font-bold">
    {{ $t('hello') }}

and that's it! you have successfully set up Vue i18n in your Vue 3 project.

Happy coding!