Reputation:
I'm using Nuxt.js and I'm trying to make my own authentication. It works fine but when I refresh the page the state is go back to initial data so I tried to initialise Vuex store from localStorage like this:
export const state = () => ({
status: '',
token: localStorage.getItem('token') || '',
loggedInUser: localStorage.getItem('user') || '',
})
but it give me this error localStorage is not defined
but localStorage.setItem
works fine in actions
This is the full code:
import axios from 'axios'
export const state = () => ({
status: '',
token: localStorage.getItem('token') || '',
loggedInUser: localStorage.getItem('user') || '',
})
export const getters = {
status (state) {
return state.status
},
authenticated (state) {
return !!state.token
},
token (state) {
return state.token
},
loggedInUser (state) {
return state.loggedInUser
},
}
export const mutations = {
auth_request(state) {
state.status = 'loading'
},
auth_success(state, token) {
state.status = 'success'
state.token = token
},
auth_error(state) {
state.status = 'error'
},
logout(state) {
state.status = ''
state.token = ''
state.loggedInUser = {}
},
auth_success2 (state, loggedInUser) {
state.loggedInUser = Object.assign({}, loggedInUser)
}
}
export const actions = {
login({commit}, data) {
return new Promise((resolve, reject) => {
commit('auth_request')
axios.post('http://127.0.0.1:8000/api/login', data)
.then((res) => {
const loggedInUser = Object.assign({}, res.data.data)
const token = res.data.meta.token
localStorage.setItem('token', token)
localStorage.setItem('user', loggedInUser.name)
axios.defaults.headers.common['Authorization'] = 'Bearer '+ token
commit('auth_success', token)
commit('auth_success2', loggedInUser)
this.$router.push('/')
resolve(res)
})
.catch((error) => {
commit('auth_error')
console.log(error)
reject(error)
})
})
}
}
Upvotes: 0
Views: 2234
Reputation: 4639
You didn't include where this error is being thrown, but I'm going to assume it's in your server logs.
What's happening is Nuxt is initializing itself server side, begins to set up the store, and hits the localStorage declaration. The server does not have localstorage, so this will fail.
To get around this, I'd suggest using a plugin, with the .client suffix, and fetch the values from localStorage during the client side initialization:
// the .client suffix is required here to tell nuxt to only run this client side.
// ~/plugins/vuex-init.client.js
export default ({ store }) => {
const token = localStorage.getItem('token') || ''
const loggedInUser = localStorage.getItem('user') || ''
store.commit('setToken', token)
store.commit('setUser', user)
}
If you don't want to do the work yourself, I've used this before and have had great results with it.
Upvotes: 2