please validate the following configuration which I am trying to use with NuxtJS where SSR is enabled.
On browser refreshes, the values are not retained in the text boxes.
0) package.json
"dependencies": {
"js-cookie": "^2.2.0",
"nuxt": "^1.0.0",
"vue": "^2.5.16",
"vuex-persistedstate": "^2.5.1"
},
"devDependencies": {
"cross-env": "^5.0.1"
}
1) nuxt.config.js
plugins: [{ src: '~/plugins/localStorage.js', ssr: true }],
2) plugins/localStorage.js
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
export default ({store}) => {
createPersistedState({
key: 'vuex',
paths: [],
storage: {
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, { expires: 3, secure: true }),
removeItem: key => Cookies.remove(key)
}
})(store)
}
3) store/index.js
import Vuex from 'vuex';
const store = () => {
return new Vuex.Store({
state: {
count: 0,
firstName:'',
lastName:'',
email:'',
ssn:'',
phoneNumber:'',
addressLine1:'',
addressLine2:'',
city:'',
state1:'',
zip:''
},
getters: {
firstName(state) {
return state.firstName;
},
lastName(state) {
return state.lastName;
},
email(state) {
return state.email;
},
ssn(state) {
return state.ssn;
},
phoneNumber(state) {
return state.phoneNumber;
},
addressLine1(state) {
return state.addressLine1;
},
addressLine2(state) {
return state.addressLine2;
},
city(state) {
return state.city;
},
state1(state) {
return state.state1;
},
zip(state) {
return state.zip;
}
},
mutations: {
updateFirstName(state, firstName){
state.firstName = firstName ;
},
updateCount(state, increment) {
state.count += increment;
},
updateLastName(state, lastName){
state.lastName = lastName ;
},
updateEmail(state, email){
state.email = email ;
},
updateSSN(state,ssn) {
state.ssn = ssn;
},
updatePhoneNumber(state,phoneNumber) {
state.phoneNumber = phoneNumber;
},
updateAddressLine1(state,addressLine1) {
state.addressLine1 = addressLine1;
},
updateAddressLine2(state,addressLine2) {
state.addressLine2 = addressLine2;
},
updateCity(state,city) {
state.city = city;
},
updateState(state,state1) {
state.state1 = state1;
},
updateZip(state,zip) {
state.zip = zip;
}
}
})
}
export default store
4) pages/step1/index.vue
<template>
<div>
<form >
<div>
<label for="name">FirstName:</label>
<input type="text" :value="firstName" @input="updateFirstName" id="firstName">
</div>
<div>
<label for="mail">LastName:</label>
<input type="text" :value="lastName" @input="updateLastName" id="lastName">
</div>
<div>
<label for="msg">Email:</label>
<input type="email" :value="email" @input="updateEmail" id="email">
</div>
<div class="button">
<button type="submit">Save</button>
<router-link to="/step2" tag="button">Next</router-link>
</div>
</form>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
export default {
computed:
mapGetters([
'firstName',
'lastName',
'email'
]),
// firstName() {
// return this.$store.getters.firstName;
// },
// lastName() {
// return this.$store.getters.lastName;
// },
// email() {
// return this.$store.getters.email;
// }
methods: {
updateFirstName(e) {
this.$store.commit('updateFirstName', e.target.value);
},
updateLastName(e) {
this.$store.commit('updateLastName', e.target.value);
},
updateEmail(e) {
this.$store.commit('updateEmail', e.target.value);
}
}
}
</script>
I see that you are using the secure option when setting cookies. Do you run your code with HTTPS?
Thank You.. it worked.
Is there a way I could configure my vuex-persisted-state to use window.sessionStorage instead of cookie based local storage especially in a nuxtjs SSR enabled application...? Won't the window is undefined while the page is server rendered? Please shed some light on how to achieve session storage in a nuxtjs server side rendered application..
@pkganthali
// ~/plugins/vuex-persistedstate.js
import createPersistedState from 'vuex-persistedstate'
export default ({ store }) => {
createPersistedState({
// other options...
storage: sessionStorage,
})(store)
}
And in your nuxt.config.js file:
// nuxt.config.js
plugins: [
// other plugins...
{ src: '~/plugins/vuex-persistedstate.js', ssr: false },
]
The ssr: false part is the important one, as it is explained in the Readme.
Although that was not related with the original question. Can we close the issue now? Thank you.
@gangsthub
import createPersistedState from 'vuex-persistedstate'
export default ({store}) => {
createPersistedState({
key: 'vuex',
paths: [],
storage: {
getItem: key => sessionStorage.get(key),
setItem: (key, value) => sessionStorage.set(key, value),
removeItem: key => {
sessionStorage.remove(key);
}
}
})(store)
}
It is not working, I have given ssr : false. Its complaining Invalid storage instance given. I tried giving window.sessionStorage too
You'll receive that error when the plugin is unable to write to the provided storage instance, see https://github.com/robinvdvleuten/vuex-persistedstate/blob/master/index.js#L52. As it is unrelated to your initial question and not an issue, I am gonna close this.
import createPersistedState from 'vuex-persistedstate';
import * as Cookies from "js-cookie";
let cookieStorage = {
getItem: function(key) {
return Cookies.getJSON(key);
},
setItem: function(key, value) {
return Cookies.set(key, value, {expires: 3, secure: false});
},
removeItem: function(key) {
return Cookies.remove(key);
}
};
export default (context) => {
createPersistedState({
storage: cookieStorage,
getState: cookieStorage.getItem,
setState: cookieStorage.setItem
})(context.store);
};
plugins: [
{ src: '~/plugins/localStorage.js', ssr: false }
]
It works for me.
An another problem can be with the data size when you use cookies for that. There is a limit of 4096b. So when you're trying to set more data than cookie can get, the browser (at least Google Chrome in my case) will silently ignore your wish.
I faced such problem and I solved it by using state modules and saving each module state in separated cookie.
I used https://www.npmjs.com/package/cookie-universal-nuxt
Here is my code example:
import createPersistedState from 'vuex-persistedstate';
export default ({store, app}) => {
createPersistedState({
storage: {
getItem: (vuexKey) => {
const vuex = {};
const cookies = app.$cookies.getAll();
for (const subKey of Object.keys(cookies)) {
if (subKey.split('_')[0] === vuexKey) {
const modKey = subKey.replace(vuexKey + '_', '');
vuex[modKey] = cookies[subKey];
}
}
return vuex;
},
setItem: (vuexKey, value) => {
const json = JSON.parse(value);
for (const k of Object.keys(json)) {
const subKey = vuexKey + '_' + k;
app.$cookies.set(subKey, json[k], {path: '/', maxAge: 60 * 60 * 24 * 7, secure: false});
}
return true;
},
removeItem: (vuexKey) => {
const cookies = app.$cookies.getAll();
for (const subKey of Object.keys(cookies)) {
if (subKey.split('_')[0] === vuexKey) {
app.$cookies.remove(subKey);
}
}
return true;
}
}
})(store)
}
export const actions = {
async nuxtServerInit({commit}, { req }) {
const vuexKey = 'vuex';
try {
const cookies = this.$cookies.getAll();
if (!!cookies[vuexKey+'_auth']) commit('auth/setUserInfo', cookies[vuexKey+'_auth']);
if (!!cookies[vuexKey+'_module2']) commit('cart-items/setItems', cookies[vuexKey+'_module2'].items);
// another stuff ...
} catch (e) {
commit("something", []);
console.log("STATE ERROR: ", e)
}
}
};
It's a bit dirty code but I hope you've got an idea.
@adamasantares this saves me thanks
Most helpful comment
It works for me.