Middleware registered in plugins is never executed
Environment
nitropack v0.5.4, no extra config
Reproduction
Given the following plugin:
// plugins/test.ts
export default defineNitroPlugin(nitroApp => {
nitroApp.h3App.use('/', () => console.log('Middleware ran'))
console.log('Plugin registered')
})
The plugin appears to register correctly ('Plugin registered' is printed), but the middleware added with h3App.use is never executed ('Middleware ran' is never printed when navigating to any route).
Describe the bug
Any middleware added inside a nitro plugin with nitroApp.h3App.use or other related methods is never executed.
This might be an intentional / known limitation of how plugins work, but it feels unexpected, given that the method throws no error and is readily accessible.
Additional context
No response
Logs
No response
See https://github.com/unjs/nitro/pull/302 and https://github.com/nuxt/nuxt.js/issues/14177.
Those issues appear to be about adding new routes, not middleware. Unless there is some way to add middleware directly to the router that I'm unaware of, I don't really get why this issue was closed.
I spent all day to figure out how to add middleware via module and didn't find a solution. The problem is actual.
Hello, Does anyone have a way to add a middleware to nitro yet?
Have a great day.
EDIT: To be more precise, I need to resolve CORS issues and can't really do that efficiently right now so I am trying to use https://github.com/NozomuIkuta/h3-cors.
This worked for me
export default defineNitroPlugin(nitroApp => {
nitroApp.h3App.stack.unshift({
route: "/",
handler: () => {
console.log('middlware ran');
},
});
})
./server/plugins/code.ts
export default defineNitroPlugin(async nitroApp => {
const handler = await createWebhook();
nitroApp.h3App.stack.unshift({
route: '/',
handler: fromNodeMiddleware(handler),
});
});
This worked for me
export default defineNitroPlugin(nitroApp => { nitroApp.h3App.stack.unshift({ route: "/", handler: () => { console.log('middlware ran'); }, }); })
I suppose that works, but it reverses the intuitive order - middlewares that are registered first are now run after middlewares that are registered later.
Thank you for providing a way to solve this. I had been searching for a solution all day.
I need to catch a route like /@:username/ and bypass all not starting with @.
Does nitro provide something like event.next()? to continue the route matching?
I need to catch a route like /@:username/ and bypass all not starting with @.
Supporting paterns in same segment of routes will be coming with next major version of h3/radix3/nitro to allow this 🤞🏼
Generally please avoid modifying nitroApp.h3App.stack, it is unsafe and error-prune and usually the routing patterns could be designed better to avoid requiring workarounds like this. if you have any questions feel free to use Discussions 🙏🏼
Wait what is the resolution of the original issue? Is there now a supported way to add middleware in a plugin?
@FeldrinH No and you should not register middleware inside a runtime plugin (it is unstable and unpredictable). Middleware should be registered via server/middleware directory or handlers: [{ middleware: true, handler: 'path to handler' }] from configuration to register middleware.
There is a new way of using hooks (request, beforeResponse and afterResponse) which request runs before any other middleware.
export default defineNitroPlugin(nitroApp => {
nitroApp.hooks.hook('request', (event) => {})
nitroApp.hooks.hook('afterResponse', (event) => {})
})
Please use Discussions if you have a case that would not be solved with hooks either.
Fair enough