Expired JWT token causes redirect without error event in Nuxt Auth
0 reputation · 02 Jul 2025, 11:11 UTC
0 reputation · 02 Jul 2025, 11:11 UTC
When using the Nuxt Auth module to protect routes, an expired JWT access token causes the router to redirect the user to the login page.
The module’s documentation does not state whether this expiry also triggers a global error handler or emits an event that can be captured by analytics or error‑tracking tools.
Developers need to know if token‑expiry can be observed through the application’s error handling mechanism or if they must implement a custom guard to surface the event.
Is there any built‑in error or event emitted when the auth middleware detects an expired token? Can a global error handler receive a 401 or similar response from an API call after token expiry? Does configuring a refresh‑token endpoint and calling $auth.refresh() automatically prevent the redirect, or must the refresh be invoked manually before each request?
34775 reputation · 02 Jul 2025, 17:03 UTC
Nuxt Auth does not emit an error or a global event when it detects an expired JWT access token. The module treats expiry as an expected state change and silently redirects to the route defined in redirect.login. Consequently, a global error handler will not receive a 401 from this redirect unless you make an actual API request after the redirect has already occurred.
onAuthError callback fires only for errors returned from the auth endpoint (e.g., 401/403) or when a token‑refresh attempt fails; it is not triggered by the mere reading of an expired token.refreshDelay (or token.refreshDelay in v5), the module will attempt to refresh the token before it expires. A successful refresh prevents the redirect; a failed refresh then invokes onAuthError.$auth.refresh() manually is only needed when you want to trigger a refresh on demand; the automatic refresh handled by refreshDelay runs without manual invocation.@nuxtjs/auth-next you are using (v4 vs v5) because option names differ.// nuxt.config.js (v4 example)
export default {
auth: {
strategies: { /* … */ },
refreshDelay: 5000 // attempt refresh 5 s before expiry
}
}
onAuthError will fire; you can handle it globally:
// plugins/auth.js
export default ({ $auth, error }) => {
$auth.onAuthError((err) => {
// send to analytics, log, etc.
console.warn('Auth error:', err);
});
}
// router.js
export default function ({ store, redirect }) {
return (to, from, next) => {
if (store.state.auth.loggedIn === false && to.path !== '/login') {
// token likely expired; emit custom event or log
window.dispatchEvent(new CustomEvent('auth-expired'));
return redirect('/login');
}
next();
};
}
Which version of @nuxtjs/auth-next are you installed with? The answer changes the exact option names (refreshDelay vs token.refreshDelay) and the way you access the auth instance.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 02 Jul 2025, 15:06 UTC
When the auth middleware sees an expired access token it calls navigateTo(redirect.login) directly. This navigation is a normal route change, so Nuxt’s global error handler (app.use((error) => …)) never receives it and no $auth.onAuthError callback is fired.
To observe the expiry you can listen to router navigation and check the auth state:
// plugins/auth‑expiry.js
export default ({ $auth, router }) => {
router.afterEach((to, from) => {
if (to.path === redirect.login && !$auth.loggedIn) {
// token expired – send to analytics, etc.
console.info('JWT expired, redirected to login');
}
});
};
If you enable refreshDelay (or token.refreshDelay in v5) the module will attempt a silent refresh before the token expires; a successful refresh avoids the redirect, while a failed refresh then triggers $auth.onAuthError.