Global middleware only runs once on client side ?

Hello there, Hope you all doing well. am trying to force a user on a password reset page based on their login token. the password reset flag is working fine. But my issues are : server side middleware redirect only works the first time the page is opened. then the user can navigate (though any usefetch will be returining 500 now ) i tried then to add a frontend middleware, but this is also only triggered once and never triggers when the user tries to navigate to other pages
export default defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore();
const {resetPassword} = storeToRefs(userStore);
if(resetPassword && !(to.fullPath == '/passResetPath' || to.fullPath == '/passResetPath/')){
navigateTo('/passResetPath',{ redirectCode: 301 })
}
});



export default defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore();
const {resetPassword} = storeToRefs(userStore);
if(resetPassword && !(to.fullPath == '/passResetPath' || to.fullPath == '/passResetPath/')){
navigateTo('/passResetPath',{ redirectCode: 301 })
}
});



8 Replies
kapa.ai
kapa.ai4w ago
Hi @Artist201. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources, I can address your question about global middleware in Nuxt 3. Global middleware in Nuxt 3 is designed to run on every route change, not just once on the client side. According to the Nuxt documentation on middleware (https://nuxt.com/docs/guide/directory-structure/middleware), global middleware (with a .global suffix) should run on every route change. However, the behavior you're experiencing suggests there might be an issue with how the middleware is being implemented or how the navigation is occurring. Here are a few points to consider: 1. Make sure your global middleware file has the .global suffix in its filename, for example, force-reset.global.ts. 2. The navigateTo function you're using is correct for middleware. As mentioned in the Nuxt documentation on middleware (https://nuxt.com/docs/guide/directory-structure/middleware#usage), navigateTo is one of the recommended helpers for redirects in middleware. 3. Your use of defineNuxtRouteMiddleware is correct. This is the proper way to define route middleware in Nuxt 3. 4. The issue might be related to how the store state is being updated or how the navigation is being triggered. To ensure that your middleware runs on every navigation, you could try using the addRouteMiddleware function in a plugin. This approach is described in the Nuxt documentation on addRouteMiddleware (https://nuxt.com/docs/api/utils/add-route-middleware#global-route-middleware). Here's an example:
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-test', () => {
const userStore = useUserStore();
const { resetPassword } = storeToRefs(userStore);
if (resetPassword.value && !(to.fullPath == '/passResetPath' || to.fullPath == '/passResetPath/')) {
return navigateTo('/passResetPath', { redirectCode: 301 });
}
}, { global: true })
})
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-test', () => {
const userStore = useUserStore();
const { resetPassword } = storeToRefs(userStore);
if (resetPassword.value && !(to.fullPath == '/passResetPath' || to.fullPath == '/passResetPath/')) {
return navigateTo('/passResetPath', { redirectCode: 301 });
}
}, { global: true })
})
This approach should ensure that the middleware runs on every route change. If you're still experiencing issues, it might be worth checking how the resetPassword value in your store is being updated and ensuring that it's reactive. Remember, if you're making changes to the store or other reactive state during navigation, you might need to use nextTick or similar to ensure the changes are reflected before the next navigation occurs. If these suggestions don't resolve your issue, you might be encountering a bug or edge case. In that situation, it would be advisable to create a minimal reproduction of the problem and seek further assistance from the Nuxt community or by filing an issue on the Nuxt GitHub repository. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@187250017914978305> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Artist201
Artist201OP4w ago
why do i have to use a plugin ?? why isn't the middleware working on every route change @kapa.ai how can i also pass a message to the frontend ? and how can the frontend recieve it ?
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To pass a message from the server-side middleware to the frontend in Nuxt 3, you can use the setResponseStatus utility along with a custom header or payload. Then, on the frontend, you can intercept this information using Nuxt hooks. Here's how you can achieve this: 1. In your server-side middleware:
export default defineEventHandler((event) => {
// Your middleware logic here
if (someCondition) {
setResponseStatus(event, 301, {
statusMessage: 'Password reset required'
})
// You can also set a custom header
setHeader(event, 'X-Password-Reset', 'true')
return sendRedirect(event, '/passResetPath')
}
})
export default defineEventHandler((event) => {
// Your middleware logic here
if (someCondition) {
setResponseStatus(event, 301, {
statusMessage: 'Password reset required'
})
// You can also set a custom header
setHeader(event, 'X-Password-Reset', 'true')
return sendRedirect(event, '/passResetPath')
}
})
2. On the frontend, you can use the useNuxtApp composable to add a hook that runs on every route change. You can place this in a plugin:
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('app:created', () => {
nuxtApp.hook('page:finish', () => {
const route = useRoute()
const message = route.meta.statusMessage
if (message) {
// Handle the message, e.g., show a notification
console.log('Status message:', message)
}

// Check for custom header
const passwordResetRequired = useRequestHeaders(['x-password-reset'])['x-password-reset']
if (passwordResetRequired === 'true') {
// Handle password reset requirement
console.log('Password reset required')
}
})
})
})
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('app:created', () => {
nuxtApp.hook('page:finish', () => {
const route = useRoute()
const message = route.meta.statusMessage
if (message) {
// Handle the message, e.g., show a notification
console.log('Status message:', message)
}

// Check for custom header
const passwordResetRequired = useRequestHeaders(['x-password-reset'])['x-password-reset']
if (passwordResetRequired === 'true') {
// Handle password reset requirement
console.log('Password reset required')
}
})
})
})
This approach is based on the information from the Nuxt documentation on hooks (https://nuxt.com/docs/api/advanced/hooks) and Nuxt documentation on server utilities (https://nuxt.com/docs/guide/going-further/hooks). By using setResponseStatus and custom headers, you can pass information from the server to the client. Then, by using Nuxt hooks, you can intercept and handle this information on the frontend. Remember to adjust the code to fit your specific use case and error handling needs. Also, be cautious about what information you pass in headers or status messages, as these can be visible to users. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@187250017914978305> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Artist201
Artist201OP4w ago
@kapa.ai there is nothing called route.meta.statusMessage
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct, and I apologize for the confusion in my previous response. Let me provide a more accurate answer based on the Nuxt 3 documentation. In Nuxt 3, there isn't a direct route.meta.statusMessage property as I incorrectly suggested. Instead, we need to use a different approach to handle error messages or status information passed from the server to the client. Here's a more accurate way to handle this in Nuxt 3: 1. On the server side, you can use createError to throw an error with a custom message:
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
data: {
myCustomField: 'Custom message'
}
})
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
data: {
myCustomField: 'Custom message'
}
})
This is based on the Nuxt documentation on createError (https://nuxt.com/docs/api/utils/create-error). 2. On the client side, you can use the useError composable to access this error information:
<script setup>
const error = useError()

if (error.value) {
console.log('Error status:', error.value.statusCode)
console.log('Error message:', error.value.statusMessage)
console.log('Custom data:', error.value.data)
}
</script>
<script setup>
const error = useError()

if (error.value) {
console.log('Error status:', error.value.statusCode)
console.log('Error message:', error.value.statusMessage)
console.log('Custom data:', error.value.data)
}
</script>
This approach is described in the Nuxt documentation on error handling (https://nuxt.com/docs/getting-started/error-handling). For handling custom headers, you can use the useRequestHeaders composable as mentioned in my previous response:
const headers = useRequestHeaders(['x-custom-header'])
console.log(headers['x-custom-header'])
const headers = useRequestHeaders(['x-custom-header'])
console.log(headers['x-custom-header'])
I apologize again for the confusion in my previous response. Thank you for pointing this out, as it allows me to provide more accurate information based on the current Nuxt 3 documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@187250017914978305> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server