@vercel/next 3.5.0 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -41579,6 +41579,8 @@ const build = async ({ files, workPath, repoRootPath, entrypoint, config = {}, m
41579
41579
  ...Object.entries(prerenderManifest.fallbackRoutes),
41580
41580
  ...Object.entries(prerenderManifest.blockingFallbackRoutes),
41581
41581
  ].forEach(([, { dataRouteRegex, dataRoute }]) => {
41582
+ if (!dataRoute || !dataRouteRegex)
41583
+ return;
41582
41584
  dataRoutes.push({
41583
41585
  // Next.js provided data route regex
41584
41586
  src: dataRouteRegex.replace(/^\^/, `^${appMountPrefixNoTrailingSlash}`),
@@ -42433,7 +42435,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
42433
42435
  });
42434
42436
  }
42435
42437
  const pageMatchesApi = (page) => {
42436
- return page.startsWith('api/') || page === 'api.js';
42438
+ return (!appPathRoutesManifest?.[page] &&
42439
+ (page.startsWith('api/') || page === 'api.js'));
42437
42440
  };
42438
42441
  const { i18n } = routesManifest;
42439
42442
  const hasPages404 = routesManifest.pages404;
@@ -43049,7 +43052,16 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
43049
43052
  // to match prerenders so we can route the same when the
43050
43053
  // __rsc__ header is present
43051
43054
  const edgeFunctions = middleware.edgeFunctions;
43055
+ // allow looking up original route from normalized route
43056
+ const inverseAppPathManifest = {};
43057
+ for (const ogRoute of Object.keys(appPathRoutesManifest)) {
43058
+ inverseAppPathManifest[appPathRoutesManifest[ogRoute]] = ogRoute;
43059
+ }
43052
43060
  for (let route of Object.values(appPathRoutesManifest)) {
43061
+ const ogRoute = inverseAppPathManifest[route];
43062
+ if (ogRoute.endsWith('/route')) {
43063
+ continue;
43064
+ }
43053
43065
  route = path_1.default.posix.join('./', route === '/' ? '/index' : route);
43054
43066
  if (lambdas[route]) {
43055
43067
  lambdas[`${route}.rsc`] = lambdas[route];
@@ -43060,6 +43072,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
43060
43072
  }
43061
43073
  }
43062
43074
  const rscHeader = routesManifest.rsc?.header?.toLowerCase() || '__rsc__';
43075
+ const rscVaryHeader = routesManifest?.rsc?.varyHeader ||
43076
+ 'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
43063
43077
  const completeDynamicRoutes = [];
43064
43078
  if (appDir) {
43065
43079
  for (const route of dynamicRoutes) {
@@ -43270,7 +43284,9 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
43270
43284
  },
43271
43285
  ],
43272
43286
  dest: path_1.default.posix.join('/', entryDirectory, '/index.rsc'),
43287
+ headers: { vary: rscVaryHeader },
43273
43288
  continue: true,
43289
+ override: true,
43274
43290
  },
43275
43291
  {
43276
43292
  src: `^${path_1.default.posix.join('/', entryDirectory, '/((?!.+\\.rsc).+?)(?:/)?$')}`,
@@ -43281,7 +43297,9 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
43281
43297
  },
43282
43298
  ],
43283
43299
  dest: path_1.default.posix.join('/', entryDirectory, '/$1.rsc'),
43300
+ headers: { vary: rscVaryHeader },
43284
43301
  continue: true,
43302
+ override: true,
43285
43303
  },
43286
43304
  ]
43287
43305
  : []),
@@ -44286,7 +44304,8 @@ async function getPrerenderManifest(entryPath, outputDirectory) {
44286
44304
  return ret;
44287
44305
  }
44288
44306
  case 2:
44289
- case 3: {
44307
+ case 3:
44308
+ case 4: {
44290
44309
  const routes = Object.keys(manifest.routes);
44291
44310
  const lazyRoutes = Object.keys(manifest.dynamicRoutes);
44292
44311
  const ret = {
@@ -44303,12 +44322,20 @@ async function getPrerenderManifest(entryPath, outputDirectory) {
44303
44322
  }
44304
44323
  routes.forEach(route => {
44305
44324
  const { initialRevalidateSeconds, dataRoute, srcRoute } = manifest.routes[route];
44325
+ let initialStatus;
44326
+ let initialHeaders;
44327
+ if (manifest.version === 4) {
44328
+ initialStatus = manifest.routes[route].initialStatus;
44329
+ initialHeaders = manifest.routes[route].initialHeaders;
44330
+ }
44306
44331
  ret.staticRoutes[route] = {
44307
44332
  initialRevalidate: initialRevalidateSeconds === false
44308
44333
  ? false
44309
44334
  : Math.max(1, initialRevalidateSeconds),
44310
44335
  dataRoute,
44311
44336
  srcRoute,
44337
+ initialStatus,
44338
+ initialHeaders,
44312
44339
  };
44313
44340
  });
44314
44341
  lazyRoutes.forEach(lazyRoute => {
@@ -44642,7 +44669,7 @@ const onPrerenderRouteInitial = (prerenderManifest, canUsePreviewMode, entryDire
44642
44669
  const pr = prerenderManifest.staticRoutes[routeKey];
44643
44670
  const { initialRevalidate, srcRoute, dataRoute } = pr;
44644
44671
  const route = srcRoute || routeKey;
44645
- const isAppPathRoute = appDir && dataRoute?.endsWith('.rsc');
44672
+ const isAppPathRoute = appDir && (!dataRoute || dataRoute?.endsWith('.rsc'));
44646
44673
  const routeNoLocale = routesManifest?.i18n
44647
44674
  ? normalizeLocalePath(routeKey, routesManifest.i18n.locales).pathname
44648
44675
  : routeKey;
@@ -44724,6 +44751,8 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44724
44751
  let initialRevalidate;
44725
44752
  let srcRoute;
44726
44753
  let dataRoute;
44754
+ let initialStatus;
44755
+ let initialHeaders;
44727
44756
  if (isFallback || isBlocking) {
44728
44757
  const pr = isFallback
44729
44758
  ? prerenderManifest.fallbackRoutes[routeKey]
@@ -44747,32 +44776,49 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44747
44776
  }
44748
44777
  else {
44749
44778
  const pr = prerenderManifest.staticRoutes[routeKey];
44750
- ({ initialRevalidate, srcRoute, dataRoute } = pr);
44779
+ ({
44780
+ initialRevalidate,
44781
+ srcRoute,
44782
+ dataRoute,
44783
+ initialHeaders,
44784
+ initialStatus,
44785
+ } = pr);
44751
44786
  }
44752
44787
  let isAppPathRoute = false;
44753
44788
  // TODO: leverage manifest to determine app paths more accurately
44754
- if (appDir && srcRoute && dataRoute.endsWith('.rsc')) {
44789
+ if (appDir && srcRoute && (!dataRoute || dataRoute?.endsWith('.rsc'))) {
44755
44790
  isAppPathRoute = true;
44756
44791
  }
44757
44792
  const isOmittedOrNotFound = isOmitted || isNotFound;
44758
- const htmlFsRef = isBlocking || (isNotFound && !static404Page)
44759
- ? // Blocking pages do not have an HTML fallback
44760
- null
44761
- : new build_utils_1.FileFsRef({
44762
- fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
44763
- ? appDir
44764
- : pagesDir, isFallback
44765
- ? // Fallback pages have a special file.
44766
- addLocaleOrDefault(prerenderManifest.fallbackRoutes[routeKey].fallback, routesManifest, locale)
44767
- : // Otherwise, the route itself should exist as a static HTML
44768
- // file.
44769
- `${isOmittedOrNotFound
44770
- ? addLocaleOrDefault('/404', routesManifest, locale)
44771
- : routeFileNoExt}.html`),
44793
+ let htmlFsRef;
44794
+ if (appDir && !dataRoute && isAppPathRoute && !(isBlocking || isFallback)) {
44795
+ const contentType = initialHeaders?.['content-type'];
44796
+ htmlFsRef = new build_utils_1.FileFsRef({
44797
+ fsPath: path_1.default.join(appDir, `${routeFileNoExt}.body`),
44798
+ contentType: contentType || 'text/html;charset=utf-8',
44772
44799
  });
44800
+ }
44801
+ else {
44802
+ htmlFsRef =
44803
+ isBlocking || (isNotFound && !static404Page)
44804
+ ? // Blocking pages do not have an HTML fallback
44805
+ null
44806
+ : new build_utils_1.FileFsRef({
44807
+ fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
44808
+ ? appDir
44809
+ : pagesDir, isFallback
44810
+ ? // Fallback pages have a special file.
44811
+ addLocaleOrDefault(prerenderManifest.fallbackRoutes[routeKey].fallback, routesManifest, locale)
44812
+ : // Otherwise, the route itself should exist as a static HTML
44813
+ // file.
44814
+ `${isOmittedOrNotFound
44815
+ ? addLocaleOrDefault('/404', routesManifest, locale)
44816
+ : routeFileNoExt}.html`),
44817
+ });
44818
+ }
44773
44819
  const jsonFsRef =
44774
44820
  // JSON data does not exist for fallback or blocking pages
44775
- isFallback || isBlocking || (isNotFound && !static404Page)
44821
+ isFallback || isBlocking || (isNotFound && !static404Page) || !dataRoute
44776
44822
  ? null
44777
44823
  : new build_utils_1.FileFsRef({
44778
44824
  fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
@@ -44798,13 +44844,16 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44798
44844
  }
44799
44845
  const outputPathPageOrig = path_1.default.posix.join(entryDirectory, origRouteFileNoExt);
44800
44846
  let lambda;
44801
- let outputPathData = path_1.default.posix.join(entryDirectory, dataRoute);
44802
- if (nonDynamicSsg || isFallback || isOmitted) {
44803
- outputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`),
44804
- // ensure we escape "$" correctly while replacing as "$" is a special
44805
- // character, we need to do double escaping as first is for the initial
44806
- // replace on the routeFile and then the second on the outputPath
44807
- `${routeFileNoExt.replace(/\$/g, '$$$$')}.json`);
44847
+ let outputPathData = null;
44848
+ if (dataRoute) {
44849
+ outputPathData = path_1.default.posix.join(entryDirectory, dataRoute);
44850
+ if (nonDynamicSsg || isFallback || isOmitted) {
44851
+ outputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`),
44852
+ // ensure we escape "$" correctly while replacing as "$" is a special
44853
+ // character, we need to do double escaping as first is for the initial
44854
+ // replace on the routeFile and then the second on the outputPath
44855
+ `${routeFileNoExt.replace(/\$/g, '$$$$')}.json`);
44856
+ }
44808
44857
  }
44809
44858
  if (isSharedLambdas) {
44810
44859
  const outputSrcPathPage = normalizeIndexOutput(path_1.default.join('/', srcRoute == null
@@ -44823,7 +44872,7 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44823
44872
  if (htmlFsRef == null || jsonFsRef == null) {
44824
44873
  throw new build_utils_1.NowBuildError({
44825
44874
  code: 'NEXT_HTMLFSREF_JSONFSREF',
44826
- message: 'invariant: htmlFsRef != null && jsonFsRef != null',
44875
+ message: `invariant: htmlFsRef != null && jsonFsRef != null ${routeFileNoExt}`,
44827
44876
  });
44828
44877
  }
44829
44878
  // if preview mode/On-Demand ISR can't be leveraged
@@ -44832,7 +44881,9 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44832
44881
  (routeKey === '/404' && !lambdas[outputPathPage])) {
44833
44882
  htmlFsRef.contentType = _1.htmlContentType;
44834
44883
  prerenders[outputPathPage] = htmlFsRef;
44835
- prerenders[outputPathData] = jsonFsRef;
44884
+ if (outputPathData) {
44885
+ prerenders[outputPathData] = jsonFsRef;
44886
+ }
44836
44887
  }
44837
44888
  }
44838
44889
  const isNotFoundPreview = isCorrectNotFoundRoutes &&
@@ -44886,9 +44937,9 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44886
44937
  allowQuery = [];
44887
44938
  }
44888
44939
  }
44889
- const rscVaryHeader = routesManifest?.rsc?.varyHeader ||
44890
- '__rsc__, __next_router_state_tree__, __next_router_prefetch__';
44891
- const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || 'application/octet-stream';
44940
+ const rscEnabled = !!routesManifest?.rsc;
44941
+ const rscVaryHeader = routesManifest?.rsc?.varyHeader || 'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
44942
+ const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || 'text/x-component';
44892
44943
  prerenders[outputPathPage] = new build_utils_1.Prerender({
44893
44944
  expiration: initialRevalidate,
44894
44945
  lambda,
@@ -44896,59 +44947,66 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
44896
44947
  fallback: htmlFsRef,
44897
44948
  group: prerenderGroup,
44898
44949
  bypassToken: prerenderManifest.bypassToken,
44950
+ initialStatus,
44951
+ initialHeaders,
44899
44952
  ...(isNotFound
44900
44953
  ? {
44901
44954
  initialStatus: 404,
44902
44955
  }
44903
44956
  : {}),
44904
- ...(isAppPathRoute
44905
- ? {
44906
- initialHeaders: {
44907
- vary: rscVaryHeader,
44908
- },
44909
- }
44910
- : {}),
44911
- });
44912
- prerenders[outputPathData] = new build_utils_1.Prerender({
44913
- expiration: initialRevalidate,
44914
- lambda,
44915
- allowQuery,
44916
- fallback: jsonFsRef,
44917
- group: prerenderGroup,
44918
- bypassToken: prerenderManifest.bypassToken,
44919
- ...(isNotFound
44920
- ? {
44921
- initialStatus: 404,
44922
- }
44923
- : {}),
44924
- ...(isAppPathRoute
44957
+ ...(rscEnabled
44925
44958
  ? {
44926
44959
  initialHeaders: {
44927
- 'content-type': rscContentTypeHeader,
44960
+ ...initialHeaders,
44928
44961
  vary: rscVaryHeader,
44929
44962
  },
44930
44963
  }
44931
44964
  : {}),
44932
44965
  });
44966
+ if (outputPathData) {
44967
+ prerenders[outputPathData] = new build_utils_1.Prerender({
44968
+ expiration: initialRevalidate,
44969
+ lambda,
44970
+ allowQuery,
44971
+ fallback: jsonFsRef,
44972
+ group: prerenderGroup,
44973
+ bypassToken: prerenderManifest.bypassToken,
44974
+ ...(isNotFound
44975
+ ? {
44976
+ initialStatus: 404,
44977
+ }
44978
+ : {}),
44979
+ ...(rscEnabled
44980
+ ? {
44981
+ initialHeaders: {
44982
+ 'content-type': rscContentTypeHeader,
44983
+ vary: rscVaryHeader,
44984
+ },
44985
+ }
44986
+ : {}),
44987
+ });
44988
+ }
44933
44989
  ++prerenderGroup;
44934
44990
  if (routesManifest?.i18n && isBlocking) {
44935
44991
  for (const locale of routesManifest.i18n.locales) {
44936
44992
  const localeRouteFileNoExt = addLocaleOrDefault(routeFileNoExt, routesManifest, locale);
44937
44993
  const localeOutputPathPage = normalizeIndexOutput(path_1.default.posix.join(entryDirectory, localeRouteFileNoExt), isServerMode);
44938
- const localeOutputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`), `${localeRouteFileNoExt}${localeRouteFileNoExt !== origRouteFileNoExt &&
44939
- origRouteFileNoExt === '/index'
44940
- ? '/index'
44941
- : ''}.json`);
44942
44994
  const origPrerenderPage = prerenders[outputPathPage];
44943
- const origPrerenderData = prerenders[outputPathData];
44944
44995
  prerenders[localeOutputPathPage] = {
44945
44996
  ...origPrerenderPage,
44946
44997
  group: prerenderGroup,
44947
44998
  };
44948
- prerenders[localeOutputPathData] = {
44949
- ...origPrerenderData,
44950
- group: prerenderGroup,
44951
- };
44999
+ if (outputPathData) {
45000
+ const localeOutputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`), `${localeRouteFileNoExt}${localeRouteFileNoExt !== origRouteFileNoExt &&
45001
+ origRouteFileNoExt === '/index'
45002
+ ? '/index'
45003
+ : ''}.json`);
45004
+ const origPrerenderData = prerenders[outputPathData];
45005
+ prerenders[localeOutputPathData] = {
45006
+ ...origPrerenderData,
45007
+ group: prerenderGroup,
45008
+ };
45009
+ }
44952
45010
  ++prerenderGroup;
44953
45011
  }
44954
45012
  }
@@ -45180,9 +45238,11 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
45180
45238
  if (shortPath.startsWith('pages/')) {
45181
45239
  shortPath = shortPath.replace(/^pages\//, '');
45182
45240
  }
45183
- else if (shortPath.startsWith('app/') && shortPath.endsWith('/page')) {
45241
+ else if (shortPath.startsWith('app/') &&
45242
+ (shortPath.endsWith('/page') || shortPath.endsWith('/route'))) {
45184
45243
  shortPath =
45185
- shortPath.replace(/^app\//, '').replace(/(^|\/)page$/, '') || 'index';
45244
+ shortPath.replace(/^app\//, '').replace(/(^|\/)(page|route)$/, '') ||
45245
+ 'index';
45186
45246
  }
45187
45247
  if (routesManifest?.basePath) {
45188
45248
  shortPath = path_1.default.posix
@@ -47,7 +47,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47
47
  });
48
48
  }
49
49
  const pageMatchesApi = (page) => {
50
- return page.startsWith('api/') || page === 'api.js';
50
+ return (!appPathRoutesManifest?.[page] &&
51
+ (page.startsWith('api/') || page === 'api.js'));
51
52
  };
52
53
  const { i18n } = routesManifest;
53
54
  const hasPages404 = routesManifest.pages404;
@@ -663,7 +664,16 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
663
664
  // to match prerenders so we can route the same when the
664
665
  // __rsc__ header is present
665
666
  const edgeFunctions = middleware.edgeFunctions;
667
+ // allow looking up original route from normalized route
668
+ const inverseAppPathManifest = {};
669
+ for (const ogRoute of Object.keys(appPathRoutesManifest)) {
670
+ inverseAppPathManifest[appPathRoutesManifest[ogRoute]] = ogRoute;
671
+ }
666
672
  for (let route of Object.values(appPathRoutesManifest)) {
673
+ const ogRoute = inverseAppPathManifest[route];
674
+ if (ogRoute.endsWith('/route')) {
675
+ continue;
676
+ }
667
677
  route = path_1.default.posix.join('./', route === '/' ? '/index' : route);
668
678
  if (lambdas[route]) {
669
679
  lambdas[`${route}.rsc`] = lambdas[route];
@@ -674,6 +684,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
674
684
  }
675
685
  }
676
686
  const rscHeader = routesManifest.rsc?.header?.toLowerCase() || '__rsc__';
687
+ const rscVaryHeader = routesManifest?.rsc?.varyHeader ||
688
+ 'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
677
689
  const completeDynamicRoutes = [];
678
690
  if (appDir) {
679
691
  for (const route of dynamicRoutes) {
@@ -884,7 +896,9 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
884
896
  },
885
897
  ],
886
898
  dest: path_1.default.posix.join('/', entryDirectory, '/index.rsc'),
899
+ headers: { vary: rscVaryHeader },
887
900
  continue: true,
901
+ override: true,
888
902
  },
889
903
  {
890
904
  src: `^${path_1.default.posix.join('/', entryDirectory, '/((?!.+\\.rsc).+?)(?:/)?$')}`,
@@ -895,7 +909,9 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
895
909
  },
896
910
  ],
897
911
  dest: path_1.default.posix.join('/', entryDirectory, '/$1.rsc'),
912
+ headers: { vary: rscVaryHeader },
898
913
  continue: true,
914
+ override: true,
899
915
  },
900
916
  ]
901
917
  : []),
package/dist/utils.js CHANGED
@@ -658,7 +658,8 @@ async function getPrerenderManifest(entryPath, outputDirectory) {
658
658
  return ret;
659
659
  }
660
660
  case 2:
661
- case 3: {
661
+ case 3:
662
+ case 4: {
662
663
  const routes = Object.keys(manifest.routes);
663
664
  const lazyRoutes = Object.keys(manifest.dynamicRoutes);
664
665
  const ret = {
@@ -675,12 +676,20 @@ async function getPrerenderManifest(entryPath, outputDirectory) {
675
676
  }
676
677
  routes.forEach(route => {
677
678
  const { initialRevalidateSeconds, dataRoute, srcRoute } = manifest.routes[route];
679
+ let initialStatus;
680
+ let initialHeaders;
681
+ if (manifest.version === 4) {
682
+ initialStatus = manifest.routes[route].initialStatus;
683
+ initialHeaders = manifest.routes[route].initialHeaders;
684
+ }
678
685
  ret.staticRoutes[route] = {
679
686
  initialRevalidate: initialRevalidateSeconds === false
680
687
  ? false
681
688
  : Math.max(1, initialRevalidateSeconds),
682
689
  dataRoute,
683
690
  srcRoute,
691
+ initialStatus,
692
+ initialHeaders,
684
693
  };
685
694
  });
686
695
  lazyRoutes.forEach(lazyRoute => {
@@ -1014,7 +1023,7 @@ const onPrerenderRouteInitial = (prerenderManifest, canUsePreviewMode, entryDire
1014
1023
  const pr = prerenderManifest.staticRoutes[routeKey];
1015
1024
  const { initialRevalidate, srcRoute, dataRoute } = pr;
1016
1025
  const route = srcRoute || routeKey;
1017
- const isAppPathRoute = appDir && dataRoute?.endsWith('.rsc');
1026
+ const isAppPathRoute = appDir && (!dataRoute || dataRoute?.endsWith('.rsc'));
1018
1027
  const routeNoLocale = routesManifest?.i18n
1019
1028
  ? normalizeLocalePath(routeKey, routesManifest.i18n.locales).pathname
1020
1029
  : routeKey;
@@ -1096,6 +1105,8 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1096
1105
  let initialRevalidate;
1097
1106
  let srcRoute;
1098
1107
  let dataRoute;
1108
+ let initialStatus;
1109
+ let initialHeaders;
1099
1110
  if (isFallback || isBlocking) {
1100
1111
  const pr = isFallback
1101
1112
  ? prerenderManifest.fallbackRoutes[routeKey]
@@ -1119,32 +1130,49 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1119
1130
  }
1120
1131
  else {
1121
1132
  const pr = prerenderManifest.staticRoutes[routeKey];
1122
- ({ initialRevalidate, srcRoute, dataRoute } = pr);
1133
+ ({
1134
+ initialRevalidate,
1135
+ srcRoute,
1136
+ dataRoute,
1137
+ initialHeaders,
1138
+ initialStatus,
1139
+ } = pr);
1123
1140
  }
1124
1141
  let isAppPathRoute = false;
1125
1142
  // TODO: leverage manifest to determine app paths more accurately
1126
- if (appDir && srcRoute && dataRoute.endsWith('.rsc')) {
1143
+ if (appDir && srcRoute && (!dataRoute || dataRoute?.endsWith('.rsc'))) {
1127
1144
  isAppPathRoute = true;
1128
1145
  }
1129
1146
  const isOmittedOrNotFound = isOmitted || isNotFound;
1130
- const htmlFsRef = isBlocking || (isNotFound && !static404Page)
1131
- ? // Blocking pages do not have an HTML fallback
1132
- null
1133
- : new build_utils_1.FileFsRef({
1134
- fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
1135
- ? appDir
1136
- : pagesDir, isFallback
1137
- ? // Fallback pages have a special file.
1138
- addLocaleOrDefault(prerenderManifest.fallbackRoutes[routeKey].fallback, routesManifest, locale)
1139
- : // Otherwise, the route itself should exist as a static HTML
1140
- // file.
1141
- `${isOmittedOrNotFound
1142
- ? addLocaleOrDefault('/404', routesManifest, locale)
1143
- : routeFileNoExt}.html`),
1147
+ let htmlFsRef;
1148
+ if (appDir && !dataRoute && isAppPathRoute && !(isBlocking || isFallback)) {
1149
+ const contentType = initialHeaders?.['content-type'];
1150
+ htmlFsRef = new build_utils_1.FileFsRef({
1151
+ fsPath: path_1.default.join(appDir, `${routeFileNoExt}.body`),
1152
+ contentType: contentType || 'text/html;charset=utf-8',
1144
1153
  });
1154
+ }
1155
+ else {
1156
+ htmlFsRef =
1157
+ isBlocking || (isNotFound && !static404Page)
1158
+ ? // Blocking pages do not have an HTML fallback
1159
+ null
1160
+ : new build_utils_1.FileFsRef({
1161
+ fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
1162
+ ? appDir
1163
+ : pagesDir, isFallback
1164
+ ? // Fallback pages have a special file.
1165
+ addLocaleOrDefault(prerenderManifest.fallbackRoutes[routeKey].fallback, routesManifest, locale)
1166
+ : // Otherwise, the route itself should exist as a static HTML
1167
+ // file.
1168
+ `${isOmittedOrNotFound
1169
+ ? addLocaleOrDefault('/404', routesManifest, locale)
1170
+ : routeFileNoExt}.html`),
1171
+ });
1172
+ }
1145
1173
  const jsonFsRef =
1146
1174
  // JSON data does not exist for fallback or blocking pages
1147
- isFallback || isBlocking || (isNotFound && !static404Page)
1175
+ isFallback || isBlocking || (isNotFound && !static404Page) || !dataRoute
1148
1176
  ? null
1149
1177
  : new build_utils_1.FileFsRef({
1150
1178
  fsPath: path_1.default.join(isAppPathRoute && !isOmittedOrNotFound && appDir
@@ -1170,13 +1198,16 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1170
1198
  }
1171
1199
  const outputPathPageOrig = path_1.default.posix.join(entryDirectory, origRouteFileNoExt);
1172
1200
  let lambda;
1173
- let outputPathData = path_1.default.posix.join(entryDirectory, dataRoute);
1174
- if (nonDynamicSsg || isFallback || isOmitted) {
1175
- outputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`),
1176
- // ensure we escape "$" correctly while replacing as "$" is a special
1177
- // character, we need to do double escaping as first is for the initial
1178
- // replace on the routeFile and then the second on the outputPath
1179
- `${routeFileNoExt.replace(/\$/g, '$$$$')}.json`);
1201
+ let outputPathData = null;
1202
+ if (dataRoute) {
1203
+ outputPathData = path_1.default.posix.join(entryDirectory, dataRoute);
1204
+ if (nonDynamicSsg || isFallback || isOmitted) {
1205
+ outputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`),
1206
+ // ensure we escape "$" correctly while replacing as "$" is a special
1207
+ // character, we need to do double escaping as first is for the initial
1208
+ // replace on the routeFile and then the second on the outputPath
1209
+ `${routeFileNoExt.replace(/\$/g, '$$$$')}.json`);
1210
+ }
1180
1211
  }
1181
1212
  if (isSharedLambdas) {
1182
1213
  const outputSrcPathPage = normalizeIndexOutput(path_1.default.join('/', srcRoute == null
@@ -1195,7 +1226,7 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1195
1226
  if (htmlFsRef == null || jsonFsRef == null) {
1196
1227
  throw new build_utils_1.NowBuildError({
1197
1228
  code: 'NEXT_HTMLFSREF_JSONFSREF',
1198
- message: 'invariant: htmlFsRef != null && jsonFsRef != null',
1229
+ message: `invariant: htmlFsRef != null && jsonFsRef != null ${routeFileNoExt}`,
1199
1230
  });
1200
1231
  }
1201
1232
  // if preview mode/On-Demand ISR can't be leveraged
@@ -1204,7 +1235,9 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1204
1235
  (routeKey === '/404' && !lambdas[outputPathPage])) {
1205
1236
  htmlFsRef.contentType = _1.htmlContentType;
1206
1237
  prerenders[outputPathPage] = htmlFsRef;
1207
- prerenders[outputPathData] = jsonFsRef;
1238
+ if (outputPathData) {
1239
+ prerenders[outputPathData] = jsonFsRef;
1240
+ }
1208
1241
  }
1209
1242
  }
1210
1243
  const isNotFoundPreview = isCorrectNotFoundRoutes &&
@@ -1258,9 +1291,9 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1258
1291
  allowQuery = [];
1259
1292
  }
1260
1293
  }
1261
- const rscVaryHeader = routesManifest?.rsc?.varyHeader ||
1262
- '__rsc__, __next_router_state_tree__, __next_router_prefetch__';
1263
- const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || 'application/octet-stream';
1294
+ const rscEnabled = !!routesManifest?.rsc;
1295
+ const rscVaryHeader = routesManifest?.rsc?.varyHeader || 'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
1296
+ const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || 'text/x-component';
1264
1297
  prerenders[outputPathPage] = new build_utils_1.Prerender({
1265
1298
  expiration: initialRevalidate,
1266
1299
  lambda,
@@ -1268,59 +1301,66 @@ const onPrerenderRoute = (prerenderRouteArgs) => (routeKey, { isBlocking, isFall
1268
1301
  fallback: htmlFsRef,
1269
1302
  group: prerenderGroup,
1270
1303
  bypassToken: prerenderManifest.bypassToken,
1304
+ initialStatus,
1305
+ initialHeaders,
1271
1306
  ...(isNotFound
1272
1307
  ? {
1273
1308
  initialStatus: 404,
1274
1309
  }
1275
1310
  : {}),
1276
- ...(isAppPathRoute
1277
- ? {
1278
- initialHeaders: {
1279
- vary: rscVaryHeader,
1280
- },
1281
- }
1282
- : {}),
1283
- });
1284
- prerenders[outputPathData] = new build_utils_1.Prerender({
1285
- expiration: initialRevalidate,
1286
- lambda,
1287
- allowQuery,
1288
- fallback: jsonFsRef,
1289
- group: prerenderGroup,
1290
- bypassToken: prerenderManifest.bypassToken,
1291
- ...(isNotFound
1292
- ? {
1293
- initialStatus: 404,
1294
- }
1295
- : {}),
1296
- ...(isAppPathRoute
1311
+ ...(rscEnabled
1297
1312
  ? {
1298
1313
  initialHeaders: {
1299
- 'content-type': rscContentTypeHeader,
1314
+ ...initialHeaders,
1300
1315
  vary: rscVaryHeader,
1301
1316
  },
1302
1317
  }
1303
1318
  : {}),
1304
1319
  });
1320
+ if (outputPathData) {
1321
+ prerenders[outputPathData] = new build_utils_1.Prerender({
1322
+ expiration: initialRevalidate,
1323
+ lambda,
1324
+ allowQuery,
1325
+ fallback: jsonFsRef,
1326
+ group: prerenderGroup,
1327
+ bypassToken: prerenderManifest.bypassToken,
1328
+ ...(isNotFound
1329
+ ? {
1330
+ initialStatus: 404,
1331
+ }
1332
+ : {}),
1333
+ ...(rscEnabled
1334
+ ? {
1335
+ initialHeaders: {
1336
+ 'content-type': rscContentTypeHeader,
1337
+ vary: rscVaryHeader,
1338
+ },
1339
+ }
1340
+ : {}),
1341
+ });
1342
+ }
1305
1343
  ++prerenderGroup;
1306
1344
  if (routesManifest?.i18n && isBlocking) {
1307
1345
  for (const locale of routesManifest.i18n.locales) {
1308
1346
  const localeRouteFileNoExt = addLocaleOrDefault(routeFileNoExt, routesManifest, locale);
1309
1347
  const localeOutputPathPage = normalizeIndexOutput(path_1.default.posix.join(entryDirectory, localeRouteFileNoExt), isServerMode);
1310
- const localeOutputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`), `${localeRouteFileNoExt}${localeRouteFileNoExt !== origRouteFileNoExt &&
1311
- origRouteFileNoExt === '/index'
1312
- ? '/index'
1313
- : ''}.json`);
1314
1348
  const origPrerenderPage = prerenders[outputPathPage];
1315
- const origPrerenderData = prerenders[outputPathData];
1316
1349
  prerenders[localeOutputPathPage] = {
1317
1350
  ...origPrerenderPage,
1318
1351
  group: prerenderGroup,
1319
1352
  };
1320
- prerenders[localeOutputPathData] = {
1321
- ...origPrerenderData,
1322
- group: prerenderGroup,
1323
- };
1353
+ if (outputPathData) {
1354
+ const localeOutputPathData = outputPathData.replace(new RegExp(`${(0, escape_string_regexp_1.default)(origRouteFileNoExt)}.json$`), `${localeRouteFileNoExt}${localeRouteFileNoExt !== origRouteFileNoExt &&
1355
+ origRouteFileNoExt === '/index'
1356
+ ? '/index'
1357
+ : ''}.json`);
1358
+ const origPrerenderData = prerenders[outputPathData];
1359
+ prerenders[localeOutputPathData] = {
1360
+ ...origPrerenderData,
1361
+ group: prerenderGroup,
1362
+ };
1363
+ }
1324
1364
  ++prerenderGroup;
1325
1365
  }
1326
1366
  }
@@ -1552,9 +1592,11 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
1552
1592
  if (shortPath.startsWith('pages/')) {
1553
1593
  shortPath = shortPath.replace(/^pages\//, '');
1554
1594
  }
1555
- else if (shortPath.startsWith('app/') && shortPath.endsWith('/page')) {
1595
+ else if (shortPath.startsWith('app/') &&
1596
+ (shortPath.endsWith('/page') || shortPath.endsWith('/route'))) {
1556
1597
  shortPath =
1557
- shortPath.replace(/^app\//, '').replace(/(^|\/)page$/, '') || 'index';
1598
+ shortPath.replace(/^app\//, '').replace(/(^|\/)(page|route)$/, '') ||
1599
+ 'index';
1558
1600
  }
1559
1601
  if (routesManifest?.basePath) {
1560
1602
  shortPath = path_1.default.posix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/next",
3
- "version": "3.5.0",
3
+ "version": "3.5.2",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -71,5 +71,5 @@
71
71
  "typescript": "4.5.2",
72
72
  "webpack-sources": "3.2.3"
73
73
  },
74
- "gitHead": "70a53515bd12202f895c369504e2d5be6c9469f4"
74
+ "gitHead": "b30f000d2ab37bea5ec67c5461bb68d1a007cc3b"
75
75
  }