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.
Table of contents
- Why do we choose Vue i18n next?
- 1. Create a new Vue 3 application
- 2. Install vue-i18n-next in your Vue 3 project
- 3. Test the i18n configuration on our Vue 3 project
- 4. Update the translations files
- 5. Refactor the HelloI18n component to use the locales’ folder translations
- 6. Create a Vue multi language switcher component
- Bonus: Manage your translations outside of your code with FlyCode 🚀
- Code is available on GitHub
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
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
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
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 withVUE_APP_I18N_LOCALE
andVUE_APP_I18N_FALLBACK_LOCALE
variables.i18n.js
(in thesrc/
folder): the i18n initialization by the createI18n function. There is a loadLocaleMessages function that loads your translation files.en.json
(in thelocales/
folder): your English translation file. It will contain all your project translations.HelloI18n.vue
(in thesrc/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>
Then, if you run your Vue application by typing npm run serve , you’ll have the following output:
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>
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 !!"
}
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
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"
}
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"
}
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(),
});
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>
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>
If you launch the project, you should have the below output.
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>
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>
Now, you can restart your project and play with the select! Here is the output for the French language:
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 is a step-by-step guide to managing your website translations using FlyCode.
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!