N
Nuxt2mo ago
dankell.

Refreshing tokens on page navigation

I'm currently fighting with refreshing tokens on route navigation in a auth.global.ts RouteMiddleware. As far as I can tell the issue is that the login and refreshToken methods in my useAuth composable are async, but using async in defineNuxtRouteMiddleware causes the server to spit out errors such as Fetch handler error: Premature close I've solved the login issue by moving it to onMounted in app.vue but would like to make sure that tokens have not expired/are refreshed on page loads (I will also be refreshing the tokens on API calls)
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @dankell.. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Refreshing tokens on route navigation in Nuxt middleware can be tricky due to the synchronous context required by defineNuxtRouteMiddleware. According to the Nuxt documentation, composables (like your useAuth) that rely on Nuxt context must be called synchronously within middleware, plugins, or setup functions. Using await or asynchronous logic directly in middleware can lead to errors such as Fetch handler error: Premature close or issues with the Nuxt instance being unavailable Vue and Nuxt Composables Context. Key points from the docs: - You can use await in defineNuxtRouteMiddleware, but only if you do not break the synchronous context before calling composables. - If your token refresh logic is asynchronous, you must ensure all composables are called synchronously before any await. - If you need to perform async token refresh, consider handling it in a plugin, or in a component lifecycle hook like onMounted (as you did for login), rather than directly in middleware. Typical approaches: - Middleware: Use middleware for synchronous checks (e.g., presence of a token) and redirect if missing, but avoid async token refresh here. - Component Lifecycle: Perform async token refresh in onMounted in your root component (e.g., app.vue), which ensures the client always attempts to refresh tokens on navigation. - API Calls: Refresh tokens as needed in your API call logic (e.g., using useFetch or Axios interceptors), as this is a natural place to handle token expiry and refresh. Example from the sources: A common pattern is to check for the token synchronously in middleware and redirect if missing, but handle actual refresh logic elsewhere. For example, in middleware:
export default defineNuxtRouteMiddleware((to, from) => {
const token = useCookie('token').value
if (!token && to.path !== '/login') {
return navigateTo('/login')
}
})
export default defineNuxtRouteMiddleware((to, from) => {
const token = useCookie('token').value
if (!token && to.path !== '/login') {
return navigateTo('/login')
}
})
And then handle token refresh in onMounted or during API calls Redirect to auth screen if no token is available in defineNuxtRouteMiddlewareVue and Nuxt Composables Context. Summary:
- Use middleware for synchronous checks and redirects. - Handle async token refresh in onMounted or during API calls, not directly in middleware. - Ensure composables are called in the correct context to avoid Nuxt instance errors. If you need to refresh tokens on every navigation, the recommended approach is to trigger the refresh in onMounted in your root component, as you have done, or to handle it in your API logic. There is no official pattern in the knowledge sources for performing async token refresh directly in middleware without risking context errors. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@602890303753682944> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?