28

I'm trying to use i18n outside a component I've found this solution https://github.com/dkfbasel/vuex-i18n/issues/16 telling to use Vue.i18n.translate('str'), but when I call this occurs an error Cannot read property 'translate' of undefined.

I'm using the following configuration

main.js

import i18n from './i18n/i18n';
new Vue({
    router,
    store,
    i18n: i18n,
    render: h => h(App)
}).$mount('#app')

i18n.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import i18nData from './i18nData'
Vue.use(VueI18n);
export default new VueI18n({
  locale: 'en',
  messages: i18nData,
});

i18nData.js

export default {
    en: {
        //my messages
    }
}

Then I trying to use this

import Vue from 'vue';
Vue.i18n.translate('someMessage');

Can anyone help me?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Alexandre Heinen
  • 623
  • 1
  • 7
  • 19

4 Answers4

50

To use i18n with Vue 3's composition API, but outside a component's setup(), you can access its translation API (such as the t function) on its global property.

E. g. in a file with unit-testable composition functions:

// i18n/index.js

import { createI18n } from 'vue-i18n'
import en from './en.json'

  ...

export default createI18n({
  datetimeFormats: {en: {...}},
  locale: 'en',
  messages: { en }
})
// features/utils.js

//import { useI18n } from 'vue-i18n'
//const { t } = useI18n() // Uncaught SyntaxError: Must be called at the top of a `setup` function

import i18n from '../i18n'

const { t } = i18n.global
dtk
  • 2,197
  • 2
  • 26
  • 19
  • 3
    This example do **not** use composition API mode of vue-i18n. For that you need createI18n({ legacy: false; }) – gagarine Jul 14 '21 at 21:17
  • 1
    @gagarine Is your comment about initialization only? can you provide better example? – lucaste Aug 01 '21 at 06:28
14

You should import i18n instead of Vue

import i18n from './i18n'

i18n.tc('someMessage')
ittus
  • 21,730
  • 5
  • 57
  • 57
8

You can use VueI18n outside components by importing i18n then, use "t" from i18n.global.

"t" doesn't need "$" and you can change Locale with i18n.global.locale.

import i18n from '../i18n';

const { t } = i18n.global;

i18n.global.locale = 'en-US'; // Change "Locale"

const data = { 
  name: t('name'), // "t" doesn't need "$"
  description: t('description'), // "t" doesn't need "$"
};
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
  • 1
    Alas, `Property 'global' does not exist on type 'typeof import("x/node_modules/vue-i18n/dist/vue-i18n")'.ts(2339)` – Lee Goddard Aug 12 '22 at 11:09
2

I managed to make it work this way:

import router from '../router';

Translate a text:

let translatedMessage = router.app.$t('someMessage');

Get the current language:

let language = router.app.$i18n.locale;
Timm
  • 31
  • 4