When trying to use an i18n message in a Nuxt3 Pinia store I get the error message:
"SyntaxError: Must be called at the top of a setup
function"
When using a message in a template I can do:
<template>
<p>{{ $t('welcome') }}</p>
</template>
But how to do it in the pinia store?
Here is what I tried in the store that led to the error:
import { defineStore } from 'pinia';
const { t } = useI18n();
export const useAppStore = defineStore('appStore', {
state: () => {
return {
label: $t('welcome')
};
},
});
Most composables in Nuxt require application context to work with. Having code inside setup()
option or using <script setup>
tag in components ensures the context is known. It is also automatically available when the app is parsing templates - this is why it "just works" inside your template.
The problematic line is const { t } = useI18n();
because placed like this it is executed immideately upon loading the script and not after it is invoked from some component.
I find out following works for referencing I18n translation function from within scripts as $i18n
object is being added into Nuxt application via the module and useNuxtApp()
exposes the app instance to you:
export const useAppStore = defineStore('appStore', {
state: () => {
return {
label: useNuxtApp().$i18n.t('welcome')
};
},
});
Since I find the syntax a bit verbose, I usually create a composable wrapper around it to spare some characters:
export function useT (key: string): string {
return useNuxtApp().$i18n.t(key)
}
Then I can only call useT('welcome')
Providing you invoke useAppStore()
inside your component's setup, it should work fine, because the Pinia store shouldn't init prior to the first useAppStore()
call.