loading...
Cover image for 5 ways of displaying i18n translations in Vue

5 ways of displaying i18n translations in Vue

anzelika profile image Anzelika ・1 min read

When your Vue app needs internalization, you'll probably come across i18n. It took me a while to get a proper grasp on how to display messages in different scenarios (especially #5), so I'm laying out a quick easy-digest summary here.

1. Basic interpolation

With the interpolation curly brackets you can render any content that can be placed directly in your template HTML.

<p>{{$t('introText')}}</p>

2. Binding the value

Useful for input placeholders or labels.

<v-text-field :label="$t('form.firstName')"></v-text-field>

3. Within a function

Note that within the Vue instance it would be necessary to use this keyword

btnLabel(){
  return this.$t('buttons.save')
}

4. Using v-t directive

With v-t directive you may specify the path of the translation string in the data object and then easily render it in the template.

data: () => ({
   path: "buttons.add"  
}),
 <v-btn v-t="path"></v-btn>

NB: This directive is not reactive, therefore the content needs to be manually reloaded when the locale changes.

5. Using v-text directive

To solve the reactivity problem, you may use v-text directive instead.

data: () => ({
   path: "buttons.add"  
}),
 <v-btn v-text="$t(path)"></v-btn>

Hope this comes in handy for our translation wizards! Give me a shout if there's a technique I missed 😜

Posted on by:

anzelika profile

Anzelika

@anzelika

Self-taught front end pixie. Coffee enthusiast. Cat obsessionist. Vuetify contributor.

Discussion

pic
Editor guide
 

There is the v-t directive to prevent re-execution of the translation too.

 

Oh, very cool! Honestly was not even aware of that. Will replace the 4th point with that, since it's much cleaner than v-text :)

 

Though I just realised it's not reactive (if you change locale, it won't refresh the messages. v-text does though, without having to refresh the page. Do you know if there is a way to achieve reactivity with v-t?

You will need to re-render the component.
This dirty workarround can be done in some ways listed here:
michaelnthiessen.com/force-re-render/

When I needed to, I used this:

<template>
  <my-component v-if="renderComponent" />
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // Remove my-component from the DOM
        this.renderComponent = false;

        this.$nextTick(() => {
          // Add the component back in
          this.renderComponent = true;
        });
      }
    }
  };

and executed the forceRerender on watch for language change.