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!
Related Articles
How to use script setup in Nuxt 2
If you love Vue script setup and want to use it in your current Nuxt 2 project, the Nuxt team has made it possible to start using it today!
Feb 14, 2022
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.
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.
Dec 9, 2019
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.