New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(nuxt): skip router middleware/redirections for islands #24421
Conversation
Run & review this pull request in StackBlitz Codeflow. |
Codecov ReportAll modified and coverable lines are covered by tests β
Additional details and impacted files@@ Coverage Diff @@
## main #24421 +/- ##
=======================================
Coverage ? 58.65%
=======================================
Files ? 5
Lines ? 861
Branches ? 46
=======================================
Hits ? 505
Misses ? 356
Partials ? 0 β View full report in Codecov by Sentry. |
@@ -182,7 +182,7 @@ async function getIslandContext (event: H3Event): Promise<NuxtIslandContext> { | |||
const context = event.method === 'GET' ? getQuery(event) : await readBody(event) | |||
|
|||
const ctx: NuxtIslandContext = { | |||
url: '/', | |||
url: event.path, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is routeRules but rather vue router which is redirecting us, probably because we are still loading the router plugin for use within island.
I'm reluctant to use the event.path
as this will still have the same issue with any middleware/redirects that apply to the original path that is loading the component.
Instead, I think we should add some more logic to the router plugin to check we're not in an island context, e.g.:
if (import.meta.client || !nuxtApp.ssrContext?.islandContext) { |
Later we can perhaps opt-out entirely of routing (or, ideally, provide a 'stub' route rather than fully initialising vue-router). But we need to ensure that useRoute()
continues to work within server components so we keep user-land differences to a minimum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this would cause an issue if there's rules applied on /__nuxt_island/**
Is there a possibility to ignore everything for /__nuxt_island
? It implies removing probably both routeRules, nitro global middlewares and the router.
Currently working on server pages, we'll probably need to disable the router plugin and provide a stubbed route for useRoute
because it currently doesn't work within islands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, that makes sense if Vue Router is handling it. I've pushed up a fix for that.
It's not really clear in this PR but the event.path
will always be /__nuxt_island/**
, I've added a comment to make that clearer. I have a strong feeling that we should go with this path (assuming there isn't a good reason for using /
), it's arbitrary as the user should never interact with it but it does solve another issue and may avoid issues in the future.
For example, if we have a plugin that does something when the user visits the home page directly, it will always get triggered when an island renders, we can work around it using env: { islands: false }
, but this seems like an easy way to trip people up.
export default defineNuxtPlugin({
setup() {
const route = useRoute()
if (route.path === '/') {
// This will run every time an island component renders
}
}
})
It feels like we're plugging holes with the implementation so gives us more protection against other possible bugs.
@harlan-zw @danielroe what do you think about that ? This is something done on the server page branch. It would allow to be in the same route as the page for an island. |
Co-authored-by: Daniel Roe <daniel@roe.dev>
Co-authored-by: Daniel Roe <daniel@roe.dev>
I'm good with Daniel's changes, seems good to merge then. Will leave you to resolve them @huang-julien |
Co-authored-by: Daniel Roe <daniel@roe.dev>
Co-authored-by: julien huang <julien.huang@outlook.fr>
π Linked issue
nuxt-modules/og-image#98
β Type of change
π Description
When rendering a Nuxt Island, we provide the SSR context url as the root route
/
. Within the rendering pipeline, something is inheriting the route rules for/
and applying them. I'm guessing Nitro.The most obvious issue here is if you have a redirect on your home page, it's going to trigger a redirect on the island render.
You can see a minimal reproduction here: https://stackblitz.com/edit/nuxt-starter-gzuypu?file=pages%2Fabout.vue
While this could probably be dug into to figure out what's causing the redirect and doing an
if (!ssrContext.islandContext)
, I think it's safer for the long term not to re-use this root route.It's possible that we are using
/
for a reason, maybe to avoid some 404 issues? Would be good to have your input. The updated URL is arbitrary, ideally, we'd pass no route within the context and rework the engine to support that (or escape early with a specific island renderer).On that note but unrelated to this PR, I think there are some opportunities to refactor the island renderer to try and decouple it outside of the core logic.
π Checklist