Skip to content

TypeError: _ctx.$t is not a function when using $t in child component #350

Closed
@boussadjra

Description

@boussadjra

vue & vue-i18n version

  • vue: 3.0.0
  • vue-i18n: 9.0.0-rc.7

Reproduction Link

https://github.com/boussadjra/vue3-tailwind2

Steps to reproduce

I added a file named i18n.ts next to main.ts which contains the following snippet :

import { createI18n } from "vue-i18n";

const i18n = createI18n({
  legacy: false,
  locale: "ja",
  messages: {
    en: {
      message: {
        language: "English",
        greeting: "Hello !"
      }
    },
    ar: {
      message: {
        language: "العربية",
        greeting: "السلام عليكم"
      }
    },
    es: {
      message: {
        language: "Español",
        greeting: "Hola !"
      }
    }
  }
});
export default i18n;

then I imported the file inside main.ts and use it :

...
import i18n from './i18n'
let root = app.use(i18n).use(store).use(router).mount('#app')

then I added the following snippet to home.vue :

<h2>{{ $t("message.greeting", {}, { locale: "en" }) }}</h2>

What is Expected?

Render the message Hello !

What is actually happening?

but this is giving the following error :

Uncaught (in promise) TypeError: _ctx.$t is not a function
at Proxy.render (Home.vue?bb51:2)

Activity

danielpetrica

danielpetrica commented on Feb 19, 2021

@danielpetrica

Hi, I think this may be similar to my issue, I found out that to have the global $t injected like on previous version I neet to pass
globalInjection: true, in the createI18n() function options.

So your i18n.ts may look like this:

import { createI18n } from "vue-i18n";

const i18n = createI18n({
  legacy: false,
  locale: "ja",
  globalInjection: true,
  messages: {
    en: {
      message: {
        language: "English",
        greeting: "Hello !"
      }
    },
    ar: {
      message: {
        language: "العربية",
        greeting: "السلام عليكم"
      }
    },
    es: {
      message: {
        language: "Español",
        greeting: "Hola !"
      }
    }
  }
});
export default i18n;
boussadjra

boussadjra commented on Feb 19, 2021

@boussadjra
Author

@danielpetrica Wow it works like charm, thank you very very much

danielpetrica

danielpetrica commented on Feb 19, 2021

@danielpetrica

@boussadjra I'm glad it worked.
This may be useful in the future. I found out that $t is not available everywhere (like inside other .ts files) but if you add this function to the i18n file you can import it and use it to translate strings:

// file: i18n.ts
/**
 * it's ugly but we can use this to translate strings inside js code
 * @param key
 */
export const translate = (key: string) => {
    if (!key) {
        return '';
    }
    return i18n.global.t(key);
};
// another .ts file
import { translate } from 'path to i18n file'
...
console.log(translate('message.languge'))
osahene

osahene commented on Mar 6, 2021

@osahene

How do I resolve the same issue in a js file?

oscyp

oscyp commented on Mar 30, 2021

@oscyp

@danielpetrica for me this.$t works inside component definition.

hks2002

hks2002 commented on Apr 27, 2021

@hks2002

Vue3 and vue-i18n-next sample, it could works as bellow:

<template>
  <q-page class="flex flex-center">
    <img alt="Quasar logo" src="/imgs/logo.svg" />
    <div>{{ t("success") }}</div>
  </q-page>
</template>

<script>
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";

export default defineComponent({
  name: "PageIndex",
  setup() {
    const { t } = useI18n();
    return {
      t,
    };
  },
});
</script>
  • import useI18n:
import { useI18n } from "vue-i18n";
  • define function in setup():
const { t } = useI18n();
  • using t in the template:
<div>{{ t("success") }}</div>
dybxin

dybxin commented on Jul 13, 2021

@dybxin

@hks2002 how to use t("") in <script></script>

dybxin

dybxin commented on Jul 13, 2021

@dybxin

if i only use in *.js file and not setup() how to use i18n? @hks2002

gwen1230

gwen1230 commented on Jul 22, 2021

@gwen1230

Hi ! I have same issue but with $tc. I pass globalInjection to true, $t is available but not $tc.

danielpetrica

danielpetrica commented on Jul 22, 2021

@danielpetrica

Hi ! I have same issue but with $tc. I pass globalInjection to true, $t is available but not $tc.

Hi @gwen1230 from what i can see the plurarization has been integrated in t()when using composition api https://vue-i18n.intlify.dev/guide/advanced/composition.html#pluralization

gwen1230

gwen1230 commented on Jul 22, 2021

@gwen1230

Hi ! I have same issue but with $tc. I pass globalInjection to true, $t is available but not $tc.

Hi @gwen1230 from what i can see the plurarization has been integrated in t()when using composition api https://vue-i18n.intlify.dev/guide/advanced/composition.html#pluralization

Yes I saw that and it works with composition API. But with global injection, $t is like the old $t, and $tc doesn't seem to exist.

21 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jbiddulph@terwer@stevereinke@danielpetrica@devinRex

        Issue actions

          TypeError: _ctx.$t is not a function when using $t in child component · Issue #350 · intlify/vue-i18n