Search code examples
vue.jsquasarpiniavue-i18n

How do I update translated text when changing a language in a Vue.js app with i18n and Pinia?


I'm using i18n and Pinia to try to change languages in my application, but when I change the language, only the value of localStorage.language changes, but the text doesn't. I tried to make the change using pinia to "force" a re-render, but it didn't work either. I would like to know how I can do this because although the value of localStorage.language does change, the application doesn't re-render.

This is my language store:

import { defineStore } from 'pinia'

export const useLanguageStore = defineStore('languages', {
  store: () => {
    return {
      language: 'es',
    }
  },
  actions: {
    setNewLanguage({ newLanguage } = {}) {
      if (!localStorage.language) {
        this.language = newLanguage ?? 'es'
        localStorage.setItem('language', this.language)
      }
    }
  },
})

This is the i18n.js:

import { createI18n } from 'vue-i18n'
import messages from '@intlify/unplugin-vue-i18n/messages'

import pinia from '../stores'

export const i18n = createI18n({
  legacy: false,
  globalInjection: true,
  locale: localStorage.language,
  fallbackLocale: 'es',
  availableLocales: ['de', 'en', 'es', 'ja', 'pt', 'ru', 'zh'],
  messages: messages
});

And this is my main.js (in case it's necessary):

import { createApp } from 'vue'
import { Quasar } from 'quasar'
import quasarLang from 'quasar/lang/es'
import router from './routes/router.js'
import { createPinia, PiniaVuePlugin } from 'pinia'

// Import icon libraries
import '@quasar/extras/material-icons/material-icons.css'
import '@quasar/extras/material-icons-outlined/material-icons-outlined.css'
import '@quasar/extras/material-icons-round/material-icons-round.css'
import '@quasar/extras/material-icons-sharp/material-icons-sharp.css'

// A few examples for animations from Animate.css:
import '@quasar/extras/animate/fadeIn.css'
import '@quasar/extras/animate/fadeOut.css'

// Import Quasar css
import 'quasar/src/css/index.sass'

import { i18n } from './utils/i18n.js'

import App from './App.vue'

createApp(App)
.use(createPinia())
.use(Quasar, {
  plugins: {}, // import Quasar plugins and add here
  lang: quasarLang,
})
.use(router)
.use(i18n)
.mount('#app')

I have left the repository public for more information (clearly, it has the latest changes); anyway, I haven't started the actual development yet, so there shouldn't be a problem: https://github.com/Santiago1010/idi-front


Solution

  • You are not setting the i18n locale when you try to switch the language in your setNewLanguage function. You only update localStorage, but localStorage is not reactive.

    You should import i18n in your Pinia store:

    import { i18n } from './utils/i18n.js';
    

    And set the global locale in your setNewLanguage function:

    i18n.locale = ‘es’;
    

    See i18n docs: https://vue-i18n.intlify.dev/guide/essentials/scope.html#locale-changing