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.


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

  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



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


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:

When I needed to, I used this:

  <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.