3D illustration of a login screen in a browser window with a user avatar, password fields and a padlock, on a pink background

Nuxt Auth - Refresh Token Authentication in Your Nuxt App

blog post publisher

Victor Motogna

Head of Web Development

Reading time: 5 min

Updated: Jul 2, 2026

Key takeaways

  • Nuxt auth centralises authentication so you can read the token, user, and login state through a single $auth object instead of wiring up axios calls yourself.
  • The nuxt-auth (auth-next) module covered here targets Nuxt 2; for a new Nuxt 3 or Nuxt 4 app, use current modules like sidebase nuxt-auth or nuxt-auth-utils.
  • Only auth-next v5 supports the refresh token strategy, so choose that version if you need token refresh.
  • A full flow covers setup, auth middleware (per route or global), login, logout, fetching the user, and refreshing the token.
  • For custom needs, you can define a custom refresh scheme and intercept all 401 responses in the axios plugin to trigger a token refresh.

User authentication is something we handle on almost every Nuxt project. This feature is widely used, especially in JavaScript, where implementation approaches vary a lot. The good news is that the Nuxt ecosystem offers dedicated auth modules with solid documentation.

A quick note before we start. This guide covers the nuxt-auth module, also known as auth-next. It was built for Nuxt 2 and the Options API. Nuxt has since moved on. Nuxt 4 is now the current stable release, and Nuxt 3 is in maintenance mode. For a new Nuxt 3 or Nuxt 4 app, the community now recommends newer modules such as sidebase nuxt-auth or the Nuxt team's nuxt-auth-utils. This article still explains the core ideas of token refresh authentication, which apply across modules. But check the official Nuxt modules directory before you start a fresh project.

With that said, nuxt-auth is the module we cover here. It lets you configure a flow that fits your needs. You can use one of the supported providers or strategies, or create a custom scheme of your own.

This article covers a complete setup for a Nuxt app that handles a token refresh scheme.

At the time of writing, the auth module had two major versions to choose from. Their statuses can be checked here. The v5 option came with more documentation, features, and fixes, though its API could still change. The v4 option did not support the refresh strategy, as the Nuxt contributors confirmed here. So let's get started.

Setup

First, we add auth-next and axios as dependencies.

Terminal commands running yarn add for the nuxtjs auth-next and axios packages

Then we add them to the modules in nuxt.config.js.

nuxt.config.js code adding the axios and auth modules to the modules array

Make sure you use auth-next v5, since it has more features, including the refresh token strategy. Also make sure the Vuex store is active.

The 'auth' middleware

The auth middleware can be enabled per route or globally. It's the default middleware, but you can also create custom ones.

Setting it per route:

Vue page component code setting the auth middleware for a single route

Setting it globally:

nuxt.config.js router code enabling the auth middleware globally for every route

Removing the middleware for specific components after setting it globally:

Vue component code disabling the auth middleware on a page after it was set globally

Setting custom middleware. For example, with multiple user types, you would add an option to the middleware:

Vue component code adding a custom middleware option to handle multiple user types

Other tweaks

There are many tweaks you can make. For example, you can set the default redirects for your auth middleware.

nuxt.config.js auth code defining default redirect routes for login, logout and home

Let's implement a login

First, we start with our Axios settings.

Axios configuration code setting the API base URL and default headers for the Nuxt app

Then we handle the login inside our component. For this example, we use a regular email and password login, but you can customize it.

Vue component code with a handleLogin method that calls this.$auth.loginWith local using email and password

You can see we used login with local inside our component. This is also set up in our nuxt.config.js file.

nuxt.config.js auth strategies code defining the local strategy with login, logout and user endpoints

Now, when you hit the button that calls handleLogin, you'll see the response from the login method of our API. In my case, that's localhost:3000/api/v1/login.

The case I considered returns a JSON like this.

JSON login response showing an access token and a refresh token returned by the API

That's why the user endpoint has false as a value. If we needed another call to fetch the user after login, we would set that up and use the autoFetch option.

For now, we only have the successful API call. But visiting any component that uses middleware: ['auth'] will redirect us back to login. To fix this, we set the token and the user in the store so that $auth treats our user as logged in.

Component code setting the auth token and user in the store after a successful login

Say we want to redirect to the user's profile page after login. Fetching the user right after login is a good idea, since it goes into the store and we can read it from there. So right after login, our page handles two things: refreshing the user data and logging out.

Logging out

Inside our nuxt.config.js, we already set logout: false in the endpoints object. Here you would add the URL if the backend also handles logout, but that's not required in our case.

After that, we can use logout. Inside our component, the button action is @click="handleLogout" with this logic.

Component code for a handleLogout method that calls this.$auth.logout to clear the session

This automatically removes the logged-in details from the store. After that, the middleware redirects the user to the chosen route when the state is not logged in.

Getting the user

By default, nuxt-auth has a user option that stores the user details right after login. It can fetch them right after a successful login, or, in our case, get them from the login API response.

The way we configured this, our user comes from user: { url: '/api/v1/profile', method: 'get' }. The property value is false because, for that call, the details sit at the root of the object.

On the profile page, we can read the user like this.

Profile page component code reading the logged-in user from this.$auth.user

This way, even when the page refreshes, the user stays stored and we don't get logged out.

Refreshing the token

Nuxt-auth v5 added the refresh token strategy. It has a default refresh scheme. It requires us to add these to our nuxt.config.js.

nuxt.config.js refresh strategy code with the refresh scheme, token and refreshToken endpoint options

This setup has default logic built in. When you call this.$auth.refreshTokens(), it uses the data in $auth.refreshToken.get() and sends it to the defined endpoint. Without the scheme refresh and the refreshToken option in the strategy, we couldn't set these up. Having both also makes the next line make more sense: the first parameter is the access token, and the second is the refresh token, which we can only use now.

Single line of code calling setUserToken with the access token and the refresh token as arguments

But in our case, the refresh token API call needs a little more. Using the example above, the call is POST /api/v1/token with { refresh_token: 'refresh_token_from_$auth' }. Our API needs parameters like { grant_type: 'refresh_token', refresh_token: 'refresh_token' }. To fix this, we can use url: '/api/v1/token?grant_type=refresh_token' as the refresh endpoint URL.

Custom refresh logic

If you need more complex refresh token logic, you can create a custom scheme and refresh controller. It looks something like this.

JavaScript code for a custom auth refresh scheme and controller overriding the refreshTokens method

This way, whenever the refreshTokens method is called, your custom refresh logic runs.

The logic to intercept all 401 requests can live in the plugins/axios.js file, with something like this.

axios plugin code with a response interceptor that catches 401 errors and triggers a token refresh

Conclusion

The benefit of this approach is that your code looks much cleaner, with all the auth methods in one place. You can read the token, the user, or the state through $auth. You don't need to implement auth methods with $axios directly, which makes everything easier to separate and handle.

I hope this guide helped you learn more about nuxt-auth and how to use it. If you'd like to build with Nuxt, take a look at our Nuxt.js development and Vue.js development services, or see how our web development team works. Want to go deeper on Nuxt itself? Read Understanding Nuxt 3 - Part I, or check out the other web development topics on our blog.

Frequently asked questions

Not for new projects. The nuxt-auth / auth-next module covered in this guide was built for Nuxt 2. Nuxt 4 is now the current stable release and Nuxt 3 is in maintenance mode. For a new Nuxt 3 or Nuxt 4 app, the community recommends newer modules such as sidebase nuxt-auth or the Nuxt team's nuxt-auth-utils. The token refresh concepts here still apply across modules.
Refresh token authentication uses two tokens. A short-lived access token authorises API requests, and a longer-lived refresh token obtains a new access token when the old one expires. This keeps users signed in without asking them to log in again, while limiting how long any single access token stays valid.
Only auth-next v5 supports the refresh token strategy. The older v4 option does not include refresh support, which the Nuxt contributors confirmed. If you need token refresh with this module, use v5 and make sure the Vuex store is active.
Enable the refresh scheme and add the refreshToken option to your strategy in the Nuxt config. Then call this.$auth.refreshTokens(), which reads the stored refresh token and sends it to your refresh endpoint. If your API needs extra parameters, such as a grant type, you can pass them as query parameters on the refresh endpoint URL, or write a custom refresh scheme.
Victor Motogna

Written by

Victor Motogna

Head of Web Development

Victor Motogna is the Head of Web Development at Wolfpack Digital, leading the web development team and driving innovation in scalable, secure web applications. With a Bachelor's in Computer Science and a Master's in High Performance Computing & Big Data Analytics, he brings deep technical expertise and a forward-thinking approach to building enterprise-grade solutions.


As both a technical leader and hands-on contributor, Victor works across the full technology stack including Ruby on Rails, Vue.js, Nuxt.js, JavaScript, and Python, with extensive experience in DevOps frameworks and cloud infrastructure (Azure, AWS, Kubernetes). His role extends beyond traditional web development—he plays a key part in architecting AI-powered features, training machine learning models, and ensuring AI integration delivers genuine business value rather than following trends.


Victor's leadership philosophy centers on balancing technical excellence with practical delivery. He excels at translating complex technical concepts into clear business language, architecting solutions that strike the right balance between technical sophistication and MVP speed, and staying ahead of rapid technological change. His approach emphasizes building stable, secure end-to-end solutions while constantly seeking smarter, more efficient development processes.


A frequent speaker at technology conferences across Europe, Victor shares insights on modern web development practices, AI integration strategies, cloud architecture, and building high-performing development teams. His writing draws on real-world experience delivering 250+ digital products and reflects his commitment to using technology to create meaningful solutions that improve people's lives.


Through his blog contributions, Victor explores topics at the intersection of web development, AI, and entrepreneurship, focusing on practical implementation strategies, technology decision-making, and fostering knowledge exchange within development teams.


Areas of expertise: Web application architecture, Ruby on Rails development, Vue.js/Nuxt.js, AI integration, machine learning model training, DevOps and cloud infrastructure, team leadership, full-stack development, technical strategy, scalable systems design.

View profile