Dealing with a similar issue, I recommend utilizing cookies instead of localStorage for a smoother experience.
Nuxt, an SSR wrapper, prioritizes fetching data from the server before resorting to the client side. As others have pointed out, middleware
will first check the server implementation if it's the initial page load (including manual refresh or non-Nuxt/Vue router anchor links). Since LocalStorage is exclusive to the browser, any access attempts must be client-side. By storing token data as a cookie, Nuxt can easily access it through HTTP requests that include cookies on every page request.
To facilitate a cookie-based solution, leverage Nuxt's store
using the actions
hook nuxtServerInit
(https://nuxtjs.org/guide/vuex-store#the-nuxtserverinit-action). This enables setting server-side states like the access token, automatically synchronized with the client-side store.
A convenient option is employing the universal-cookies
package or creating a custom method to handle server-received or client-stored cookies conditionally.
store/index.js
import Cookies from 'universal-cookies'
export const state = () => ({
token: null
})
export const actions = {
nuxtServerInit ({ commit }, { req }) {
const cookies = new Cookies(req.headers.cookie)
const token = cookies.get('token')
commit('SET_TOKEN', token);
}
}
export const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
}
}
export const getters = {
token: state => state.token
}
Your middleware can now access the token state from the store whether it originates from the server or client thanks to the provided Nuxt context
object in all middleware methods. Don't forget about the universal redirect
method available within context
.
middleware/auth.js
export default function ({ store, redirect }) {
if (!store.getters['token']) {
redirect('/login')
}
}
While this doesn't directly address localStorage compatibility, leveraging cookies aligns well with Nuxt's server-side focus and simplifies handling authorization/authentication requests.