@@ -45,6 +45,7 @@ import type {
45
45
} from './cache-key'
46
46
import {
47
47
doesStaticSegmentAppearInURL ,
48
+ getCacheKeyForDynamicParam ,
48
49
getRenderedPathname ,
49
50
getRenderedSearch ,
50
51
parseDynamicParamFromURLPart ,
@@ -900,8 +901,11 @@ function convertRootTreePrefetchToRouteTree(
900
901
// Remove trailing and leading slashes
901
902
const pathnameParts = renderedPathname . split ( '/' ) . filter ( ( p ) => p !== '' )
902
903
const index = 0
904
+ const rootSegment = ROOT_SEGMENT_CACHE_KEY
903
905
return convertTreePrefetchToRouteTree (
904
906
rootTree . tree ,
907
+ rootSegment ,
908
+ null ,
905
909
ROOT_SEGMENT_REQUEST_KEY ,
906
910
ROOT_SEGMENT_CACHE_KEY ,
907
911
pathnameParts ,
@@ -911,6 +915,8 @@ function convertRootTreePrefetchToRouteTree(
911
915
912
916
function convertTreePrefetchToRouteTree (
913
917
prefetch : TreePrefetch ,
918
+ segment : FlightRouterStateSegment ,
919
+ param : RouteParam | null ,
914
920
requestKey : SegmentRequestKey ,
915
921
cacheKey : SegmentCacheKey ,
916
922
pathnameParts : Array < string > ,
@@ -922,52 +928,71 @@ function convertTreePrefetchToRouteTree(
922
928
// it once instead of on every access. This same cache key is also used to
923
929
// request the segment from the server.
924
930
925
- let segment = prefetch . segment
926
-
927
- let doesAppearInURL : boolean
928
- let param : RouteParam | null = null
929
- if ( Array . isArray ( segment ) ) {
930
- // This segment is parameterized. Get the param from the pathname.
931
- const paramType = segment [ 2 ] as DynamicParamTypesShort
932
- const paramValue = parseDynamicParamFromURLPart (
933
- paramType ,
934
- pathnameParts ,
935
- pathnamePartsIndex
936
- )
937
- param = {
938
- name : segment [ 0 ] ,
939
- value : paramValue ,
940
- type : paramType ,
941
- }
942
-
943
- // Assign a cache key to the segment, based on the param value. In the
944
- // pre-Segment Cache implementation, the server computes this and sends it
945
- // in the body of the response. In the Segment Cache implementation, the
946
- // server sends an empty string and we fill it in here.
947
- // TODO: This will land in a follow up PR.
948
- // segment[1] = getCacheKeyForDynamicParam(paramValue)
949
-
950
- doesAppearInURL = true
951
- } else {
952
- doesAppearInURL = doesStaticSegmentAppearInURL ( segment )
953
- }
954
-
955
- // Only increment the index if the segment appears in the URL. If it's a
956
- // "virtual" segment, like a route group, it remains the same.
957
- const childPathnamePartsIndex = doesAppearInURL
958
- ? pathnamePartsIndex + 1
959
- : pathnamePartsIndex
960
-
961
931
let slots : { [ parallelRouteKey : string ] : RouteTree } | null = null
962
932
const prefetchSlots = prefetch . slots
963
933
if ( prefetchSlots !== null ) {
964
934
slots = { }
965
935
for ( let parallelRouteKey in prefetchSlots ) {
966
936
const childPrefetch = prefetchSlots [ parallelRouteKey ]
967
- const childSegment = childPrefetch . segment
968
- // TODO: Eventually, the param values will not be included in the response
969
- // from the server. We'll instead fill them in on the client by parsing
970
- // the URL. This is where we'll do that.
937
+ const childParamName = childPrefetch . name
938
+ const childParamType = childPrefetch . paramType
939
+ const childServerSentParamKey = childPrefetch . paramKey
940
+
941
+ let childDoesAppearInURL : boolean
942
+ let childParam : RouteParam | null = null
943
+ let childSegment : FlightRouterStateSegment
944
+ if ( childParamType !== null ) {
945
+ // This segment is parameterized. Get the param from the pathname.
946
+ const childParamValue = parseDynamicParamFromURLPart (
947
+ childParamType ,
948
+ pathnameParts ,
949
+ pathnamePartsIndex
950
+ )
951
+
952
+ // Assign a cache key to the segment, based on the param value. In the
953
+ // pre-Segment Cache implementation, the server computes this and sends
954
+ // it in the body of the response. In the Segment Cache implementation,
955
+ // the server sends an empty string and we fill it in here.
956
+
957
+ // TODO: We're intentionally not adding the search param to page
958
+ // segments here; it's tracked separately and added back during a read.
959
+ // This would clearer if we waited to construct the segment until it's
960
+ // read from the cache, since that's effectively what we're
961
+ // doing anyway.
962
+ const renderedSearch = '' as NormalizedSearch
963
+ const childParamKey =
964
+ // The server omits this field from the prefetch response when
965
+ // clientParamParsing is enabled. The flag only exists while we're
966
+ // testing the feature, in case there's a bug and we need to revert.
967
+ // TODO: Remove once clientParamParsing is enabled everywhere.
968
+ childServerSentParamKey !== null
969
+ ? childServerSentParamKey
970
+ : // If no param key was sent, use the value parsed on the client.
971
+ getCacheKeyForDynamicParam ( childParamValue , renderedSearch )
972
+
973
+ childParam = {
974
+ name : childParamName ,
975
+ value : childParamValue ,
976
+ type : childParamType ,
977
+ }
978
+ childSegment = [
979
+ childParamName ,
980
+ childParamKey ,
981
+ childParamType ,
982
+ childParamValue ,
983
+ ]
984
+ childDoesAppearInURL = true
985
+ } else {
986
+ childSegment = childParamName
987
+ childDoesAppearInURL = doesStaticSegmentAppearInURL ( childParamName )
988
+ }
989
+
990
+ // Only increment the index if the segment appears in the URL. If it's a
991
+ // "virtual" segment, like a route group, it remains the same.
992
+ const childPathnamePartsIndex = childDoesAppearInURL
993
+ ? pathnamePartsIndex + 1
994
+ : pathnamePartsIndex
995
+
971
996
const childRequestKeyPart = createSegmentRequestKeyPart ( childSegment )
972
997
const childRequestKey = appendSegmentRequestKeyPart (
973
998
requestKey ,
@@ -981,6 +1006,8 @@ function convertTreePrefetchToRouteTree(
981
1006
)
982
1007
slots [ parallelRouteKey ] = convertTreePrefetchToRouteTree (
983
1008
childPrefetch ,
1009
+ childSegment ,
1010
+ childParam ,
984
1011
childRequestKey ,
985
1012
childCacheKey ,
986
1013
pathnameParts ,
0 commit comments