Having trouble setting up my Vuex store from localStorage for authentication in Nuxt

I have been working with Nuxt.js and have been trying to create my own authentication system. Everything seems to be functioning correctly, but whenever I refresh the page, the state reverts back to its initial data. To address this issue, I attempted to initialize the Vuex store using localStorage in the following manner:

export const state = () => ({
    status: '',
    token: localStorage.getItem('token') || '',
    loggedInUser: localStorage.getItem('user') || '',
})

However, I encountered an error stating localStorage is not defined, even though localStorage.setItem works without any issues in the actions.

Below is the complete code snippet:

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)
                })
        })
    }
}

Answer №1

The error you're experiencing seems to be related to the initialization of Nuxt on the server side. It appears that the issue arises when Nuxt tries to access the localStorage, which is not available on the server.

To resolve this issue, one solution is to create a plugin with a .client suffix that fetches the values from localStorage during the client-side initialization process:

// Ensure to use the .client suffix to indicate that this code should only run on the 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 prefer not to implement this manually, you can consider using Vuex-persistedstate which automates this process and has been known to yield excellent results.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Compatibility of Vue-apexcharts with different versions

Which versions are compatible with vue-apexcharts on platforms such as "Windows", "Linux", "Mac", "Android", "iOS", and "Tablet"? ...

Moving the layout container towards the left: a quick guide

I am currently attempting to display the legend contents in a horizontal alignment within the layout container. The issue is that while the layout containing the legend aligns horizontally as desired, it extends beyond the screen border. I do not want the ...

Activate vertical scrolling in JavaScript when an image is clicked

I currently have a collection of button images with different hover effects specified like this: <img src="home.PNG" onmouseover="this.src='homemo.PNG'" onmouseout="this.src='home.PNG'" /> My goal is to make them scroll down to ...

Implementing a function to navigate to a different page using jQuery mobile

I'm attempting to pass a function when changing pages in jQuery Mobile, but I keep getting an error that points to `$.ajax` $( ":mobile-pagecontainer" ).pagecontainer( "change", "#schoolperformance", { reload : true, showLoadMsg : false, ...

Is it possible to dynamically load JavaScript?

I'm currently working on a project that requires me to dynamically add JavaScript. I have a global.js file that contains all the global variables I need to add dynamically. However, I'm facing an issue where global.js is not being added before ut ...

Angular 2 doesn't reflect changes in component variables in the view until mouseover happens

Since updating from angular2-alpha to the latest version, I've noticed that when a boolean value changes in my *ngIf directive, it doesn't reflect in the view until certain actions are taken. Here is the specific component code: declare var CKE ...

Blocked the loading of scripts due to non-compliance with the Content Security Policy directive

Encountering an error with externally loaded scripts: Refusing to load the script 'https://code.jquery.com/jquery-3.4.1.slim.min.js' due to violating the Content Security Policy directive: "script-src 'self' https://ajax.googlea ...

Encountered a challenge when loading resources with the Vite PWA plugin during development mode

In my simple vite app, I'm trying to implement the vite-pwa plugin to enable offline functionality. It works perfectly when I build the app (npm run build and then npm run preview), but not in dev mode. When running npm run dev, none of the resources ...

Using Vue 2 with Webpack works seamlessly for one application but encounters issues when used for another

I've been struggling with this problem for days now. I'm working on a project that consists of two single-page Vue applications or a two-page application as some might call it. These apps have common functionalities which have been extracted into ...

Is there a way to adjust the width of a table cell in Material UI using React?

I encountered a problem where I am attempting to adjust the width of a table cell, specifically in Typescript. However, I am only able to choose between medium and small sizes for TableCellProps. Is there a workaround for this issue? I am looking to expand ...

Receiving : npm WARNING using --force Suggested protections are now inactive

I'm facing an issue with my old Nuxt.js package that was initially developed for Node 12, and now I need to use it with Node 16 (the latest stable version). However, while trying to install the packages using npm install, I'm encountering errors ...

The OrbitControls function is not able to be instantiated as a constructor

I've been working on creating a WebVR environment for the past week using Three.js, but I'm having trouble getting the VR controls to function correctly. Here are some of the things I've tried: 1. Adding packages in my node_modules and imp ...

Angular: utilizing a ng-false-value function

Within my Angular application, I have a series of checkboxes generated using a nested ng-repeat: <div ng-repeat="partner in type.partners"> <label class="checkbox-inline"> <input type="checkbox" ng-model="partners[$paren ...

Obtaining a 16-bit integer from the response of an LWIP server

On the server side, I have implemented a loop that takes a 16-bit integer ranging from 0 to 639 and splits it into two 8-bit characters to populate a buffer of 1280 Bytes. The buffer is then sent via TCP-IP to the client. .c unsigned int data2[1000]; ch ...

Transmitted only JSON data instead of using multiform data with jQuery Ajax

When I use jQuery Ajax to send a JSON object, it ends up being interpreted as 'multiform' instead of pure JSON. How can I make sure my request is sent as a pure JSON object and not multiform? var demo = new Array("One", "Two", "Three"); $.ajax ...

Conceal object after a brief pause

Why does the element hide immediately instead of slowly fading out? I can't figure out why it doesn't first display the "P" tag and then gradually hide it. Please help me solve this issue. var step = 0.1; var delay = 90000; var displayMe = fun ...

AngularJS - how to dynamically delete a directive from an element

Looking for a way to dynamically add or remove directives from compiled and linked elements? I have a page with numerous inputs and want to disable all of them if a specific flag is set. The conventional method using jQuery's element.prop('disabl ...

Axios could potentially neglect default headers in certain cases

In my nuxt project, I am utilizing axios for making requests. However, I have encountered an issue where the default headers are being ignored specifically on node.js. When I run the following code snippet on node.js: import axios from "axios"; ...

Retrieve information by clicking on a hyperlink in JavaScript

Is it possible to extract content from a website that uses "onClick" instead of "href" in hyperlinks, resulting in the same URL regardless of the page being viewed? The specific content I'm attempting to retrieve is located under "Alimentação" > ...

Listener for 'timeupdate' event on video doesn't retain values

My html5 video event listener is designed to pause the video at a specific time while the user participates in a quiz. The first 'lesson' works fine, and the second video also appears to add the listener with the correct pause time. However, when ...