Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue 3 - useI18n - Uncaught SyntaxError: Must be called at the top of a `setup` function

I have a problem with useI18n that I'm unable to solve. Whatever I do, I am unable to get i18n translation to work and in my console perpetually see this message:

Uncaught SyntaxError: Must be called at the top of a setup function

The stack-track reveals that it happens when invoking the useI18n() function despite it being within a function called setup. The next level up the stack trace reveals that within the ```useI18n()`` function that an exception is being raised due to it not detecting an instance of my app.

function useI18n(options = {}) {
    const instance = getCurrentInstance();
    if (instance == null) {
        throw createI18nError(I18nErrorCodes.MUST_BE_CALL_SETUP_TOP);
    }
...

My code is as follows:

main.js

// frontend/src/main.ts

import i18n from './i18n';

import Vue, { createApp } from 'vue';

import axios from 'axios';
import VueAxios from 'vue-axios';

import App from './App.vue';

//Vue.use(VueI18n);

const app = createApp(App);
app.use(VueAxios, axios, i18n);
app.provide('axios', app.config.globalProperties.axios);
app.mount('#i-english-editor');

console.log(app);

i18n.ts

import { createI18n } from "vue-i18n";

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

export default i18n;

App.vue

<div>
{{ t('message.greeting') }}
</div>
...
<script lang="ts">
import {defineComponent, ref, inject} from "vue";
import { useI18n } from "vue-i18n";

export default defineComponent({
  setup() {
    const { t } = useI18n();

...


    return {
      ...
      {t},
    }
  }
});
</script>

As you can see, my code looks like the various examples online showing me how to get translations working. I've looked at various solutions and none of them are working for me. This includes trying an alternative method of setting globalInjection to true and using {{ $t('message.greeting') }} in a tag which reveals the error:

ctx.$t is not a function

I am literally at a dead end and can't figure out a solution that seems to work for most people. My version of Vue is Vue 3 and the version of i18n I'm using is [email protected].

If anyone knows why this is happening to me but no-one else, I'd appreciate it if you have a solution.

like image 988
Richard Avatar asked Dec 07 '25 08:12

Richard


1 Answers

This is an old question, but today I found the same problem and stills to be not clear on the web.

It seems that the useI18n() is a composal function that is implemented by Composition API, must be called at the top of a setup function, to use on a TS file without a setup we need to use the useNuxtApp() to add the context.

export default (): string => {
  const { $i18n } = useNuxtApp();
  const t = $i18n.t;

  return t('my-translation-key');
};

I hope helps.

like image 141
BlackSlash Avatar answered Dec 10 '25 10:12

BlackSlash