Yung Silva
Yung Silva

Reputation: 1510

Access LocalStorage in Middleware - NuxtJs

Well, I'm starting with nuxt and I have following routes:

/home

/dashboard

/login

I want to protect the /dashboard, but only for users logged in with a token in localStorage.

The simplest way I thought of doing this was by creating a /middleware/auth.js

export default function () {
  if (!window.localStorage.getItem('token')) {
    window.location = '/login'
  }
}

and registering it in the /dashboard/index.vue component.

<script>
export default {
  middleware: 'auth',
}
</script>

But I cannot access localStorage within a middleware, because LocalStorage is client-side.

I have already tried to add this same check in the created() dashboard layout, but I cannot return window not set mounted() is too late, it can only check after the page has been fully assembled.

So how can I achieve this? Note: I do not intend to use any Vuex for this project.

Upvotes: 7

Views: 23612

Answers (5)

RodrigoRoy
RodrigoRoy

Reputation: 21

I have the same problem in Nuxt3. According to the documentation When Middleware Runs, the middleware will be executed both server and client side. You need to skip the server part enterily and mantain only the client side verifications:

middleware/example.ts

export default defineNuxtRouteMiddleware((to, from) => {
  // skip middleware on server (first middleware execution)
  if (import.meta.server) return

  // now we are on the client side (second middleware execution)
  // we have access to localStorage
  if (import.meta.client)
    if(localStorage.getItem('token'))
      return
    else
      return navigateTo('/login')
})

I hope this helps, because it is a common problem with the default universal rendering used by Nuxt and the code example in the documentation is tricky and take me a while to figure it out.

Upvotes: 0

Neo Mn
Neo Mn

Reputation: 597

nuxt middleware runs two times , 1 time when your request goes to server and another time when the response of that request are rendered in your browser , so in the server side there is no localStorage, you shoudl try accessing local storage just in browser , right ?

export default defineNuxtRouteMiddleware(to => {

   if (process.server) {
       // this section will run on the server
   }

   if (process.client) {
      //this section will run in the browser so you can access 
      // local storage
   }


   const nuxtApp = useNuxtApp()
   if (process.client && nuxtApp.isHydrating && 
               nuxtApp.payload.serverRendered) {
      // this section will run only once , in the browser, when the page 
      // initialized
   }
})

Upvotes: 0

rrrm93
rrrm93

Reputation: 416

I used cookie-universal-nuxt

On vuex store for login action I set a commit with the token

window.$cookies.set('token', payload, {
    path: '/',
})

and access it in middleware as middleware/auth.js

export default (context) => {
    if (!context.app.$cookies.get('token')) {
        return context.redirect('/login')
    }
}

Upvotes: 6

Aldarund
Aldarund

Reputation: 17621

You can use this for Local Storage (and many other things) in Nuxt. It will work on client and server. There's no documentation, but README should be sufficient.

https://github.com/nuxt-community/universal-storage-module

Upvotes: 0

MR_BlueScr
MR_BlueScr

Reputation: 139

For anyone not satisfied storing the information in cookies, here's me solution:

I've been having a lot of problems with this and I were not satisfied setting a cookie. If you are running Nuxt and haven't told it to run in spa mode it will run in universal mode. Nuxt defines universal mode as:

Isomorphic application (server-side rendering + client-side navigation)

The result being that localStorage is not defined serverside and thus throws an error.

The give away for me was that console logging from middleware files and Vuex outputted to terminal and not the console in developer tools in the browser.

The solution for me was to change the mode to spa in the nuxt.config.js which is located at the root.

Please notice that you can still access localStorage, running universal mode, in page files and components because they are not server side.

Middleware files are, in universal mode, run server side, so changing to spa mode makes them run client side and thus allows them access to localStorage.

For more information about Nuxt modes, read these:

Upvotes: 6

Related Questions