I'm currently trying to internationalize my vue 3 vite project with "@intlify/vite-plugin-vue-i18n". The problem I am facing here, is that i currently have to import and setup the t variable for every component to use it.
example component:
<template>
t('translation')
</template>
<script>
import { useI18n } from 'vue-i18n'
export default {
setup(){
const {t} = useI18n();
return {t}
},
};
</script>
My question is, if its possible, what is the best way to make the variable "t" global? I cant find any examples/help on this, since they all import it into every compoenent. All help would be apreciated! :) For reference, here are the relevant files.
export default defineConfig({
plugins: [
vue(),
vueI18n({
include: path.resolve(__dirname, './src/locales/**')
})
]
})
main.ts:
import i18n from './i18n';
const app = createApp(App);
app.use(i18n);
app.mount("#app");
i18n.js:
import { createI18n } from 'vue-i18n'
import messages from '@intlify/vite-plugin-vue-i18n/messages'
export default createI18n({
legacy: false,
locale: 'no',
messages
})
The i18n plugin registering using app.use(i18n)
make a global function $t
available for all the children components :
<template>
{{$t('translation')}}
</template>
This function is also available in option api and you could it like :
mounted() {
console.log(this.$t('translation'))
}
But you should add globalInjection: true,
to i18n config as follows :
import { createI18n } from 'vue-i18n'
import messages from '@intlify/vite-plugin-vue-i18n/messages'
export default createI18n({
legacy: false,
locale: 'no',
globalInjection: true,
messages
})
BONUS :
Change the locale by watching the getter inside App.vue
then set locale:
<script>
import { defineComponent, onMounted, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useStore } from "vuex";
export default defineComponent({
name: "app",
data() {
return {};
},
setup() {
const i18n = useI18n();
const store = useStore();
watch(()=>store.getters.currentLang,(newVal) => { //watch the getter
i18n.locale.value = store.getters.currentLang;
},{
immediate:true
});
},
});
</script>