DEV Community

Cover image for Step-by-step: How to Create a Vue Multi-Language App with Vue-i18n
Gaël Thomas for FlyCode org

Posted on • Updated on • Originally published at blog.flycode.com

Step-by-step: How to Create a Vue Multi-Language App with Vue-i18n

Discover how to add translations to your Vue 3 application using “vue-i18n-next”. From nothing to a multi language app.


Our previous guide introduced you to internationalizing a Next.js application with next-translate as an i18n library. This time, we will focus on doing it with Vue 3.

This step-by-step guide will teach you:

  • How to initialize your Vue 3 application with “vue-i18n-next” (the i18n library that we will use)
  • How to create translations and start localizing your website
  • How to use the main translation feature

Ready to create a website in different languages? 🇺🇸🇫🇷

Why do we choose Vue i18n next?

You probably heard of many libraries to translate your Vue application (“vue-i18next”, “vue-simple-i18n”, etc.).

In this guide, we will use the Vue i18n next library because it would benefit the most readers since it’s the most used one (+650k downloads per week).

Most GitHub repositories that you will find online are using it. So, right after this guide, you will understand the basics and deep dive further into all these online resources.

Don’t worry, we will probably certainly write about other libraries in the future. If you don’t want to miss other content, I highly recommend following FlyCode on Twitter.

1. Create a new Vue 3 application

Note: You can skip to the next step if you already have an existing application.

Once you’re ready, you can open your terminal and move it into your project folder. The first thing you need to do is initialize a Vue 3 application.

You can enter the vue create [project-name] command to create a new project using the Vue CLI.

Note: If you don’t have the Vue CLI yet, you can install it using npm install -g @vue/cli.

In our case, we will name the project: “vue-3-i18n-example-with-vue-i18n-next” (vue create vue-3-i18n-example-with-vue-i18n-next).

Once you hit “Enter”, the Vue CLI will prompt you to select a preset for your new project. Select the “Default (Vue 3)” preset.

When your project is ready, move into it.

Your folder tree should look like below:

    .
    ├── README.md
    ├── babel.config.js
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   └── index.html
    └── src
        ├── App.vue
        ├── assets
        │   └── logo.png
        ├── components
        │   └── HelloWorld.vue
        └── main.js

    4 directories, 10 files
Enter fullscreen mode Exit fullscreen mode

2. Install vue-i18n-next in your Vue 3 project

The following step of this tutorial is to install the Vue i18n library that we will use.
Come back to your terminal and enter the command below:

$ vue add i18n
Enter fullscreen mode Exit fullscreen mode

After the package installation, the CLI will prompt you with some questions to configure your Vue 3 project.

Question 1: “The locale of project localization.”

It’s the default language of your website. In this guide, it will be English.
You can press enter to keep the default value (en).

Question 2: “The fallback locale of project localization.”

It’s the locale you want to redirect your user if he tries to access a non-existing language on your website. Usually, we set the same fallback locale as the default locale.
You can do the same and keep the default parameter (ENTER ).

Question 3: “The directory where store localization messages of project. It’s stored under src directory.”

This configuration asks you how you want to name your translation folder (folder containing all the translations of your website).

In this guide, we will keep the default name “locales”. But, if you want, feel free to change it to anything else “translations”, “languages”, etc.

Again, to keep the default setting, you can press ENTER.

Question 4: “Enable legacy API (compatible vue-i18n@v8.x) mode ?”

By default, the answer is N. I recommend you to keep it because it’s one of the significant features of Vue 3.

Note: legacy: false to allow Vue I18n to switch the API mode from Legacy API mode to Composition API mode.

After that, your project is ready to handle the first translations! 👏

If you look at your project tree, it should look like this:

    .
    ├── README.md
    ├── babel.config.js
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   └── index.html
    ├── src
    │   ├── App.vue
    │   ├── assets
    │   │   └── logo.png
    │   ├── components
    │   │   ├── HelloI18n.vue
    │   │   └── HelloWorld.vue
    │   ├── i18n.js
    │   ├── locales
    │   │   └── en.json
    │   └── main.js
    └── vue.config.js

    5 directories, 14 files
Enter fullscreen mode Exit fullscreen mode

Ask you can see, there are a lot of updates in your code and some new files! Let me introduce them to you.

  • vue.config.js (at the folder root): a configuration file with all the i18n settings. You will see most of your CLI answers here.

  • .env (at the folder root): an environment file with VUE_APP_I18N_LOCALE and VUE_APP_I18N_FALLBACK_LOCALE variables.

  • i18n.js (in the src/ folder): the i18n initialization by the createI18n function. There is a loadLocaleMessages function that loads your translation files.

  • en.json (in the locales/ folder): your English translation file. It will contain all your project translations.

  • HelloI18n.vue (in the src/components/ folder): a Vue demo component for the vue-i18n-next library (in the next section, we will launch it to see if everything is working).

3. Test the i18n configuration on our Vue 3 project

Before going further, it’s essential to test if everything is working correctly with the generated Vue i18next configuration.

To do so, we will use the HelloI18n.vue demo component. You will need to open your App.vue file and update the <script> and <template> parts to replace the current HelloWord component.

Your code will end up looking like this:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloI18n />
</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

Then, if you run your Vue application by typing npm run serve , you’ll have the following output:

vue-i18n-next example

If you see this page without any errors in your server console, it means that everything is appropriately configurated!

Before going further and creating our first global translations in Vue, let’s review the HelloI18n.vue code.

The example from the vue-i18n-next library is different from what we will use in this step-by-step guide. But, it’s interesting to explain it, so you will be able to deep dive into the i18n single file components later on your side.

Indeed, the code below uses the local t function (translation function). As you can see in the setup function, the vue-i18n library is configured to use only the current file translations.

Below the file component, you can see some <i18n> tags with JSON code. This JSON contains the “Hello i18n in SFC!” text displayed when you launched the project using npm run serve.

<template>
  <p>{{ t("hello") }}</p>
</template>

<script>
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";

export default defineComponent({
  name: "HelloI18n",
  setup() {
    const { t } = useI18n({
      inheritLocale: true,
      useScope: "local"
    });

    // Something todo ..

    return { t };
  }
});
</script>

<i18n>
    {
      "en": {
        "hello": "Hello i18n in SFC!"
      },
    }
</i18n>
Enter fullscreen mode Exit fullscreen mode

We will not discover this library feature in detail because it’s a particularity of the library and not using the global i18n translations. But, feel free to read more on the documentation if you want to create single components with proper translations.

4. Update the translations files

Before starting to update our project code, here are a few points to know:

  • all your translation files are in the folder configured at the third question in the vue-i18n CLI (by default locales/)

  • this folder contains one JSON file per locale (example: locales/en.json for the English language)

  • each JSON follows the key/value schema (example: “message” is the translation key and “hello i18n !!” is the translation)

{
  "message": "hello i18n !!"
}
Enter fullscreen mode Exit fullscreen mode

You got it! If you want to add/edit/remove a translation, you should do it in this file.

If you want to have two languages on your website, you should do it in the two corresponding files (example: locales/en.json and locales/fr.json).

In our case, we will need to create another file inside the locales/ folder. This file will be for the French language (fr.json file).

Your project tree should look like below.

    .
    ├── README.md
    ├── babel.config.js
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   └── index.html
    ├── src
    │   ├── App.vue
    │   ├── assets
    │   │   └── logo.png
    │   ├── components
    │   │   ├── HelloI18n.vue
    │   │   └── HelloWorld.vue
    │   ├── i18n.js
    │   ├── locales
    │   │   ├── en.json
    │   │   └── fr.json
    │   └── main.js
    └── vue.config.js

    5 directories, 15 files
Enter fullscreen mode Exit fullscreen mode

Once you have done that, we will update the locales/en.json file with the following content:

{
  "title": "Vue 3 i18n",
  "description": "A Vue i18n next example using vue-i18n-next"
}
Enter fullscreen mode Exit fullscreen mode

And update the locales/fr.json file with the same content, but translated:

{
  "title": "Vue 3 i18n",
  "description": "Un exemple Vue i18n next avec vue-i18n-next"
}
Enter fullscreen mode Exit fullscreen mode

As you can see, we created two translations:

  • one with title as name (key)
  • the other one with description as a name (key)

Everything is ready on the translation side. Now let’s dive into the code part! 💻

5. Refactor the HelloI18n component to use the locales’ folder translations

Let’s refactor the HelloI18n.js file to a much simpler code that will use the global translation files.

First, we need to open the i18n.js file and update the createI18n function. You will need to add the globalInjection parameter and set it to true.

It will allow you to use the i18n object from everywhere using the $ character.

export default createI18n({
  legacy: false,
  globalInjection: true,
  locale: process.env.VUE_APP_I18N_LOCALE || "en",
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || "en",
  messages: loadLocaleMessages(),
});
Enter fullscreen mode Exit fullscreen mode

To use a translation, you will be able to use the $t function from i18n:

<template>
  <h1>{{ $t('title') }}</h1>
  <p>{{ $t('description') }}</p>
</template>
Enter fullscreen mode Exit fullscreen mode

Let’s come back to the HelloI18n.js file. We will simplify it by using an empty component and calling the $t function with our translation key (as above).

<template>
  <h1>{{ $t("title") }}</h1>
  <p>{{ $t("description") }}</p>
</template>

<script>
export default {
  name: "HelloI18n"
};
</script>
Enter fullscreen mode Exit fullscreen mode

If you launch the project, you should have the below output.

Vue 3 internationalization example

We’re good; our HelloI18n component uses the English translations in the locales/en.json file.

But… I believe you’re wondering how to change the language from English to French. We will do it by creating a Vue multi language switcher component!

6. Create a Vue multi language switcher component

The final step of this step-by-step guide helps you switch from one language to the other and display the appropriate translation.

Based on the locale changing documentation of vue-i18n, we can do it by creating a <select> HTML element that modifies the $i18n.locale variable (i18n instance current language).

You can do it by creating a new LocaleSwitcher.vue file in the components/ folder.

Then, add the following code that creates a basic select with our two locales as a choice.

<template>
  <select v-model="$i18n.locale">
    <option v-for="(locale, i) in locales" :key="`locale-${i}`" :value="locale">
      {{ locale }}
    </option>
  </select>
</template>

<script>
export default {
  name: "LocaleSwitcher",
  data() {
    return { locales: ["fr", "en"] };
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

The last step is to add the LocaleSwitcher to our HelloI18n component.

<template>
  <h1>{{ $t("title") }}</h1>
  <p>{{ $t("description") }}</p>
  <LocaleSwitcher />
</template>

<script>
import LocaleSwitcher from "./LocaleSwitcher.vue";

export default {
 name: "HelloI18n",
 components: { LocaleSwitcher }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Now, you can restart your project and play with the select! Here is the output for the French language:

Vue multi language switcher component example

Boom… 💥 You just finalized your first internationalized website in Vue 3!

Bonus: Manage your translations outside of your code with FlyCode 🚀

As you can imagine, updating the translations inside your project can become tricky for some reasons:

  • if you start to have big translation files
  • if you have a lot of supported languages
  • if your product team is managing them and asking for a lot of changes

Let me show you one Git-based Product Editor created for this purpose. It will gather all your translations and allow you to manage them outside of your code editor. As an example, a product manager can modify them directly by himself.

Once he finishes updating all translations, he saves, and FlyCode creates a pull request on your GitHub repository. You can validate the PR and release your changes in just one click. ✅

Convinced? 😉 Here are a few articles that you can read and share with your team in addition to the Flycode website:

Code is available on GitHub

If you want to retrieve the complete code and execute it, everything is available on the FlyCode GitHub.

GitHub => Vue 3 i18n Example with Vue-i18n-next

I hope you liked this step-by-step guide! Follow FlyCode on Twitter to be notified when new content is available!

Discussion (0)