Search code examples
vue.jsvuexvuejs3vitevue-i18n

Internationalization for vue 3 vite with i18n


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
})

Solution

  • 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>