@@ -109,28 +109,36 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
109109 return undefined ;
110110 }
111111
112- // If this is a nested outlet (has an explicit ID like "main"),
113- // we need to figure out what part of the path was already matched
114- if ( this . id !== 'routerOutlet' && this . ionRouterOutlet ) {
112+ // Check if this outlet has route children to analyze
113+ if ( this . ionRouterOutlet ) {
115114 const routeChildren = extractRouteChildren ( this . ionRouterOutlet . props . children ) ;
116115 const { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = analyzeRouteChildren ( routeChildren ) ;
117116
118- const result = computeParentPath ( {
119- currentPathname,
120- outletMountPath : this . outletMountPath ,
121- routeChildren,
122- hasRelativeRoutes,
123- hasIndexRoute,
124- hasWildcardRoute,
125- } ) ;
117+ // Root outlets have IDs like 'routerOutlet' or 'routerOutlet-2'
118+ // But even outlets with auto-generated IDs may need parent path computation
119+ // if they have relative routes (indicating they're nested outlets)
120+ const isRootOutlet = this . id . startsWith ( 'routerOutlet' ) ;
121+ const needsParentPath = ! isRootOutlet || hasRelativeRoutes || hasIndexRoute ;
122+
123+ if ( needsParentPath ) {
124+ const result = computeParentPath ( {
125+ currentPathname,
126+ outletMountPath : this . outletMountPath ,
127+ routeChildren,
128+ hasRelativeRoutes,
129+ hasIndexRoute,
130+ hasWildcardRoute,
131+ } ) ;
132+
133+ // Update the outlet mount path if it was set
134+ if ( result . outletMountPath && ! this . outletMountPath ) {
135+ this . outletMountPath = result . outletMountPath ;
136+ }
126137
127- // Update the outlet mount path if it was set
128- if ( result . outletMountPath && ! this . outletMountPath ) {
129- this . outletMountPath = result . outletMountPath ;
138+ return result . parentPath ;
130139 }
131-
132- return result . parentPath ;
133140 }
141+
134142 return this . outletMountPath ;
135143 }
136144
@@ -246,7 +254,9 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
246254 parentPath : string | undefined ,
247255 leavingViewItem : ViewItem | undefined
248256 ) : boolean {
249- if ( this . id === 'routerOutlet' || parentPath !== undefined || ! this . ionRouterOutlet ) {
257+ // Root outlets have IDs like 'routerOutlet' or 'routerOutlet-2'
258+ const isRootOutlet = this . id . startsWith ( 'routerOutlet' ) ;
259+ if ( isRootOutlet || parentPath !== undefined || ! this . ionRouterOutlet ) {
250260 return false ;
251261 }
252262
@@ -283,7 +293,9 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
283293 enteringViewItem : ViewItem | undefined ,
284294 leavingViewItem : ViewItem | undefined
285295 ) : boolean {
286- if ( this . id === 'routerOutlet' || enteringRoute || enteringViewItem ) {
296+ // Root outlets have IDs like 'routerOutlet' or 'routerOutlet-2'
297+ const isRootOutlet = this . id . startsWith ( 'routerOutlet' ) ;
298+ if ( isRootOutlet || enteringRoute || enteringViewItem ) {
287299 return false ;
288300 }
289301
@@ -943,7 +955,8 @@ function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo, paren
943955 // SIMPLIFIED: Trust React Router 6's matching more, compute relative path when parent is known
944956 if ( ( hasRelativeRoutes || hasIndexRoute ) && parentPath ) {
945957 const parentPrefix = parentPath . replace ( '/*' , '' ) ;
946- const normalizedParent = stripTrailingSlash ( parentPrefix ) ;
958+ // Normalize both paths to start with '/' for consistent comparison
959+ const normalizedParent = stripTrailingSlash ( parentPrefix . startsWith ( '/' ) ? parentPrefix : `/${ parentPrefix } ` ) ;
947960 const normalizedPathname = stripTrailingSlash ( routeInfo . pathname ) ;
948961
949962 // Only compute relative path if pathname is within parent scope
@@ -959,12 +972,29 @@ function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo, paren
959972 for ( const child of sortedRoutes ) {
960973 const childPath = child . props . path as string | undefined ;
961974 const isAbsoluteRoute = childPath && childPath . startsWith ( '/' ) ;
975+
976+ // Determine which pathname to match against:
977+ // - For absolute routes: use the original full pathname
978+ // - For relative routes with a parent: use the computed relative pathname
979+ // - For relative routes at root level (no parent): use the original pathname
980+ // (matchPath will handle the relative-to-absolute normalization)
962981 const pathnameToMatch = isAbsoluteRoute ? originalPathname : relativePathnameToMatch ;
963982
964- // Only use derivePathnameToMatch for absolute routes or wildcard patterns;
965- // non-wildcard relative routes match directly against the computed relative pathname.
983+ // Determine the path portion to match:
984+ // - For absolute routes: use derivePathnameToMatch
985+ // - For relative routes at root level (no parent): use original pathname
986+ // directly since matchPath normalizes both path and pathname
987+ // - For relative routes with parent: use derivePathnameToMatch for wildcards,
988+ // or the computed relative pathname for non-wildcards
966989 let pathForMatch : string ;
967- if ( isAbsoluteRoute || ( childPath && childPath . includes ( '*' ) ) ) {
990+ if ( isAbsoluteRoute ) {
991+ pathForMatch = derivePathnameToMatch ( pathnameToMatch , childPath ) ;
992+ } else if ( ! parentPath && childPath ) {
993+ // Root-level relative route: use the full pathname and let matchPath
994+ // handle the normalization (it adds '/' to both path and pathname)
995+ pathForMatch = originalPathname ;
996+ } else if ( childPath && childPath . includes ( '*' ) ) {
997+ // Relative wildcard route with parent path: use derivePathnameToMatch
968998 pathForMatch = derivePathnameToMatch ( pathnameToMatch , childPath ) ;
969999 } else {
9701000 pathForMatch = pathnameToMatch ;
0 commit comments