Table of Contents

Introduction

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.

Internationalization is one of the ways to make your web application accessible to broader users worldwide, providing 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.

So, let’s start exploring internationalization with the Vue internationalization example.

Tutorial Goal: Vue Internationalization Example with Vue l18n

In this tutorial, with the help of the Vue internationalization example, we will learn about Vue I18n and explore how to implement internationalization and translation in our VueJS application.

Project Set-Up

First, we will create a VueJS application using Vue CLI.

Copy Text
vue create vue-internationalization

Install and VueI18n Set Up

Now, with the help of Vue CLI, add our translation library, vue-i18n.

Copy Text
cd  vue-internationalization
vue add i18n

Vue CLI automatically does all required setups for us. This will create a locale folder and one en.json file as our default language file.

Copy Text
//en.json
{
  "welcome": "Welcome!"
}

Store Vue Translations in JSON Files

Let’s create two more files in the directory for Hindi and French translations, hi.json & fr.json, and add the following code to the respective file.

Copy Text
//hi.json
{
  "welcome": "स्वागत हे!"
}

//fr.json
{
  "welcome": "Bienvenue!"
}

Open App.vue,, to use the above files in our app. First, rename the HelloWorld.vue file to HelloI18n.vue. Now, ket’s edit App.vue as follows.

// App.vue

Copy Text
<template>
 <div id="app">
   <h1> Vue Internationalization App</h1>
   <HelloI18n />
 </div>
</template>
 
<script>
import HelloI18n from "./components/HelloI18n.vue";
 
export default {
 name: "App",
 components: {
   HelloI18n,
 },
};
</script>

Want to develop a sustainable and high-performance VueJS application?
Bacancy has astute developers with high problem-solving skills and advanced VueJs knowledge. Contact us and hire Vue Js developer for your dream project.

Use VueI18n in Template

In the HelloI18n.vue file, remove all the code and add the below one for our example.

// HelloI18n.vue

Copy Text
<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', 'hi', 'fr']
    }
  }
}
</script>

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.

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

//hi.json
"language_select_info": "उस भाषा का चयन करें जिसका आप उपयोग करना चाहते हैं"

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

Move the i18n.js file in the root folder to the plugins folder for better structure.

Run the application. We’ll see language_select_info value in English. We haven’t set our preference yet, so that it will take the default English language.

Use VueI18n in Template

Now, open the browser. It will look like this.

Vue internationalization app

Directory Structure

We can have separate JSON files for different languages in the locales folder

Copy Text
src
|--locales
|  |--de.json
|  |--en.json
|  |--hi.json
|  |--fr.json

Translations in Vue Component Files

Copy Text
<i18n>
  {
    "en": {
      "hello": "hello world"
    },
    "fr": {
      "hello": "Bonjour monde"
    },
    "hi": {
      "hello": "हैलो दुनिया"
    }
  }
</i18n>

We can add component-specific translations in the component itself with the help of the above syntax. While this might look like a nice option from other locales files, it’s not a very good option for a few scenarios. It would work for small applications with fewer translations, but as the application starts getting bigger and bigger, we’ll soon run into problems likes:

  • We’ll end up duplicating data. Suppose, Hello text is used in many other components, and we will individually write the same translations for every component.
  • As the number of translation messages and languages increases, the component starts getting bigger and bigger. Soon, it will look like one big ugly component, eventually becoming difficult to maintain.
  • Unable to share local translations among various components.

We will use .json files for our app since it is easier to debug and maintain the app. Our demo application is not large enough, but the real-world application will be more complex than our demo. So for better understanding, we will do the .json file way. We have used both examples so that you can play around with them. Later, in the tutorial, we will share the github link of the Vue Internationalization example for you to explore more.

Using Browser’s Default Langauge

Since we haven’t chosen any default language for our application, the app would take the browser’s default language, i.e., English. Suppose the browser’s default language is other than English, and your application still takes English as its default language. In that case, you need to change the language manually with the help of the Select option.

The app should automatically detect the browser’s default language and set it in for a better user experience.

Let’s work on that and see how we can do it.

Update the i18n.js file. Assign navigator.language (the browser’s API to detect default language) to the locale exported variable. The browser’s language usually prefixes the default language like en-GB or en-IN. We just need the first part for our application, so we have used navigator.language.split(‘-‘)[0]:

Copy Text
// 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()
})

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.

Copy Text
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()
})

As you can see, I have split the browser default language and our JSON filenames and finally matched en-GB with en-IN, which is a good choice over showing Dutch. As you can see, I have exported a few more constants from the file, which I’ll use later in our app.

Persisting Language Preferences

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

This doesn’t make any sense. We can improve it. Somehow we have to store the user’s choice and use it in our application every time the user visits or reloads the pages. We can use the browser’s localStorage for that to save and fetch from it every time, or we can use one plugin – vuex-persistedstate which does the same for us automatically

Let’s do it the Vuex way as we assumed we are using a real-world application. First, we need to install the plugin:

Copy Text
npm install --save vuex-persistedstate

//store/index.js

Copy Text
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()]
})

// main.js

Copy Text
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");

Instead of using the local variable from the component, let’s use vuex-persistedstate to store and update the change in user-selected language. Our plugin will store the user’s selected language in localStorage. When the user reloads or reopens the page, our plugin will fetch language from localStorage, use it in the app, and set its value in the language selection dropdown.

Copy Text
<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>

Instead of a static language list in the component state, we used the exported list from the i18n.js file instead of a static language list. If you try reopen or reload any page, selected language text will appear. Great it works!

Resuing Translations

As the app started growing, our translation file contents became large too. For better code maintenance, we need to organize our translations in language JSON files for better readability. Soon we will end up having repeated messages, keys, or phrases like username, password, button, or submit in many components.

Copy Text
//en.json
{
 "dashboardpage": {
    "welcomeMessage": "Welcome to Vue internationalization blog tutorial",
    "userName": "Username",
    "login": "Login"
  },
  "login": {
    "userName": "Enter your Username",
    "password": "Enter your Password",
    "login": "Login"
  },
  "forgotEmail": {
    "email": "Email",
    "continue": "Click here to get recovery your email",
    "submit": "Click here to get Login"
  }
}

As you can see in the above example, we have a few repeating words. Now imagine if we have to update any message, we have to do it at all the occurrences to reflect all the places in the application. In medium to large applications, we’ll have hundreds of messages of translations in each JSON file. If, for one component, we have different nested objects for the same message, it will become hard to track and debug.

Somehow we should group them and put them in one place. Doing so still we will have some duplicates, but we overcome them by using the links shown below:

Copy Text
//en.json
{
 "dashboardpage": {
    "welcomeMessage": "Welcome to Vue internationalization blog tutorial",
    "userName": "Username",
    "login": "Login"
  },
  "login": {
    "userName": "Enter your @:homepage.userName",
    "password": "Enter your Password",
    "login": "@:homepage.login"
  },
  "forgotEmail": {
    "email": "Email",
    "continue": "Click here to get recovery @:forgotEmail.email",
    "submit": "Click here to get @:login.login"
  }
}

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 Internationalization Example

Feel free to visit the source code, clone the repository using the below command, and play around with it.

Copy Text
git clone https://github.com/jaydadhaniya/vue-internationalization.git

Conclusion

So, this was about implementing internalization and translations in our VueJS application with the Vue Internationalization example. We hope the tutorial has helped you learn VueI18n and figure out how to get started with your demo app. If you have any questions or feedback after cloning our source code or going through the tutorial step by step, feel free to contact us.

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

Outsource Team Of Dedicated Vue.js Developers

  • Flexible Hiring Models
  • Agile Development Process
  • Transparency and Integrity

BOOK A 30 MIN CALL

Build Your Agile Team

Hire Skilled Developer From Us

[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?