Tutorial

More i18n with Vue: Formatting and Fallbacks

Published on April 1, 2020
Default avatar

By Jim Toth

More i18n with Vue: Formatting and Fallbacks

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Today we’ll be covering how a number of formatting options available with the vue-i18n plugin for internationalization (i18n). We’ll also be covering how to handle fallbacks when no string is available for a locale. We’ll be using the vue-i18n plugin written by Kazuya Kawaguchi, and this article is building up from this previous one, which introduces using vue-i18n for internationalization (i18n) in Vue.js apps.

vue-i18n provides a number of ways to format your app strings. We can even define a custom formatter if you don’t like the default style. We can also provide fallbacks that are useful when we’re missing strings for a given locale.

App Setup

We’ll start by assuming you’ve already created a simple Vue app. Now we’ll add the vue-i18n plugin using your preferred method:

# Yarn
$ yarn add vue-i18n

# npm
$ npm install vue-i18n

# Vue CLI 3.x+
$ vue add i18n

We’ll continue where we left off in the last post. I’ll skip the code for the <SelectLocale /> component in that post since it won’t be changing, but feel free to include it if you’re following along from last time 🐊!

main.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';

import App from './App.vue';

Vue.use(VueI18n);

const messages = {
  en: {
    message: {
      hello: 'Hello, {name}!'
    }
  },
  de: {
    message: {
      hello: 'Guten Tag, {name}!'
    }
  }
};

const i18n = new VueI18n({
  locale: 'en',
  messages
});

new Vue({
  render: h => h(App),
  i18n
}).$mount('#app');
App.vue
<template>
  <div id="app">
    <HelloGator />
  </div>
</template>

<script>
import HelloGator from './components/HelloGator.vue';

export default {
  name: 'App',
  components: {
    HelloGator
  }
}
</script>
components/HelloGator.vue
<template>
  <div>{{ $t('message.hello', { name: 'Gator' }) }}</div>
</template>

<script>
export default { name: 'Gator' }
</script>

Formatting Features

We’ve already covered the basic formatting that vue-i18n uses with the code above. The plugin offers a couple of other formatting-related features such as lists, HTML, and custom formatters.

Lists

The vue-i18n plugin also provides a way to format using lists of variables. We’ll pass an array of strings as the second parameter of $t which are accessible in our app strings through their index:

main.js
const messages = {
  en: {
    message: {
      hello: 'Hello, {name}!',
      counting: 'One: {0}, Two: {1}, Three: {2}'
    }
  },
  de: {
    message: {
      hello: 'Guten Tag, {name}!',
      counting: 'Eins: {0}, Zwei: {1}, Drei: {2}'
    }
  }
};

Now let’s add our message.counting string to HelloGator.vue:

Template: components/HelloGator.vue
<div>
  {{ $t('message.hello', { name: 'Gator' }) }}
  <br />
  {{ $t('message.counting', ['🐊', '🤖', '👽']) }}
</div>

HTML

The vue-i18n plugin also lets us use HTML directly in our app strings. Any standard HTML will be rendered in the browser.

We’ll add the message.welcome app string below, wrapped with a <strong> tag:

main.js
const messages = {
  en: {
    message: {
      hello: 'Hello, {name}!',
      counting: 'One: {0}, Two: {1}, Three: {2}',
      welcome: '<strong>Welcome!</strong>'
    }
  },
  de: {
    message: {
      hello: 'Guten Tag, {name}!',
      counting: 'Eins: {0}, Zwei: {1}, Drei: {2}',
      welcome: '<strong>Wilkommen!</strong>'
    }
  }
};

Now let’s add our HTML app string to HelloGator.vue:

Template: components/HelloGator.vue
<div>
  {{ $t('message.hello', { name: 'Gator' }) }}
  <br />
  {{ $t('message.counting', ['🐊', '🤖', '👽']) }}
  <br />
  {{ $t('message.welcome') }}
</div>

You should now see a bold Welcome! or Wilkommen! depending on the locale.

Ruby on Rails

There’s also out-of-the-box support for Ruby on Rails style i18n, if that’s your preference:

const messages = {
  en: {
    message: {
      hello: 'Hello, %{name}!',
      ...
    }
  },
  ...
}

Custom

You probably won’t need this feature, but the vue-i18n plugin also allows you to define your own custom formatter. We won’t cover this in detail here but it mostly involves writing a function that would take the place of the $t translation function made available by the plugin. Make sure to check the Custom Formatting Docs if you’d like to learn more.

Fallbacks

The vue-i18n plugin allows us to easily fallback on another locale’s app strings if the current locale is missing any.

Let’s add another app string called message.description which will only be available in English. We’ll also specify the fallbackLanguage so the plugin uses the English app strings if they’re missing from another locale:

main.js
const messages = {
  en: {
    message: {
      hello: 'Hello, {name}!',
      description: 'This sentence is in English!'
    }
  },
  de: {
    message: {
      hello: 'Guten Tag, {name}!'
    }
  }
};

const i18n = new VueI18n({
  locale: 'en',
  fallbackLocale: 'en',
  messages
});

Now let’s add our English-only message to HelloGator.vue:

Template: components/HelloGator.vue
<div>
  {{ $t('message.hello', { name: 'Gator' }) }}
  <br />
  {{ $t('message.description') }}
</div>

You’ll notice that when switching the locale to de we’ll see the first message in German with the second message in English. This is super useful if you’d like to begin adding support for a new locale but don’t have all the app strings defined yet.

Wrapping Up

With all of the formatting options offered by vue-i18n, it’s rare you’ll have to implement custom formatting logic yourself. There’s enough out-of-the-box support to cover most formatting use cases related to internationalizing your app. As always, make sure to check out the docs! 🤓

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Jim Toth

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Ok thanks for information keep going

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel