Vuex-persistedstate: Seems to not be working with Nuxt.js

Created on 29 May 2019  路  10Comments  路  Source: robinvdvleuten/vuex-persistedstate


Do you want to request a feature or report a bug?
Bug

What is the current behavior?
When I refresh my page, the state goes away

If the current behavior is a bug, please provide the steps to reproduce.

  1. Add the following code to the nuxt.config.js file:
plugins: [
{ 
      src: '~/plugins/localStorage.js',
      ssr: false 
    }
],
  1. In the localStorage.js file, the entire contents is this:
import createPersistedState from 'vuex-persistedstate'

export default ({store}) => {
  window.onNuxtReady(() => {
    createPersistedState({
        key: 'vuex',
        paths: []
    })(store)
  })
}

What is the expected behavior?
The state should remain when the page is refreshed.

If this is a feature request, what is motivation or use case for changing the behavior?
Not applicable.

Most helpful comment

I was having the same issues at first, it took me couple of hours to get it right :)

my folders structure

- store
-- index.js
-- listings.js
-- search.js
  • index.js
import createPersistedState from 'vuex-persistedstate'

export const state = () => ({
 counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

/**
 * This is our 'presistedstate state' store :)
 * - paths: a list of 'store(s)' that we wish to be persisted.
 * @type {any[]}
 */
export const plugins = [
  createPersistedState({
    key: 'my-key',
    paths: ['listings', 'search']
  })
]
  • search.js
export const state = () => ({
  list: [],
  current: {}
})

export const mutations = {
  set(state, listings) {
    state.list = listings
  },
  add(state, item) {
    state.list.push(item)
  },
  remove(state, { item }) {
    state.list.splice(state.list.indexOf(item), 1)
  },
  setCurrent(state, item) {
    state.current = item
  },
  updateCurrent(state, item) {
    state.current = { ...state.current, ...item }
  }
}
  • usage
this.$store.commit('search/add', { id: 22, price: 110 })
// or
store.commit('search/add', { id: 22, price: 110 })

now I can use the following 'store(s)' (search, listings) as persistedstate storage :)

All 10 comments

I have the same problem. It seems that the nuxt tips is not correct.

I fixed the problem by creating an index.js in the store folder and added the following code to set up the veux-persiststate.

import VuexPersist from 'vuex-persistedstate';

const vuexSession = new VuexPersist({
  storage: window.sessionStorage
});

export const plugins = [vuexSession];

I am also facing the same issue as @damcclean is facing, i have written same code and facing same issue.

Just chiming in that I'm also having the same problem. Refresh loses all state values. Not working with nuxt 2.6.3.

I was having the same issues at first, it took me couple of hours to get it right :)

my folders structure

- store
-- index.js
-- listings.js
-- search.js
  • index.js
import createPersistedState from 'vuex-persistedstate'

export const state = () => ({
 counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

/**
 * This is our 'presistedstate state' store :)
 * - paths: a list of 'store(s)' that we wish to be persisted.
 * @type {any[]}
 */
export const plugins = [
  createPersistedState({
    key: 'my-key',
    paths: ['listings', 'search']
  })
]
  • search.js
export const state = () => ({
  list: [],
  current: {}
})

export const mutations = {
  set(state, listings) {
    state.list = listings
  },
  add(state, item) {
    state.list.push(item)
  },
  remove(state, { item }) {
    state.list.splice(state.list.indexOf(item), 1)
  },
  setCurrent(state, item) {
    state.current = item
  },
  updateCurrent(state, item) {
    state.current = { ...state.current, ...item }
  }
}
  • usage
this.$store.commit('search/add', { id: 22, price: 110 })
// or
store.commit('search/add', { id: 22, price: 110 })

now I can use the following 'store(s)' (search, listings) as persistedstate storage :)

UPDATE

If you wish to add 'actions' (when using fetch/asyncData), the following will help you.

  • add this block of code to your relevant 'store' (in my 'listings.js' store)
export const actions = {
  async GET_LISTING({ commit }, id) {
    await this.$axios
      .get('/listings/' + id, {
        baseURL: `https://${APISERVERS[Math.floor(Math.random() * APISERVERS.length)]}/api/v1`,
        headers: headers
      })
      .then(res => {
        console.info('GET_LISTING INFO', id, res.data)
        if (res.status === 200) {
          commit('addOne', res.data)
          commit('setListing', res.data)
        }
      })
      .catch(function(error) {
        console.log('GET_LISTING - ERROR', error)
      })
      .finally(function() {
        console.info('GET_LISTING', 'DONE')
      })
  },
  async show({ commit }, params) {
    await this.$axios.get(`cars/${params.car_id}`).then(res => {
      if (res.status === 200) {
        commit('setCar', res.data)
      }
    })
  },
  async set({ commit }, car) {
    await commit('set', car)
  }
}
  • usage
async fetch({ app, store, params }) {
      await store.dispatch('listings/GET_LISTING', params)
 }
  • usage
 // mutations
 this.$store.commit('search/add', { id: 22, price: 110 })
 // actions
 this.$store.dispatch('listings/doAction', 11)

I was having the same issues at first, it took me couple of hours to get it right :)

my folders structure

- store
-- index.js
-- listings.js
-- search.js
  • index.js
import createPersistedState from 'vuex-persistedstate'

export const state = () => ({
 counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

/**
 * This is our 'presistedstate state' store :)
 * - paths: a list of 'store(s)' that we wish to be persisted.
 * @type {any[]}
 */
export const plugins = [
  createPersistedState({
    key: 'my-key',
    paths: ['listings', 'search']
  })
]
  • search.js
export const state = () => ({
  list: [],
  current: {}
})

export const mutations = {
  set(state, listings) {
    state.list = listings
  },
  add(state, item) {
    state.list.push(item)
  },
  remove(state, { item }) {
    state.list.splice(state.list.indexOf(item), 1)
  },
  setCurrent(state, item) {
    state.current = item
  },
  updateCurrent(state, item) {
    state.current = { ...state.current, ...item }
  }
}
  • usage
this.$store.commit('search/add', { id: 22, price: 110 })
// or
store.commit('search/add', { id: 22, price: 110 })

now I can use the following 'store(s)' (search, listings) as persistedstate storage :)

I got

window is not defined

error.

var e,t=(e=require("deepmerge"))&&"object"==typeof e&&"default"in e?e.default:e,r=require("shvl");module.exports=function(e,n,u){function o(e,t,r){try{return(r=t.getItem(e))&&void 0!==r?JSON.parse(r):void 0}catch(e){}}if(n=(e=e||{}).storage||window&&window.localStorage,u=e.key||"vuex",!function(e){try{return e.setItem("@@",1),e.removeItem("@@"),!0}catch(e){}return!1}(n))throw new Error("Invalid storage instance given");return function(i){var c=r.get(e,"getState",o)(u,n);"object"==typeof c&&null!==c&&i.replaceState(t(i.state,c,{arrayMerge:e.arrayMerger||function(e,t){return t},clone:!1})),(e.subscriber||function(e){return function(t){return e.subscribe(t)}})(i)(function(t,o){(e.filter||function(){return!0})(t)&&(e.setState||function(e,t,r){return r.setItem(e,JSON.stringify(t))})(u,(e.reducer||function(e,t){return 0===t.length?e:t.reduce(function(t,n){return r.set(t,n,r.get(e,n))},{})})(o,e.paths||[]),n)})}};
//# sourceMappingURL=vuex-persistedstate.js.map

I am using Vuex in module mode. Nuxt.js is v2.9.
There is no need to write anything in nuxt.config.ts.

Vuex folder structure

- store
-- store.ts
-- modules
--- test.ts

store.ts

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

const vuexSession = createPersistedState({
  key: 'vuex'
})

export interface State {}

export default new Vuex.Store<State>({
  plugins: [vuexSession]
})

This works fine.

I was having the same issues at first, it took me couple of hours to get it right :)

my folders structure

- store
-- index.js
-- listings.js
-- search.js
  • index.js
import createPersistedState from 'vuex-persistedstate'

export const state = () => ({
 counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

/**
 * This is our 'presistedstate state' store :)
 * - paths: a list of 'store(s)' that we wish to be persisted.
 * @type {any[]}
 */
export const plugins = [
  createPersistedState({
    key: 'my-key',
    paths: ['listings', 'search']
  })
]
  • search.js
export const state = () => ({
  list: [],
  current: {}
})

export const mutations = {
  set(state, listings) {
    state.list = listings
  },
  add(state, item) {
    state.list.push(item)
  },
  remove(state, { item }) {
    state.list.splice(state.list.indexOf(item), 1)
  },
  setCurrent(state, item) {
    state.current = item
  },
  updateCurrent(state, item) {
    state.current = { ...state.current, ...item }
  }
}
  • usage
this.$store.commit('search/add', { id: 22, price: 110 })
// or
store.commit('search/add', { id: 22, price: 110 })

now I can use the following 'store(s)' (search, listings) as persistedstate storage :)

I got

window is not defined

error.

var e,t=(e=require("deepmerge"))&&"object"==typeof e&&"default"in e?e.default:e,r=require("shvl");module.exports=function(e,n,u){function o(e,t,r){try{return(r=t.getItem(e))&&void 0!==r?JSON.parse(r):void 0}catch(e){}}if(n=(e=e||{}).storage||window&&window.localStorage,u=e.key||"vuex",!function(e){try{return e.setItem("@@",1),e.removeItem("@@"),!0}catch(e){}return!1}(n))throw new Error("Invalid storage instance given");return function(i){var c=r.get(e,"getState",o)(u,n);"object"==typeof c&&null!==c&&i.replaceState(t(i.state,c,{arrayMerge:e.arrayMerger||function(e,t){return t},clone:!1})),(e.subscriber||function(e){return function(t){return e.subscribe(t)}})(i)(function(t,o){(e.filter||function(){return!0})(t)&&(e.setState||function(e,t,r){return r.setItem(e,JSON.stringify(t))})(u,(e.reducer||function(e,t){return 0===t.length?e:t.reduce(function(t,n){return r.set(t,n,r.get(e,n))},{})})(o,e.paths||[]),n)})}};
//# sourceMappingURL=vuex-persistedstate.js.map

@akeyboardlife i'm facing the same problem. How'd you solved it?

Seems to be an issue with your application and not with this plugin. Please move the discussion Vue Forum or StackOverflow(https://stackoverflow.com/).

@anuardaher, @kaito3desuyo

In Nuxt, you should place the instantiation in /plugins, as stated in the readme. This is what I usually do:

// plugins/vuex-persistedstate.js
import createPersistedState from 'vuex-persistedstate'

const NAME_SPACE = 'xxxxx'

export default ({ store, isHMR }) => {
  if (isHMR) return
  if (process.browser) {
    createPersistedState({
      key: NAME_SPACE,
      paths: ['module-persisted1', 'module-persisted2'],
      // ...
    })(store)
  }
}

And then in the nuxt.config.js:

{
  // ...
  { src: '~/plugins/vuex-persistedstate.js', mode: 'client' },
}

Note, the new syntax for client-only plugins.

Note: Since Nuxt.js 2.4, mode has been introduced as option of plugins to specify plugin type, possible value are: client or server. ssr: false will be adapted to mode: 'client' and deprecated in next major release.

Source: https://nuxtjs.org/guide/plugins

in next major release.

Hopefully expected this year, as soon as Vue 3 comes out.

Was this page helpful?
0 / 5 - 0 ratings