Vue-i18n: TypeError: "i18n is undefined" when extending Vue component

Created on 30 Apr 2019  路  7Comments  路  Source: kazupon/vue-i18n

vue & vue-i18n version

Vue: 2.6.10, vue-18n: 8.11.2

Reproduction Link

https://codesandbox.io/s/0p2l41ql0w

Steps to reproduce

  1. Create a component with using $t function
  2. Extend, instantiate and mount it anywhere else in the app

What is Expected?

Component should mount properly

What is actually happening?

A typeError is thrown because this.$i18n is undefined inside $t function


I'm using nuxt-i18n but the bug happens when using vue-i18n directly too

Most helpful comment

I get the same message, dont know if these are related. For me $t works between <template></template> tags, but not inside my typescript component. There, I have to use this.$root.$t for the error to go away.

All 7 comments

I've found a workaround for the moment by accessing the i18n store directly in my extended component but if someone has a better solution please tell me !

I think the real problem here is that i18n is getter-only in the Vue protoype so can't set it before extending my component.

I don't know if this is clear but I'm using Nuxt and Vue.extend to clone a component and injecting it in the dom after. Because the Vue instance used by Nuxt and the one I use to extend are not the same, the i18n attribute is undefined with the custom one. So I need to pass Nuxt's i18n into Vue's one.

For example, to pass the store I do that:
Vue.prototype.$store = this.$store;
and then
Vue.extend(MyComponent);
But I can't do the same with i18n for the reasons I explained above.

If you need further details please feel free to ask me.

Thanks !

Hi @ValentinCrochemore
Thanks for repro and detailed investigation 馃憤

I think the real problem here is that i18n is getter-only in the Vue protoype so can't set it before extending my component.

Hmm, if so, this issue sounds more like limitation to Vue 2.6.
Do you have any idea about how to improve vue-i18n to overcome this?

I get the same message, dont know if these are related. For me $t works between <template></template> tags, but not inside my typescript component. There, I have to use this.$root.$t for the error to go away.

Hey @exoego thanks for your answer !

I must admit I don't know how to improve this. Maybe it comes from Vue, maybe it comes from Nuxt when it injects modules, I don't know. But what I did was a really edgy case that I finally gave up to adopt a more conventional way. My workaround was to put the component in the <template> like any other one, hide it and clone it elsewhere when I need it. This way I can access Nuxt context and solve my problem.

If anyone know how to solve it, if it is really an issue to solve, I'd be glad to hear it.

Concerning @darthf1 I don't know either, I don't use Typescript but it seems that somthing (maybe typescript's implementation) is changing the context and removes $t :man_shrugging:
I suggest that you create another issue if you didn't yet.

Thanks @clovis-maniguet for your very interesting advice but it doesn't fit my use case perfectly :wink:

Hey Guys,

I found a workaround for this when using Vue.extend. Basically I passed the $t global function into the component like this:

const ComponentClass = Vue.extend(CarDetails);
const instance = new ComponentClass({
   methods: {
        t:(...args) => this.$t(...args)
   }
})

Then inside the component, swtich the function call $t(...) to t(...).

Hope this helps!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

flaird picture flaird  路  28Comments

tvld picture tvld  路  19Comments

tobeorla picture tobeorla  路  18Comments

Mrkisha picture Mrkisha  路  29Comments

nchutchind picture nchutchind  路  17Comments