fix(nuxt): populate route.meta.layout from appLayout route rules#34342
fix(nuxt): populate route.meta.layout from appLayout route rules#34342M-YasirGhaffar wants to merge 1 commit intonuxt:mainfrom
route.meta.layout from appLayout route rules#34342Conversation
|
|
@nuxt/kit
@nuxt/nitro-server
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
WalkthroughThe pull request modifies the router setup to automatically populate π₯ Pre-merge checks | β 6β Passed checks (6 passed)
βοΈ Tip: You can configure your own custom pre-merge checks in the settings. β¨ Finishing touches
π§ͺ Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
π§Ή Nitpick comments (1)
packages/nuxt/src/pages/runtime/plugins/router.ts (1)
185-190: Logic looks correct; consider reusinggetRouteRulesresult to avoid a duplicate call.
getRouteRules({ path: to.path })is called here and again at line 204 with the same argument within the samebeforeEachguard. You could hoist the call and reuserouteRulesfor both the layout assignment and the middleware lookup.β»οΈ Suggested refactor
+ const routeRules = getRouteRules({ path: to.path }) if (to.meta.layout === undefined) { - const appLayout = getRouteRules({ path: to.path }).appLayout + const appLayout = routeRules.appLayout if (appLayout) { to.meta.layout = appLayout as Exclude<PageMeta['layout'], Ref | false> } } nuxtApp._processingMiddleware = true if (import.meta.client || !nuxtApp.ssrContext?.islandContext) { type MiddlewareDef = string | RouteMiddleware const middlewareEntries = new Set<MiddlewareDef>([...globalMiddleware, ...nuxtApp._middleware.global]) for (const component of to.matched) { const componentMiddleware = component.meta.middleware as MiddlewareDef | MiddlewareDef[] if (!componentMiddleware) { continue } for (const entry of toArray(componentMiddleware)) { middlewareEntries.add(entry) } } - const routeRules = getRouteRules({ path: to.path })π€ Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/nuxt/src/pages/runtime/plugins/router.ts` around lines 185 - 190, The code calls getRouteRules({ path: to.path }) twice inside the same beforeEach guard; hoist this call into a local const (e.g., routeRules = getRouteRules({ path: to.path })) and reuse routeRules for both the layout assignment (to.meta.layout) and the later middleware lookup, replacing the duplicate calls to getRouteRules to avoid redundant computation.
π€ Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/nuxt/src/pages/runtime/plugins/router.ts`:
- Around line 185-190: The code calls getRouteRules({ path: to.path }) twice
inside the same beforeEach guard; hoist this call into a local const (e.g.,
routeRules = getRouteRules({ path: to.path })) and reuse routeRules for both the
layout assignment (to.meta.layout) and the later middleware lookup, replacing
the duplicate calls to getRouteRules to avoid redundant computation.
| if (to.meta.layout === undefined) { | ||
| const appLayout = getRouteRules({ path: to.path }).appLayout | ||
| if (appLayout) { | ||
| to.meta.layout = appLayout as Exclude<PageMeta['layout'], Ref | false> |
There was a problem hiding this comment.
I have an open question in my mind as to whether this is correct, because appLayout is being applied by Nitro route rules, which do not necessarily match the vue-router route. You might have a route, for example, like a catch-all, where the layout applies to only some of the paths that that route represents. It might not be correct to set layout metadata on the route itself.
I would also want to see what happens if we transition from one page rendered by this route which does match an app layout rule to another page which doesn't match the app layout rule. Does the metadata change? We probably need to make sure that it does.
Or maybe we need to rethink this PR. What do you think?
There was a problem hiding this comment.
Oh I see, yeah with a catch-all route the layout would leak on the shared meta object and not clear when navigating to a path without an appLayout rule. A reset of to.meta.layout to undefined at the start of each navigation (when not readonly) should handle that.
But if mutating route meta isn't the right call here, what approach would you go with instead?
π Linked issue
resolves #34305
π Description
route.meta.layoutisundefinedwhen usingappLayoutin route rules, even though the layout renders correctly. The layout was only being resolved insideNuxtLayoutbut never written back toroute.meta.layout.This sets
to.meta.layoutfrom the route rule'sappLayoutin the routerbeforeEachguard, same spot and pattern used forappMiddleware. It only applies whento.meta.layout === undefinedso it won't overridedefinePageMetaorlayout: false.Also added a test to check
route.meta.layoutis actually set on the route-rules layout page.