Categories
Vue

Creating Multilingual Apps with vue-i18n

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *