In this short post we will look into adding Internationalization to a Vue.js project. This will allow us to support multiple languages for all our text elements
to start we will create a simple Vue project using the Vue cli as follows
vue init webpack i18nSample
we can test the application by going to the directory created and starting the project
cd i18nSample npm run dev
Now lets add internationalization to this project
vue-i18n Plugin
We will be using the vue-i18n plugin to support language translations
to install the plugin via npm run the following command line
npm install vue-i18n --save
next we will create a folder called ‘plugins’ under the ‘src’ folder and create a new file called i18n.js with the following content
import VueI18n from 'vue-i18n' import Vue from 'vue' import { DEFAULT_LANGUAGE, FALLBACK_LANGUAGE } from '@/constants/translations' import en from '@/lang/en.json' import es from '@/lang/es.json' import de from '@/lang/de.json' Vue.use(VueI18n) export const i18n = new VueI18n({ locale: DEFAULT_LANGUAGE, // set locale fallbackLocale: FALLBACK_LANGUAGE, messages: { en, es, de }// set locale messages })
we need to create the folder and file for our constants. Lets create a folder called constants and a file called translations.js
export const DEFAULT_LANGUAGE = 'en' export const FALLBACK_LANGUAGE = 'en' export const SUPPORTED_LANGUAGES = ['en', 'es', 'de']
in addition we create a folder called ‘lang’ to keep our translation data
in the lang folder create a file called en.json as follows
<h1>{{ $t(helloMessage) }}</h1>
{ }
then create two more files just like it called es.json and de.json
now lets tell Vue to use the plugin. Add the following line to your main.js file
import { i18n } from '@/plugins/i18n'
and then add it to your Vue instance
new Vue({ el: '#app', i18n, components: { App }, template: '<App/>' })
running the project should again produce the same sample program without any errors
Now lets add some translations
edit the helloworld.vue file and change the content of the H1 tag to
<h1>{{ $t('helloMessage') }}</h1>
running the app now will show the text helloMessage but will also show the following warnings in the console
[vue-i18n] Cannot translate the value of keypath 'helloMessage'. Use the value of keypath as default. [vue-i18n] Value of key 'helloMessage' is not a string! [vue-i18n] Value of key 'helloMessage' is not a string!
now lets provide a translation in the main language which is english in our file en.json
{ "helloMessage": "Hello to our first Vue App with translations" }
after saving the title of our app should instantly change to the text provided in the translation and the warnings will go away as well.
to test our translations we will need to add a feature to switch languages. Lets add the following 3 buttons to our helloWorld.vue component
<button @click="changeToEnglish">English</button> <button @click="changeToSpanish">Espanol</button> <button @click="changeToGerman">Deutsch</button>
we need to import the plugin
import {i18n} from '@/plugins/i18n';
and then add the following methods
methods: { changeToEnglish: function () { i18n.locale = 'en'; }, changeToSpanish: function () { i18n.locale = 'es'; }, changeToGerman: function () { i18n.locale = 'de'; }, }
now if we run the app it will show the 3 buttons at the top. When clicking one of the other languages we get the following warnings and the text will not change
[vue-i18n] Fall back to translate the keypath 'helloMessage' with 'en' locale. [vue-i18n] Value of key 'helloMessage' is not a string!
of course we didnt supply any translation for our message. Lets modify the es.json and de.json files as follows
{ "helloMessage": "Hola a nuestra primera aplicación Vue con traducciones." }
{ "helloMessage": "Willkommen zu unserer ersten Vue App mit Übersetzungen" }
these are automated translations but for our test this will be good enough
Now lets run the app again and test the different languages
we can make the language switching even nicer. There is a vue package with flag icons called vue-flag-icon that contains all flags in an SVG collection.
we can install that package using the following command line
npm install vue-flag-icon --save
Once installed we have to important and use them
import FlagIcon from 'vue-flag-icon' Vue.use(FlagIcon)
lets add a constant for our supported languages to translations.js in our constants folder
export const LANGUAGES_INFO = [ { flagIcon: 'us', language: 'en', Name: 'English' }, { flagIcon: 'es', language: 'es', Name: 'Español' }, { flagIcon: 'de', language: 'de', Name: 'Deutsch' } ]
in the helloworld component we import the constants
import { LANGUAGES_INFO } from '@/constants/translation'
then then add a data element for them
data () { return { langs: LANGUAGES_INFO, } },
this will give us an array of supported languages that we can use to create our buttons
lets remove the 3 buttons we created earlier and add the following
<button v-for="lang in langs" @click="changeLanguage(lang.language)"> <flag :iso="lang.flagIcon" /> {{ lang.Name }} </button>
then remove the 3 methods and add the following
changeLanguage(lang) { i18n.locale = lang; },
and to make the buttons look nicer lets add the following style
button { padding: 8px; margin: 6px; }
Now when running the app we should get 3 buttons with flags and the name of the language