Vue-i18n: Implement Internationalization in Vue 3

Vue.js is a great framework for building user interfaces, but if you want to reach a broader audience, you’ll need to make your application accessible to people all around the globe. Luckily, internationalization (or i18n) and translation are fundamental concepts in software development these days. If you’ve already begun exploring Vue with your new project, excellent — we can build on that knowledge together! In this article, we will explore how we can implement i18n in our projects using vue-i18n.

Let’s jump right into our tutorial

First install plugin

You need to install plugin for vue-i18n@9

//npm
npm install vue-i18n@9 --save

Create the config file in your src files Vue App

//~i18n.js
import { nextTick } from 'vue';
import { createI18n } from 'vue-i18n';

let i18n;

export const SUPPORT_LOCALES = ['pt', 'en', 'es'];

export function setI18nLanguage(locale) {
  loadLocaleMessages(locale);

  if (i18n.mode === 'legacy') {
    i18n.global.locale = locale;
  } else {
    i18n.global.locale.value = locale;
  }

  document.querySelector('html').setAttribute('lang', locale);
  localStorage.setItem('lang', locale);
}

export async function loadLocaleMessages(locale) {
  // load locale messages with dynamic import
  const messages = await import(
    /* webpackChunkName: "locale-[request]" */ `./locales/${locale}.json`
  );

  // set locale and locale message
  i18n.global.setLocaleMessage(locale, messages.default);

  return nextTick();
}

export default function setupI18n() {
  if(!i18n) {
    let locale = localStorage.getItem('lang') || 'pt';

    i18n = createI18n({
      globalInjection: true,
      legacy: false,
      locale: locale,
      fallbackLocale: 'pt'
    });

    setI18nLanguage(locale);
  }
  return i18n;
}

Import this file i18n.js in your main.js of Vue

//~main.js
import { createApp } from 'vue'

import App from './App.vue'

import i18n from './i18n';

createApp(App)
  .use(i18n())
  .mount('#app')

Awesome, now you need to create your translate files to use in your components

Create Files for translate locales

In src folder, create a folder with name locales and create all json files with name en.json or pt.json or es.json with your translate file occurrences. Checkout this example json below

name file: locales/en.json

{
  "languages": {
    "pt": "Portuguese",
    "en": "English",
    "es": "Spanish"
  },
  "title": {
    "config": "Configuration"
  }
}

name file: locales/pt.json

{
  "languages": {
    "pt": "Português",
    "en": "Inglês",
    "es": "Espanhol"
  },
  "title": {
    "config": "Configurações"
  }
}

name file: locales/es.json

{
  "languages": {
    "pt": "Portugués",
    "en": "Inglés",
    "es": "Español"
  },
  "title": {
    "config": "Configurações"
  }
}

Very good, now our app translates to English, Portuguese and Spanish

Now lets use translate in our components

Create a select or a button for changing language of locale with global hook useI18n

//~app.vue

<script setup>
import { watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { SUPPORT_LOCALES as supportLocales, setI18nLanguage } from '../i18n';

const { locale } = useI18n({ useScope: 'global' });
watch(locale, (val) => {
  setI18nLanguage(val);
});
</script>

<template>
  <h1>{{ $t('title.config') }}</h1>
  <select class="App-language" v-model="locale">
    <option
      v-for="optionLocale in supportLocales"
      :key="`locale-${optionLocale}`"
      :value="optionLocale">{{ optionLocale }}
    </option>
  </select>
</template>

Completed! You are now a vue.js ninja with internationalization skills. Now your vue.js apps can be accessible to people who interact with different languages.