@@ -282,7 +282,7 @@ export class ReactRouterViewStack extends ViewStacks {
282282 if ( hasParams ) {
283283 if ( isWildcard ) {
284284 const existingPathnameBase = v . routeData ?. match ?. pathnameBase ;
285- const newMatch = matchComponent ( reactElement , routeInfo . pathname , false ) ;
285+ const newMatch = matchComponent ( reactElement , routeInfo . pathname , false , this . outletParentPaths . get ( outletId ) ) ;
286286 const newPathnameBase = newMatch ?. pathnameBase ;
287287 if ( existingPathnameBase !== newPathnameBase ) {
288288 return false ;
@@ -309,7 +309,7 @@ export class ReactRouterViewStack extends ViewStacks {
309309 existingViewItem . mount = true ;
310310 existingViewItem . ionPageElement = page || existingViewItem . ionPageElement ;
311311 const updatedMatch =
312- matchComponent ( reactElement , routeInfo . pathname , false ) ||
312+ matchComponent ( reactElement , routeInfo . pathname , false , this . outletParentPaths . get ( outletId ) ) ||
313313 existingViewItem . routeData ?. match ||
314314 createDefaultMatch ( routeInfo . pathname , reactElement . props ) ;
315315
@@ -337,7 +337,7 @@ export class ReactRouterViewStack extends ViewStacks {
337337 }
338338
339339 const initialMatch =
340- matchComponent ( reactElement , routeInfo . pathname , true ) ||
340+ matchComponent ( reactElement , routeInfo . pathname , true , this . outletParentPaths . get ( outletId ) ) ||
341341 createDefaultMatch ( routeInfo . pathname , reactElement . props ) ;
342342
343343 viewItem . routeData = {
@@ -360,7 +360,7 @@ export class ReactRouterViewStack extends ViewStacks {
360360 */
361361 private renderViewItem = ( viewItem : ViewItem , routeInfo : RouteInfo , parentPath ?: string , reRender ?: ( ) => void ) => {
362362 const routePath = viewItem . reactElement . props . path || '' ;
363- let match = matchComponent ( viewItem . reactElement , routeInfo . pathname ) ;
363+ let match = matchComponent ( viewItem . reactElement , routeInfo . pathname , false , parentPath ) ;
364364
365365 if ( ! match ) {
366366 const indexMatch = resolveIndexRouteMatch ( viewItem , routeInfo . pathname , parentPath ) ;
@@ -593,10 +593,18 @@ export class ReactRouterViewStack extends ViewStacks {
593593 outletId : string ,
594594 ionRouterOutlet : React . ReactElement ,
595595 routeInfo : RouteInfo ,
596- reRender : ( ) => void
596+ reRender : ( ) => void ,
597+ parentPathnameBase ?: string
597598 ) => {
598599 const viewItems = this . getViewItemsForOutlet ( outletId ) ;
599600
601+ // Seed the mount path from the parent route context if available.
602+ // This provides the outlet's mount path immediately on first render,
603+ // eliminating the need for heuristic-based discovery in computeParentPath.
604+ if ( parentPathnameBase && ! this . outletMountPaths . has ( outletId ) ) {
605+ this . outletMountPaths . set ( outletId , parentPathnameBase ) ;
606+ }
607+
600608 // Determine parentPath for outlets with relative or index routes.
601609 // This populates outletParentPaths for findViewItemByPath's matchView
602610 // and the catch-all deactivation logic in renderViewItem.
@@ -680,7 +688,7 @@ export class ReactRouterViewStack extends ViewStacks {
680688 const viewRoutePath = viewItem . reactElement ?. props ?. path as string | undefined ;
681689 if ( viewRoutePath ) {
682690 // First try exact match using matchComponent
683- const routeMatch = matchComponent ( viewItem . reactElement , routeInfo . pathname ) ;
691+ const routeMatch = matchComponent ( viewItem . reactElement , routeInfo . pathname , false , parentPath ) ;
684692 if ( routeMatch ) {
685693 // View matches current route, keep it
686694 return true ;
@@ -794,10 +802,10 @@ export class ReactRouterViewStack extends ViewStacks {
794802
795803 const isIndexRoute = ! ! v . routeData . childProps . index ;
796804 const previousMatch = v . routeData ?. match ;
797- const result = v . reactElement ? matchComponent ( v . reactElement , pathname ) : null ;
805+ const outletParentPath = storedParentPaths . get ( v . outletId ) ;
806+ const result = v . reactElement ? matchComponent ( v . reactElement , pathname , false , outletParentPath ) : null ;
798807
799808 if ( ! result ) {
800- const outletParentPath = storedParentPaths . get ( v . outletId ) ;
801809 const indexMatch = resolveIndexRouteMatch ( v , pathname , outletParentPath ) ;
802810 if ( indexMatch ) {
803811 match = indexMatch ;
@@ -977,10 +985,21 @@ export class ReactRouterViewStack extends ViewStacks {
977985/**
978986 * Utility to apply matchPath to a React element and return its match state.
979987 */
980- function matchComponent ( node : React . ReactElement , pathname : string , allowFallback = false ) {
988+ function matchComponent ( node : React . ReactElement , pathname : string , allowFallback = false , parentPath ?: string ) {
981989 const routeProps = node ?. props ?? { } ;
982990 const routePath : string | undefined = routeProps . path ;
983- const pathnameToMatch = derivePathnameToMatch ( pathname , routePath ) ;
991+
992+ let pathnameToMatch : string ;
993+ if ( parentPath && routePath && ! routePath . startsWith ( '/' ) ) {
994+ // When parent path is known, compute exact relative pathname
995+ // instead of using the tail-slice heuristic
996+ const relative = pathname . startsWith ( parentPath )
997+ ? pathname . slice ( parentPath . length ) . replace ( / ^ \/ / , '' )
998+ : pathname ;
999+ pathnameToMatch = relative ;
1000+ } else {
1001+ pathnameToMatch = derivePathnameToMatch ( pathname , routePath ) ;
1002+ }
9841003
9851004 const match = matchPath ( {
9861005 pathname : pathnameToMatch ,
0 commit comments