@@ -1386,8 +1386,8 @@ export class RouterCore<
1386
1386
if ( ! match ) return
1387
1387
1388
1388
match . abortController . abort ( )
1389
- match . _nonReactive . pendingTimeout = undefined
1390
1389
clearTimeout ( match . _nonReactive . pendingTimeout )
1390
+ match . _nonReactive . pendingTimeout = undefined
1391
1391
}
1392
1392
1393
1393
cancelMatches = ( ) => {
@@ -2114,7 +2114,10 @@ export class RouterCore<
2114
2114
triggerOnReady ( )
2115
2115
}
2116
2116
2117
- const handleRedirectAndNotFound = ( match : AnyRouteMatch , err : any ) => {
2117
+ const handleRedirectAndNotFound = (
2118
+ match : AnyRouteMatch | undefined ,
2119
+ err : any ,
2120
+ ) => {
2118
2121
if ( isRedirect ( err ) || isNotFound ( err ) ) {
2119
2122
if ( isRedirect ( err ) ) {
2120
2123
if ( err . redirectHandled ) {
@@ -2124,27 +2127,30 @@ export class RouterCore<
2124
2127
}
2125
2128
}
2126
2129
2127
- match . _nonReactive . beforeLoadPromise ?. resolve ( )
2128
- match . _nonReactive . loaderPromise ?. resolve ( )
2129
- match . _nonReactive . beforeLoadPromise = undefined
2130
- match . _nonReactive . loaderPromise = undefined
2131
-
2132
- updateMatch ( match . id , ( prev ) => ( {
2133
- ...prev ,
2134
- status : isRedirect ( err )
2135
- ? 'redirected'
2136
- : isNotFound ( err )
2137
- ? 'notFound'
2138
- : 'error' ,
2139
- isFetching : false ,
2140
- error : err ,
2141
- } ) )
2130
+ // in case of a redirecting match during preload, the match does not exist
2131
+ if ( match ) {
2132
+ match . _nonReactive . beforeLoadPromise ?. resolve ( )
2133
+ match . _nonReactive . loaderPromise ?. resolve ( )
2134
+ match . _nonReactive . beforeLoadPromise = undefined
2135
+ match . _nonReactive . loaderPromise = undefined
2136
+
2137
+ updateMatch ( match . id , ( prev ) => ( {
2138
+ ...prev ,
2139
+ status : isRedirect ( err )
2140
+ ? 'redirected'
2141
+ : isNotFound ( err )
2142
+ ? 'notFound'
2143
+ : 'error' ,
2144
+ isFetching : false ,
2145
+ error : err ,
2146
+ } ) )
2142
2147
2143
- if ( ! ( err as any ) . routeId ) {
2144
- ; ( err as any ) . routeId = match . routeId
2145
- }
2148
+ if ( ! ( err as any ) . routeId ) {
2149
+ ; ( err as any ) . routeId = match . routeId
2150
+ }
2146
2151
2147
- match . _nonReactive . loadPromise ?. resolve ( )
2152
+ match . _nonReactive . loadPromise ?. resolve ( )
2153
+ }
2148
2154
2149
2155
if ( isRedirect ( err ) ) {
2150
2156
rendered = true
@@ -2197,13 +2203,13 @@ export class RouterCore<
2197
2203
2198
2204
err . routerCode = routerCode
2199
2205
firstBadMatchIndex = firstBadMatchIndex ?? index
2200
- handleRedirectAndNotFound ( this . getMatch ( matchId ) ! , err )
2206
+ handleRedirectAndNotFound ( this . getMatch ( matchId ) , err )
2201
2207
2202
2208
try {
2203
2209
route . options . onError ?.( err )
2204
2210
} catch ( errorHandlerErr ) {
2205
2211
err = errorHandlerErr
2206
- handleRedirectAndNotFound ( this . getMatch ( matchId ) ! , err )
2212
+ handleRedirectAndNotFound ( this . getMatch ( matchId ) , err )
2207
2213
}
2208
2214
2209
2215
updateMatch ( matchId , ( prev ) => {
@@ -2458,35 +2464,45 @@ export class RouterCore<
2458
2464
let loaderIsRunningAsync = false
2459
2465
const route = this . looseRoutesById [ routeId ] !
2460
2466
2461
- const executeHead = async ( ) => {
2467
+ const executeHead = ( ) => {
2462
2468
const match = this . getMatch ( matchId )
2463
2469
// in case of a redirecting match during preload, the match does not exist
2464
2470
if ( ! match ) {
2465
2471
return
2466
2472
}
2473
+ if (
2474
+ ! route . options . head &&
2475
+ ! route . options . scripts &&
2476
+ ! route . options . headers
2477
+ ) {
2478
+ return
2479
+ }
2467
2480
const assetContext = {
2468
2481
matches,
2469
2482
match,
2470
2483
params : match . params ,
2471
2484
loaderData : match . loaderData ,
2472
2485
}
2473
- const headFnContent =
2474
- await route . options . head ?.( assetContext )
2475
- const meta = headFnContent ?. meta
2476
- const links = headFnContent ?. links
2477
- const headScripts = headFnContent ?. scripts
2478
- const styles = headFnContent ?. styles
2479
-
2480
- const scripts = await route . options . scripts ?.( assetContext )
2481
- const headers = await route . options . headers ?.( assetContext )
2482
- return {
2483
- meta,
2484
- links,
2485
- headScripts,
2486
- headers,
2487
- scripts,
2488
- styles,
2489
- }
2486
+
2487
+ return Promise . all ( [
2488
+ route . options . head ?.( assetContext ) ,
2489
+ route . options . scripts ?.( assetContext ) ,
2490
+ route . options . headers ?.( assetContext ) ,
2491
+ ] ) . then ( ( [ headFnContent , scripts , headers ] ) => {
2492
+ const meta = headFnContent ?. meta
2493
+ const links = headFnContent ?. links
2494
+ const headScripts = headFnContent ?. scripts
2495
+ const styles = headFnContent ?. styles
2496
+
2497
+ return {
2498
+ meta,
2499
+ links,
2500
+ headScripts,
2501
+ headers,
2502
+ scripts,
2503
+ styles,
2504
+ }
2505
+ } )
2490
2506
}
2491
2507
2492
2508
const potentialPendingMinPromise = async ( ) => {
@@ -2499,11 +2515,14 @@ export class RouterCore<
2499
2515
const prevMatch = this . getMatch ( matchId ) !
2500
2516
if ( shouldSkipLoader ( matchId ) ) {
2501
2517
if ( this . isServer ) {
2502
- const head = await executeHead ( )
2503
- updateMatch ( matchId , ( prev ) => ( {
2504
- ...prev ,
2505
- ...head ,
2506
- } ) )
2518
+ const headResult = executeHead ( )
2519
+ if ( headResult ) {
2520
+ const head = await headResult
2521
+ updateMatch ( matchId , ( prev ) => ( {
2522
+ ...prev ,
2523
+ ...head ,
2524
+ } ) )
2525
+ }
2507
2526
return this . getMatch ( matchId ) !
2508
2527
}
2509
2528
}
@@ -2615,7 +2634,7 @@ export class RouterCore<
2615
2634
await route . options . loader ?.( getLoaderContext ( ) )
2616
2635
2617
2636
handleRedirectAndNotFound (
2618
- this . getMatch ( matchId ) ! ,
2637
+ this . getMatch ( matchId ) ,
2619
2638
loaderData ,
2620
2639
)
2621
2640
updateMatch ( matchId , ( prev ) => ( {
@@ -2627,7 +2646,8 @@ export class RouterCore<
2627
2646
// so we need to wait for it to resolve before
2628
2647
// we can use the options
2629
2648
await route . _lazyPromise
2630
- const head = await executeHead ( )
2649
+ const headResult = executeHead ( )
2650
+ const head = headResult ? await headResult : undefined
2631
2651
await potentialPendingMinPromise ( )
2632
2652
2633
2653
// Last but not least, wait for the the components
@@ -2646,18 +2666,19 @@ export class RouterCore<
2646
2666
2647
2667
await potentialPendingMinPromise ( )
2648
2668
2649
- handleRedirectAndNotFound ( this . getMatch ( matchId ) ! , e )
2669
+ handleRedirectAndNotFound ( this . getMatch ( matchId ) , e )
2650
2670
2651
2671
try {
2652
2672
route . options . onError ?.( e )
2653
2673
} catch ( onErrorError ) {
2654
2674
error = onErrorError
2655
2675
handleRedirectAndNotFound (
2656
- this . getMatch ( matchId ) ! ,
2676
+ this . getMatch ( matchId ) ,
2657
2677
onErrorError ,
2658
2678
)
2659
2679
}
2660
- const head = await executeHead ( )
2680
+ const headResult = executeHead ( )
2681
+ const head = headResult ? await headResult : undefined
2661
2682
updateMatch ( matchId , ( prev ) => ( {
2662
2683
...prev ,
2663
2684
error,
@@ -2667,16 +2688,20 @@ export class RouterCore<
2667
2688
} ) )
2668
2689
}
2669
2690
} catch ( err ) {
2670
- const head = await executeHead ( )
2671
-
2672
- updateMatch ( matchId , ( prev ) => {
2673
- prev . _nonReactive . loaderPromise = undefined
2674
- return {
2675
- ...prev ,
2676
- ...head ,
2691
+ const match = this . getMatch ( matchId )
2692
+ // in case of a redirecting match during preload, the match does not exist
2693
+ if ( match ) {
2694
+ const headResult = executeHead ( )
2695
+ if ( headResult ) {
2696
+ const head = await headResult
2697
+ updateMatch ( matchId , ( prev ) => ( {
2698
+ ...prev ,
2699
+ ...head ,
2700
+ } ) )
2677
2701
}
2678
- } )
2679
- handleRedirectAndNotFound ( this . getMatch ( matchId ) ! , err )
2702
+ match . _nonReactive . loaderPromise = undefined
2703
+ }
2704
+ handleRedirectAndNotFound ( match , err )
2680
2705
}
2681
2706
}
2682
2707
@@ -2711,11 +2736,14 @@ export class RouterCore<
2711
2736
// if the loader did not run, still update head.
2712
2737
// reason: parent's beforeLoad may have changed the route context
2713
2738
// and only now do we know the route context (and that the loader would not run)
2714
- const head = await executeHead ( )
2715
- updateMatch ( matchId , ( prev ) => ( {
2716
- ...prev ,
2717
- ...head ,
2718
- } ) )
2739
+ const headResult = executeHead ( )
2740
+ if ( headResult ) {
2741
+ const head = await headResult
2742
+ updateMatch ( matchId , ( prev ) => ( {
2743
+ ...prev ,
2744
+ ...head ,
2745
+ } ) )
2746
+ }
2719
2747
}
2720
2748
}
2721
2749
if ( ! loaderIsRunningAsync ) {
0 commit comments