The requested page still loads when making a redirection via route middleware
Environment
- Operating System:
Darwin - Node Version:
v16.15.1 - Nuxt Version:
3.0.0-rc.6 - Package Manager:
[email protected] - Builder:
vite - User Config:
ssr,components,meta,alias,buildModules,vue,css,modules,postcss,runtimeConfig,vite - Runtime Modules:
@nuxtjs/[email protected] - Build Modules:
@nuxtjs/[email protected],@pinia/[email protected]
Reproduction
https://codesandbox.io/s/zen-bohr-d8yhrj
Describe the bug
When a middleware which makes a redirection to an external URL executes, the requested page still loads after the middleware, which then triggers undesired behaviours as, for example, the middleware may have been guarding the page from loading if the required authentication to load the resources the page needs was not yet available to the app.
If this is somehow the expected behaviour, I would appreciate if somebody could guide me into how to stop the page from loading after an external redirect in a middleware.
Let me know if you need any further details.
Thanks for the help!
Additional context
In the repro, I'm using a helper function provided by @justin-schroeder which is a wrapper of H3's sendRedirect() , given that we still cannot redirect using Nuxt's navigateTo(), see #5022.
Use case: I'm trying to implement an OAuth 2.0 client middleware to get a token from my custom OAuth 2.0 server. Because of this issue, errors are triggered by the loaded page since the token has not yet being retrieved and the page attempts to load several protected resources. This and other current bugs/lack of features such as the aforementioned external redirection issue and Pinia not being able to be used inside server middleware (see https://github.com/vuejs/pinia/discussions/1212) make it quite painful to implement something so critical for corporate-sized apps such as a custom OAuth 2.0 flow.
Logs
No response
The best solution will be to resolve in linked PR.
But for now, a workaround would be:
await externalRedirect("http://www.google.com");
return abortNavigation()
You can ignore the resulting Route navigation aborted: /' error.
@danielroe the page still loads when using abortNavigation() as per your example. I've changed the repro to show this.
More info: the issue seems to be that the page still loads server-side when abortNavigation() is called. I changed once again the repro to show this: a simple route middleware which calls abortNavigation() server-side still loads the page server-side. This happens regardless of if I make a redirection or not.
@danielroe I don't see any workarounds for this, do you have anything in mind?
Same behaviour with same configuration. also internal redirection not preventing page from rendering on server side. Tried both async and normal types of middleware.
Indeed, even after a navigateTo inside a middleware, the guarded route is still called. To be more accurate, the setup function is called but not the onMounted method. This behaviour only occurs on server side.
Here is a reproduction: https://stackblitz.com/edit/github-ueekmy?file=pages%2Fabout.vue,middleware%2Fredirect.ts
In my case, this workaround works.
It seems to be fixed in rc.9. For internal redirection at least: https://stackblitz.com/edit/github-ueekmy-nfbnoq?file=package.json,middleware%2Fredirect.ts
Yes, resolved in https://github.com/nuxt/framework/pull/5145.