In
NuxtJS
on our home page we have a title which has the letters
JS
as a green color, a different color to the rest of the text. Obviously this is done by adding a span with a color of light-green. This span is then added to all the other languages we have. We then import this using
v-html
. So far so good. It works. Why change this?
title: 'The Intuitive <span class="text-nuxt-lightgreen">Vue</span> Framework',
<p v-html="$t('title')"></p>
So recently we added eslint to our main website. Obviously this didn't pass the rule where v-html
is considered a bad practice. But with eslint we can just turn off the rule. Problem solved. OK but what happens if we need to change the light-green to a dark-green. Well we need to change it in the i18n file of each language. Tedious? Well we could just do a find and replace. Problem solved.
So basically it means people can translate our text and change the text and color to anything they like. But surely they wouldn't do that. But that's not the point. Should we really have this in our translations? Is it really necessary? Isn't there a better way?
That's where i18n interpolation comes into practice. With i18n, instead of using v-html
we can instead use interpolation. How?
i18n gives us an <i18n>
component that we can use on any of our pages or inside our components. In this component we can set up the tag to be any html element we want such as h2
, div
, a
or whatever we want to use for that particular text.
<i18n tag="h1"></i18n>
We then allocate it to our translation. If for example in our en-EN.js file we have homepage.title
:
module.exports = {
homepage: {
title:
'The Intuitive <span class="text-nuxt-lightgreen">Vue</span> Framework'
Then this is what we will use as the path in our <i18n>
component.
tag="h1"
path="homepage.title"
</i18n>
We can also add classes to our component just like any other component
tag="h1"
path="homepage.welcome.title"
class="title"
</i18n>
We can now use slots inside our component to render what we want, which in our case is our span class. We give the slot a name so we can then refer to it in our translation file. And then we add our span.
tag="h1"
path="homepage.welcome.title"
class="title"
<template v-slot:frameworkType>
<span class="text-nuxt-lightgreen">
</span>
</template>
</i18n>
Now in our translation file we can add the name of our slot enclosed in curly brackets where we want the actual span to appear.
module.exports = {
homepage: {
title: 'The Intuitive {frameworkType} Framework'
This will now give us the translated text with a placeholder for our span class. And in our fr-FR.js file we can add the French translation where our placeholder will go at the end of the sentence instead of after the word Intuitive like in English.
module.exports = {
homepage: {
title: 'Le Framework Intuitif basé sur {frameworkType}'
Now if we want to modify our span to be a different colour or add more styling we only have to do it in one place, and our translators only have to worry about translating the texts without having to deal with unnecessary html.
It is also possible to add more than one slot to your <i18n>
component. For example, for styling purposes, you might want to add a break in the sentence. Just make sure you give them unique names and then you can use the placeholders in your translation files.
tag="h1"
path="homepage.welcome.title"
class="title"
<template v-slot:br>
</template>
<template v-slot:frameworkType>
<span class="text-nuxt-lightgreen">
</span>
</template>
</i18n>
title: 'The Intuitive {br} {frameworkType} Framework',
title: 'Le Framework Intuitif {br} basé sur {frameworkType}',
As you an see it is much better to use i18n interpolation rather than v-html in your code as it allows you to keep your styling and html separate from your translations. This not only makes it easier for translators but it also makes it much easier to modify as the html code is not repeated throughout the translation files.
If you have never worked with i18n then check out these links to help you get started:
For more info on using i18n with Nuxt.js check out the nuxt-i18n module
For more info on component interpolation checkout the vue-i18n docs
To learn more about i18n checkout the i18n course on Vue School
Debbie O'Brien
Aug 17, 2020
4 min read
Share on
Twitter
LinkedIn