dkfbasel / vuex-i18n

Localization plugin for vue.js 2.0 using vuex as store
MIT License
666 stars 56 forks source link

Problem when refresh page in Nuxt project #75

Open dimaslz opened 6 years ago

dimaslz commented 6 years ago

Hi, I read the others issues about problems with nuxt but anyone can help me. I explain my case:

I using the plugin like this:

import Vue from 'vue';
import Vuex from 'vuex';
import vuexI18n from 'vuex-i18n/dist/vuex-i18n.umd.js';

const createStore = () => {
  const store = new Vuex.Store({
    state: {
      counter: 0,
    },
    mutations: {
      increment (state) {
        state.counter++
      }
    }
  });

  Vue.use(vuexI18n.plugin, store);
  const locale = 'en';
  Vue.i18n.add('es', require(`~/locales/es.json`));
  Vue.i18n.add('en', require(`~/locales/en.json`));
  Vue.i18n.add('fr', require(`~/locales/fr.json`));
  Vue.i18n.set(locale);

  return store;
}

export default createStore

And the first time is working perfect, but when I reload the page, the console is returning:

screen shot 2018-03-20 at 21 12 42

And if I use the plugin as nuxt instruction like { src: '~plugins/i18n', ssr: false },, when I save and do the hot-reload, everything is working perfect but when I reload, the error is:

screen shot 2018-03-20 at 21 15 13

but, if in the created() or mounted() do a console.log(this.$t) $t exist.

And I using the custom routers with vue-router

Thanks in advance!

tikiatua commented 6 years ago

Hi @dimaslz

Thank you for reporting this issue. We are not using nuxt ourselves, therefore I have very little experience with it. I will try to find some time next week to look into the issue. Would be great if someone else with some experience with nuxt could chime in.

tikiatua commented 6 years ago

Hmm..

According to the nuxt documentation and some issues if found for vuex plugins, it could be possible that plugins need to be registered differently for nuxt.

https://nuxtjs.org/guide/vuex-store https://github.com/nuxt/nuxt.js/issues/972#issuecomment-332308183 https://github.com/nuxt/nuxt.js/issues/560

dimaslz commented 6 years ago

Hi @tikiatua I did my own i18n plugin and works perfect. I will try to do a PR about my solution. I think it is something easy, but I need to check in deep.

Kind regards!

abhipanda commented 6 years ago

Its a blocker - happening for SSR in general - I am using hackernews template

Ado20 commented 6 years ago

Hi, there are some problems with dynamic vuex module registration during SSR. That's why you have to register i18n module at startup manually:

1.) register vue plugin

import vuexI18n from 'vuex-i18n/dist/vuex-i18n.umd.js'
Vue.use(vuexI18n.plugin, store)

2.) register vuex module

import vuexI18n from 'vuex-i18n/dist/vuex-i18n.umd.js'
const store = new Vuex.Store({
  modules: {
    i18n: vuexI18n.store
  }
})

The error should disappear :)

AshleyCao commented 5 years ago

@dimaslz Has your problem solved? If not, what about vuex-persistedstate?

ortegarenzy commented 3 years ago

Issue is still existing specially when used with SSR. The registered module "i18n" is lost when the translate function is called after refresh

tikiatua commented 3 years ago

Hi @ortegarenzy

Thank you for bringing this to our attention again. I will put this on the list of things to investigate. Need to understand first how nuxt works its magic with state persistence.

ortegarenzy commented 3 years ago

@tikiatua In my case, I am not using Nuxt and I am following this guide

This is where I registered the vuex-i18n in my store/index.js

export function createStore(preserveState = false) {
    var store = new Vuex.Store()
    var config = {
        moduleName: "i18n"
    }
    if(preserveState) {
        config.preserveState = !!store.state[config.moduleName]
    }
    Vue.use(vuexI18n.plugin, store, config)
    if(preserveState === false) {
        Vue.i18n.add("fi", fi)
        Vue.i18n.add("en", en)
    }
    Vue.i18n.set("fi")
    return store
}

On my understanding, I need to register it on both server side and client side. When executed on the client side, I don't need to add the translations but instead use the state that was registered on the server, hence the use of preserveState here.

Maybe I used it incorrectly ?

UPDATE

@tikiatua After some time debugging it, I found the "probable cause" why we encounter the error.

The library is installed via Vue.use, and according to the docs

Vue.use automatically prevents you from using the same plugin more than once, so calling it multiple times on the same plugin will install the plugin only once.

In my case, createStore is called multiple times(based from here) and returns always a fresh instance of Vuex.Store, but the line Vue.use(vuexI18n.plugin, store, config) is prevented from executing by Vue. By the time the createStore is called more than once, the previously registered module of vuex-i18n is already lost due to the fresh instance returned by createStore.

My workaround for the time being is not to call Vue.use() but instead call vuexi18n.plugin.install(Vue, store, config) manually, which is not the intended way to use this library. Hopefully this would also give some insight as to how this library should really behave when used in SSR