Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
In this article, we’ll look at how to create multilingual Vue apps with vue-i18n.
Getting Started
To get started, we install the package by writing:
npm i vue-i18n
Then we can write:
main.js
import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
const messages = {
en: {
message: {
hello: "hello"
}
},
fr: {
message: {
hello: "bonjour"
}
}
};
const i18n = new VueI18n({
locale: "fr",
messages
});
Vue.config.productionTip = false;
new Vue({
i18n,
render: h => h(App)
}).$mount("#app");
And we can display the translation by writing:
<template>
<div id="app">
<p>{{ $t("message.hello") }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
Formatting
We can interpolate expression in our messages by writing:
import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
const messages = {
en: {
message: {
hello: "{msg} world"
}
},
fr: {
message: {
hello: "bonjour"
}
}
};
const i18n = new VueI18n({
locale: "en",
messages
});
Vue.config.productionTip = false;
new Vue({
i18n,
render: h => h(App)
}).$mount("#app");
And in our component, we can write:
<template>
<div id="app">
<p>{{ $t('message.hello', { msg: 'hello' }) }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
Then we get hello world
displayed on screen.
List Formatting
We can format lists with vue-i18n.
For example, we can write:
const messages = {
en: {
message: {
hello: "{0} world"
}
},
fr: {
message: {
hello: "bonjour"
}
}
};
And we can write:
<template>
<div id="app">
<p>{{ $t('message.hello', ['hi']) }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
to display hello world
.
We can also use an array-like object instead of an array:
<template>
<div id="app">
<p>{{ $t('message.hello', {'0': 'hi'}) }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
And we get the same thing.
Ruby on Rails Message Format
The placeholder can also be written in Ruby on Rails format.
For instance, we can write:
const messages = {
en: {
message: {
hello: "%{msg} world"
}
},
fr: {
message: {
hello: "bonjour"
}
}
};
And we write:
<template>
<div id="app">
<p>{{ $t('message.hello', {msg: 'hi'}) }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
Custom Formatter
We can add a custom formatter class:
class CustomFormatter {
constructor (options) {
// ...
}
interpolate (message, values) {
return ['resolved message string']
}
}
Then we can set it in the message that we pass into the VueI18n
constructor:
const i18n = new VueI18n({
locale: 'en',
formatter: new CustomFormatter(),
messages: {
en: {
// ...
},
// ...
}
})
We just set the formatter
property of the object we pass into the constructor.
Pluralization
vue-18n supports pluralization.
To add single and plural words to messages
, we add the words to a string separated by the |
character.
For instance, we can write:
import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
const messages = {
en: {
apple: "apple | apples",
orange: "no oranges | one orange | {count} oranges"
}
};
const i18n = new VueI18n({
locale: "en",
messages
});
Vue.config.productionTip = false;
new Vue({
i18n,
render: h => h(App)
}).$mount("#app");
Then we write the following in our component:
<template>
<div id="app">
<p>{{ $tc('apple', 1) }}</p>
<p>{{ $tc('apple', 2) }}</p>
<p>{{ $tc('orange', 0) }}</p>
<p>{{ $tc('orange', 1) }}</p>
<p>{{ $tc('orange', 5, { count: 5 }) }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
And we get:
apple
apples
no oranges
one orange
5 oranges
on the screen.
We used the $tc
function instead of the $t
function for regular translations.
The placeholder is in the braces.
DateTime Localization
Date and time can also be localized, we just have to pass in an object with the date formats we want to show.
To do that, we write:
import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
const dateTimeFormats = {
en: {
short: {
year: "numeric",
month: "short",
day: "numeric"
},
long: {
year: "numeric",
month: "short",
day: "numeric",
weekday: "short",
hour: "numeric",
minute: "numeric"
}
}
};
const i18n = new VueI18n({
locale: "en",
dateTimeFormats
});
Vue.config.productionTip = false;
new Vue({
i18n,
render: h => h(App)
}).$mount("#app");
Then we can use the $d
function as follows:
<template>
<div id="app">
<p>{{ $d(new Date(), 'short') }}</p>
<p>{{ $d(new Date(), 'long', 'en') }}</p>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
We pass in the 'long'
and 'short'
format strings and optionally the language.
Conclusion
We can use vue-i18n to format localize our apps.
Text, single and plural words, and dates can be added for different locales.