diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index 29c3cf2af5..dd56a75ea2 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -3032,6 +3032,7 @@ interface RouteLike { children?: Array options?: { caseSensitive?: boolean + isVirtualLayout?: boolean } } @@ -3225,6 +3226,8 @@ export function getMatchedRoutes({ routeParams = getMatchedParams(foundRoute)! } else { foundRoute = flatRoutes.find((route) => { + if (route.options?.isVirtualLayout) return false + const matchedParams = getMatchedParams(route) if (matchedParams) { diff --git a/packages/router-generator/src/generator.ts b/packages/router-generator/src/generator.ts index 83fee9af4b..c4f8b0bbfc 100644 --- a/packages/router-generator/src/generator.ts +++ b/packages/router-generator/src/generator.ts @@ -525,6 +525,23 @@ export class Generator { (d) => d, ]) + // After all nodes have been processed we can safely (re)-evaluate + // whether a virtual `layout` route should be treated as a virtual-layout wrapper + sortedRouteNodes.forEach((node) => { + if ( + node.isVirtual && + node._fsRouteType === 'layout' && + node.children && + !node.children.some((c) => c.cleanedPath === '/') + ) { + node.isVirtualLayout = true + } else { + // If the conditions are not met, ensure the flag is falsy so we + // don't rely on an outdated value that may have been set earlier. + delete node.isVirtualLayout + } + }) + const pluginConfig = plugin.config({ generator: this, rootRouteNode, @@ -583,6 +600,7 @@ export class Generator { `id: '${node.path}'`, !node.isNonPath ? `path: '${node.cleanedPath}'` : undefined, `getParentRoute: () => ${findParent(node, exportName)}`, + node.isVirtualLayout ? `isVirtualLayout: true` : undefined, ] .filter(Boolean) .join(',')} diff --git a/packages/router-generator/src/types.ts b/packages/router-generator/src/types.ts index b64674066d..f89d0829fd 100644 --- a/packages/router-generator/src/types.ts +++ b/packages/router-generator/src/types.ts @@ -13,6 +13,7 @@ export type RouteNode = { children?: Array parent?: RouteNode exports?: Array + isVirtualLayout?: boolean } export interface GetRouteNodesResult {