From Basics to Advanced: Vue.js Internationalization Explained

chaimamehrzi

Mehrzi

Posted on January 29, 2024

From Basics to Advanced: Vue.js Internationalization Explained

Introduction
In today's globalized world, it's crucial for web developers to create applications that can be easily localized for users from different regions and cultures. As we know, people around the world speak many languages.

So, if we want our application to be accessible to everyone, it is necessary to create it in their native language and that's where internationalization is one of the best ways to make your web application accessible to all the people around the world providing them with a better user experience. If we look at it from a business perspective, internationalization and translation aid in strengthening global presence, consequently generating more revenue.

Join me as we unravel the tapestry of internationalization with the Vue internationalization example, weaving together the threads of culture, language, and seamless user experiences.

Tutorial Goal: Vue Internationalization Tutorial with Vue l18n
In this tutorial, you will learn about the Vue I18n plugin and explore how to implement internationalization and translation in our VueJS web application.

What is Vue I18n ?

You must be wondering what is Vue I18n and its specific role in the journey toward internationalizing our web applications. Vue I18n is a localization library for Vue.js that helps developers easily handle application translations. It provides a simple and flexible API to integrate translations into Vue components, which makes creating multi-language apps almost effortless. With Vue I18n, you can define translation messages in different languages and easily switch between them based on the user's locale. It also supports multiple advanced features like dynamic translations or pluralization which makes it a truly comprehensive solution for Vue internationalization

Project Set-Up

First, let's create a new Vue.js project using the Vue CLI. If you don't have the Vue CLI installed, you can just follow this command to install it:

npm install -g @vue/cli
Enter fullscreen mode Exit fullscreen mode

Now, create a new project:

vue create vue-i18n-tutorial

Enter fullscreen mode Exit fullscreen mode

and don't forget to change the project directory:

cd vue-i18n-tutorial
Enter fullscreen mode Exit fullscreen mode

Installing and configuring Vue I18n

As you know we need Vue I18n to implement internationalization. Install it using the following command

vue add i18n

Enter fullscreen mode Exit fullscreen mode

You will see now how the Vue CLI is going to do all the required setup for you by creating a locale folder and an en.json file as our default language file.

Creating translation files

Create translation files for each language you want to support. For example, create a fr.json for French translations :

{
    "greeting": "Bonjour!"
}

Enter fullscreen mode Exit fullscreen mode

and a de.json for German translations :

{
    "greeting": "Hallo!"
}

Enter fullscreen mode Exit fullscreen mode

App.vue

Now we need to edit App.vue as follows and rename the generated HelloWorld.vue to HelloI18n.vue

<template>
  <div id="app" class="container">
    <div class="jumbotron">
      <h1 class="display-4">Vue Internationalization App</h1>
    </div>
    <HelloI18n />
  </div>
</template>

<script>
import HelloI18n from "./components/HelloI18n.vue";

export default {
  name: "App",

  components: {
    HelloI18n,
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Enter fullscreen mode Exit fullscreen mode

Add Vue18In in our template

In the HelloI18n.vue file remove everything and add the below one as an example :

<template>
  <div>
    <h1>
      {{ $t('language_select_info') }}
    </h1>
    <div>
      <select v-model="$i18n.locale">
        <option
          v-for="(langnguage, i) in languages"
          :key="langnguage"
          :value="langnguage">
          {{ langnguage }}
        </option>
      </select>
    </div>
  </div>
</template>
<script>
export default {
    data(){
    return {
      languages: ['en', 'de', 'fr']
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Now, as you can see, we have used language_select_info inside our template. Edit all the JSON files with this key and its translated value respective to the language as shown below.

//en.json
"language_select_info": "Select the language you want to use"

//de.json
"language_select_info": "Wählen Sie die Sprache aus, die Sie verwenden möchten"

//fr.json
"language_select_info": "Sélectionnez la langue que vous souhaitez utiliser"
Enter fullscreen mode Exit fullscreen mode

For a better structure of our code, Create a plugins directory and move the previous i18n.js file from the root folder to the plugins folder.

Now let's try to run our web app for the first time don't forget to use this command:

npm run serve 
Enter fullscreen mode Exit fullscreen mode

It will look like this :

Image description
Using Browser's default language

The application will use the default language set by the browser, which is English, as we haven't selected a default language for it. Let's say that even though the browser's default language is not English, your application still uses English. In that scenario, you will need to use the Select option to manually change the language.

Modify the file i18n.js. Assign the browser's default language detection API, navigator.language, to the locale exported variable. The default language, such as en-GB or en-IN, is typically prefixed with the language of the browser. Since we only require the first section for our application, navigator.language.split('-')[0] has been used:

// plugins/i18n.js
export default new VueI18n({
  locale:
    navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})
Enter fullscreen mode Exit fullscreen mode

Let’s assume that we have region-specific languages in our app. We normally follow the naming convention in which we suffix the region’s short name after languages like en-GB.json and en-IN.json. To fetch the right language for the user’s region, we need to add the following code to our application.

function checkDefaultLanguage() {
  let matched = null
  const languages = Object.getOwnPropertyNames(loadLocaleMessages())
  languages.forEach(language => {
    if (language === navigator.language) {
      matched = language
    }
  })
  if (!matched) {
    languages.forEach(language => {
      if (language === navigator.language.split('-')[0]) {
        matched = language
      }
    })
  }
  if (!matched) {
    languages.forEach(language => {
      if (language.split('-')[0] === navigator.language.split('-')[0]) {
        matched = language
      }
    })
  }
  return matched
}


export const selectedLocale =
  checkDefaultLanguage() || process.env.VUE_APP_I18N_LOCALE || 'en'
export const languages = Object.getOwnPropertyNames(loadLocaleMessages())
export default new VueI18n({
  locale: selectedLocale,
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})
Enter fullscreen mode Exit fullscreen mode

As you can see, I separated the browser default language and our JSON filenames and then matched en-GB with en-IN, which is a better choice than presenting Dutch. As you can see, I've exported a couple more constants from the file to utilize later in our project.

Persisting Language Preferences

Let’s change the language to German using our created language list. You can see our texts get translated into German but if you refresh the web page, You can see the translated Hindi message is reset to English again!

This does not make sense. We can enhance it. We need to save the user's preference and apply it in our application every time the user visits or reloads the sites. We can use the browser's localStorage to save and get from it every time, or we can use one plugin - vuex-persistedstate - that accomplishes the same thing for us automatically.

First, we need to install the plugin:

npm install --save vuex-persistedstate
Enter fullscreen mode Exit fullscreen mode

and then we need to change some files :

//store/index.js :

import Vuex from 'vuex'
import Vue from 'vue'
import i18n, { selectedLocale } from '@/plugins/i18n'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    locale: i18n.locale
  },
  mutations: {
    updateLocale(state, newLocale) {
      state.locale = newLocale
    }
  },
  actions: {
    changeLocale({ commit }, newValue) {
      // update it in i18n plugin
      i18n.locale = newValue
      commit('updateLocale', newValue)
    }
  },
  plugins: [createPersistedState()]
})
Enter fullscreen mode Exit fullscreen mode

//main.js :

import Vue from "vue";
import App from "./App.vue";
import i18n from "./plugins/i18n";
import store from "./store";

Vue.config.productionTip = false;

new Vue({
  i18n,
  store,
  render: (h) => h(App),
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

Instead of using the component's local variable, let's utilize vuex-persistedstate to save and update changes in the user-selected language. Our plugin will save the user-selected language in localStorage. When the user reloads or reopens the page, our plugin retrieves the language from localStorage, uses it in the app, and displays its value in the language option dropdown.

<template>
  <div class="lang-dropdown">
    <select v-model="lang">
      <option
        v-for="(language, i) in languages"
        :key="language"
        :value="language">
        {{ language }}
      </option>
    </select>
  </div>
</template>
<script>
import { languages } from '@/plugins/i18n'
export default {
  computed: {
    lang: {
      get: function() {
        return this.$store.state.locale
      },
      set: function(newVal) {
        this.$store.dispatch('changeLocale', newVal)
      }
    }
  }
 created() {
    i18n.locale = this.lang;
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

There you go, we did it!

We learned how we could implement internationalization in our Vue app with the help of Vue-i18n. The vue-i18n documentation is well written. You will learn about many other translation concepts in the Vue app. We should consider that.

Github Repository: Vue-i18n-tutorial

git clone https://github.com/chaymamehrzi/vue-i18n-tutorial.git
Enter fullscreen mode Exit fullscreen mode

Advanced Features with Vue I18n
Vue I18n provides a range of advanced features to handle complex translation requirements. Some of the notable features include:

  • Custom Formatting: You can define custom formatters to format translated values based on your specific requirements.
  • Fallback Strategies: Vue internationalization allows you to define fallback strategies for missing translations, ensuring a smooth user experience even when translations are not available.
  • Number and Date Formatting: Vue I18n provides built-in support for formatting numbers and dates according to the user's locale.
  • Pluralization Rules: You can customize the pluralization rules for different languages, allowing you to handle complex plural forms.

Bonus - How to easily translate your i18n files
To learn more about Vue internationalization and its features, refer to the official documentation of Vue.js. Additionally, you can use tools like DevTranslate to automate the translation process and manage your Vue files efficiently.

Conclusion
In this comprehensive guide, we explored the process of Vue internationalization using the Vue I18n plugin.
We hope the tutorial has helped you learn VueI18n and figure out how to get started with your demo app.

For more such VueJS tutorials, visit the VueJs tutorial page and start digging deeper into the world of Vue.

💖 💪 🙅 🚩
chaimamehrzi
Mehrzi

Posted on January 29, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related