Search code examples
vue.jspiniavue-i18n

Vue - How to use vue-i18n inside a pinia store


I am trying to use vue-i18n inside a pinia store's actions block. But I could not get it to work. Here is my i18n instance:

import en from './en.json'
import ja from './ja.json'

export const createI18nInstance = () => {
    return createI18n({
        legacy: false,
        locale: localStorage.getItem('app-lang') || navigator.language || 'en',
        messages: {
            en,
            'en-US': en,
            ja
        }
    })
}

export const i18n = createI18nInstance()

Here is a sample usage. setBanner is a pinia action from another store and takes the translated message as the first argument and passes it tto a bootstrap alert component.

export const useTodos = defineStore("todos", {
    state: () => ({
        todos: [],
    actions: {
        async addTodo(todo) {
            const bannerStore = useBanner()
            try {
                const res = await todoService.addTodo(todo)
                if (res.status === 201) {
                    this.todos.push(todo)
                    bannerStore.setBanner(`${this.$t('successAddSticky')}`, 'success')
                }
            } catch (error) {
                bannerStore.setBanner(`Failed To add todo item ${todo}: ${error}`, 'error')
            }
        },

Error:

Failed To add todo item [object Object]: TypeError: this.$t is not a function

Another attempt that I did:

        async addTodo(todo) {
            const bannerStore = useBanner()
            const { t } = useI18n()
            try {
                const res = await todoService.addTodo(todo)
                if (res.status === 201) {
                    this.todos.push(todo)
                    bannerStore.setBanner(`${t('successAddSticky')}`, 'success')
                }
            } catch (error) {
                bannerStore.setBanner(`Failed To add todo item ${todo}: ${error}`, 'error')
            }
        },Ï
Uncaught (in promise) SyntaxError: Must be called at the top of a `setup` function (at vue-i18n.js?v=db96110f:267:17)

Solution

  • use i18n global

    import { i18n } from "app/i18n"
    
    export const useTodos = defineStore("todos", {
        actions: {
            async addTodo(todo) {
    i18n.global.$t("message")
            },
        }
    })