Hi there! First of all, I’m sorry for this time of no posting any tips… I was developing some VueDose internals and switching the email tool in order to make it easier to post more Vue tips for you! So… back to the ride!

Before starting: are you planning to learn about testing Vue.js apps? In the next Vue Day Verona, 4th April, I’ll be giving the “Vue Testing for Everyone” workshop, where I’ll share all my knowledge and experience on the topic. Regular tickets just started, and there are only 10 remaining!

About conferences, I’ll be next week in Vue Amsterdam and have some surprises! Hope to see you there and say hi.

No more words, let’s go to the tip!

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!

Remember you can read this tip online (with copy/pasteable code), and don’t forget to share VueDose with your colleagues, so they also know about these tips as well!

See you soon.

Start saving time and get a tip about the Vue ecosystem every week, right in your inbox.

Latest Vue Jobs