Internationalization for vue 3 vite with i18n
Asked Answered
A

2

9

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
})
Aekerly answered 21/3, 2021 at 13:14 Comment(0)
J
22

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>
Josephjosepha answered 21/3, 2021 at 13:23 Comment(3)
How can we change locale when action triggered??Jahveh
I found that you can use $i18n.locale = 'es' for example to change to spanishJahveh
Yes in options api or template you could do thatJosephjosepha
S
17

I have an additional example to show of accessing the global composer instance in vue-i18n v9:

i18n.js

import { createI18n } from 'vue-i18n';
import en from './locales/en';
import fr from './locales/fr';

const i18n = createI18n({
    legacy: false,
    locale: 'en',
    fallbackLocale: 'en',
    messages: {
        en,
        fr,
    },
});

export default i18n;

main.js

import i18n from './i18n.js';

...

app.use(i18n);

Then you can import the instance into any file, such as vue-router's beforeEnter hook or vuex, etc.

import i18n from '../i18n.js';

console.log('i18n', i18n.global);

// to change locale:
i18n.global.locale.value = 'en';

You access it via i18n.global. it is the same instance that is returned via useI18n() from the 'vue-i18n' package.

Swithin answered 22/12, 2021 at 20:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.