How to Persist and Rehydrate Vuex State Between Page Reloads in Nuxt.js

Alex Kasongo
JavaScript in Plain English
4 min readFeb 18, 2021

--

In a new project, I’ve been working on a user profile page. I want to persist the form data from the Vuex Store even after a user reloads the page, and also want to clear it out at will or on logout. I want the user to be able to fill in their profile details, reload the page, and return to find each form field still populated with their filled-in data.

Vuex-persistedstate is an npm-package that lets us store our Vuex state into localStorage or cookies.

Completed project 🌱

Repo 🌱

Installation

  1. Add Vuex-persistedstate to your project.
yarn add or npm install vuex-persistedstate

2. Create a new plugin instance in a separate file. You can call it whatever you want, I’ve called it persistedState.client.jsNaming your plugin ‘xxx.client.js’ will make it execute only on the client-side.

3. Add the plugin to nuxt.config.js

// nuxt.config.js

...
/*
* Naming your plugin 'xxx.client.js' will make it execute only on the client-side.
* https://nuxtjs.org/guide/plugins/#name-conventional-plugin
*/
plugins: [{ src: '~/plugins/persistedState.client.js' }]
...

4. Create a simple form in index.vueit could be anywhere. I’m using Beufy, it’s a Lightweight UI components library for Vue.js/Nuxt.js based on Bulma. I absolutely love it 🌱.

<template>
<div class="p-5 columns">
<div class="column">
<section>
<b-field label="Name">
<b-input v-model="userName" type="text"></b-input>
</b-field>

<b-field label="Email">
<b-input v-model="userEmail" type="email" maxlength="30"> </b-input>
</b-field>

<b-field label="Message">
<b-input v-model="message" maxlength="200" type="textarea"></b-input>
</b-field>

<b-field label="Subject" class="mb-5">
<b-select v-model="selected" placeholder="Select a subject" expanded>
<option value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
</b-select>
</b-field>
</section>
</div>
<div class="column">
<section>
<b-field>
<b-switch @click.native="switchPersistance" v-model="isSwitch"
>Start Persistance</b-switch
>
</b-field>
</section>
</div>
</div>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
name: 'HomePage',

data: () => ({
isSwitch: false,
userName: '',
userEmail: '',
message: '',
selected: '',
}),
computed: {
...mapState({
persistedState: 'persistedState',
}),
},
methods: {
// persist to vuex store
...mapActions({
switchPersistanceState: 'switchPersistanceState',
}),

switchPersistance() {
// when the switch is turned on do this.
if (this.isSwitch === false) {
const userInfo = {
userName: this.userName,
userEmail: this.userEmail,
message: this.message,
selected: this.selected,
}

this.switchPersistanceState(userInfo)
}

// When the swith is turned off, do this.
if (this.isSwitch === true) {
this.userName = ''
this.userEmail = ''
this.message = ''
this.selected = ''

this.switchPersistanceState(null)
}
},
},
// Do this when the page reloads
mounted() {
// check if persisted state exists
if (this.persistedState !== null) {
this.isSwitch = true
this.userName = this.persistedState.userName
this.userEmail = this.persistedState.userEmail
this.message = this.persistedState.message
this.selected = this.persistedState.selected
} else {
this.isSwitch = false
}
},
}
</script>

You should see something like this:

5. Create a vuex store file called index.js

export const state = () => ({
persistedState: null,
alert: false,
})

export const getters = {}

export const actions = {
switchPersistanceState({ commit }, payload) {
commit('SET_STATE', payload)
commit('SET_ALERT', true)
},
}

export const mutations = {
SET_STATE(state, payload) {
state.persistedState = payload
},
SET_ALERT(state, payload) {
state.alert = payload
},
}

6. Now we can finally persist our data to localStorage using vuex-persistedstate.

import createPersistedState from 'vuex-persistedstate'

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

7. View the persisted data in action. Open devtools. I’m using Google Chrome. Head over to Application and click on Local Storage.

Conclusion

That’s it. Hopefully, this will help you create ‘universal’ applications that persist data between server-side and client-side rendering.

Aleko 🌱

--

--

Hi, my name is Alex. I’m a front-end engineer, passionate for the web, responsive design, & typography.