Create a i18n Plugin with Composition API in Vue.js 3

The way plugins are coded in Vue.js 3 with Composition API differ from traditional plugins. Traditional are used via a install function and added using Vue.use(plugin). They usually manipulate/extend the Vue prototype.

However, in Composition API plugins are non-manipulative and coded using an inject-provide pattern. For instance, you can create a i18n plugin like this:

// i18nPlugin.js
import { ref, provide, inject } from "@vue/composition-api";

const createI18n = config => ({
  locale: ref(config.locale),
  messages: config.messages,
  $t(key) {
    return this.messages[this.locale.value][key];
  }
});

const i18nSymbol = Symbol();

export function provideI18n(i18nConfig) {
  const i18n = createI18n(i18nConfig);
  provide(i18nSymbol, i18n);
}

export function useI18n() {
  const i18n = inject(i18nSymbol);
  if (!i18n) throw new Error("No i18n provided!!!");

  return i18n;
}

As you can see, the functions provide and inject are used to create the plugin instance and hold it in a dependency injection mechanism.

Check that we use ref for the locales, since we need the to be reactive.

If you're not very familiar yet with Composition API, please read the tip to easily migrate to Composition API and how to use old instance properties to get a bit more in detail about it.

Then, once in the app you must initialize the plugin with the right configuration by using the provideI18n function. That's usually done in the root App.vue component:

<script>
  import { provideI18n } from "./i18nPlugin";
  import HelloWorld from "./HelloWorld";

  export default {
    components: { HelloWorld },
    setup() {
      provideI18n({
        locale: "en",
        messages: {
          en: {
            hello_world: "Hello world"
          },
          es: {
            hello_world: "Hola mundo"
          }
        }
      });
    }
  };
</script>

Finally, in any component we want to use the plugin, we must inject it by using the useI18n function in the setup function. Create a HelloWorld.vue component with:

<template>
  <div>
    <h2>{{ i18n.$t('hello_world') }}</h2>
  </div>
</template>

<script>
  import { useI18n } from "./i18nPlugin";

  export default {
    setup() {
      const i18n = useI18n();

      return { i18n };
    }
  };
</script>

But hey... what's the fun of it if we cannot change the language? Let's add to the previous code the functionality to change the language:

<template>
  <div>
    <h2>{{ i18n.$t('hello_world') }}</h2>
    <button @click="switchLanguage">Switch language</button>
  </div>
</template>

<script>
  import { useI18n } from "./i18nPlugin";

  export default {
    setup() {
      const i18n = useI18n();

      const switchLanguage = () => {
        const locale = i18n.locale.value === "en" ? "es" : "en";
        i18n.locale.value = locale;
      };

      return {
        i18n,
        switchLanguage
      };
    }
  };
</script>

Just by adding a button and the switchLanguage function we already have the feature.

That's all. What I like the most about Composition API is the easiness to develop code that is predictable and maintainable by providing clean patterns.

How do you like it?

If you want to see with your own eyes that this code truly works, go and check it in this CodeSandbox!

That's it for today's tip!

Don't miss out anything about Vue, your favourite framework.

Subscribe to receive all the articles we publish in a concise format, perfect for busy devs.

Related Articles

Use Composition API to easily handle API requests in Vue.js

Not sure how to organize your API client in Vue.js? Learn this simple technique on how to do it using the new Composition API and make it easy.

Carlos Rodrigues

Carlos Rodrigues

Jul 6, 2020

Access template refs in Composition API in Vue.js 3

Quick tip on how to access the old this.$refs by using ref() in the new Composition API in Vue.js 3 components.

Alex Jover Morales

Alex Jover Morales

Dec 9, 2019

Use old instance properties in Composition API in Vue.js 3

Learn how to use this.$emit, this.$attrs and more in the new Composition API, where you have no this instance in your Vue.js Components.

Alex Jover Morales

Alex Jover Morales

Nov 26, 2019

Sponsors

VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.

Silver
StoryBlok
Learning Partner
Vue School