render.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.renderToHTML = renderToHTML;
  6. var _react = _interopRequireDefault(require("react"));
  7. var _styledJsx = require("styled-jsx");
  8. var _constants = require("../lib/constants");
  9. var _constants1 = require("../shared/lib/constants");
  10. var _isSerializableProps = require("../lib/is-serializable-props");
  11. var _ampMode = require("../shared/lib/amp-mode");
  12. var _ampContext = require("../shared/lib/amp-context");
  13. var _head = require("../shared/lib/head");
  14. var _headManagerContext = require("../shared/lib/head-manager-context");
  15. var _loadable = _interopRequireDefault(require("../shared/lib/loadable"));
  16. var _loadableContext = require("../shared/lib/loadable-context");
  17. var _routerContext = require("../shared/lib/router-context");
  18. var _isDynamic = require("../shared/lib/router/utils/is-dynamic");
  19. var _utils = require("../shared/lib/utils");
  20. var _htmlContext = require("../shared/lib/html-context");
  21. var _normalizePagePath = require("../shared/lib/page-path/normalize-page-path");
  22. var _denormalizePagePath = require("../shared/lib/page-path/denormalize-page-path");
  23. var _requestMeta = require("./request-meta");
  24. var _redirectStatus = require("../lib/redirect-status");
  25. var _renderResult = _interopRequireDefault(require("./render-result"));
  26. var _isError = _interopRequireDefault(require("../lib/is-error"));
  27. var _nodeWebStreamsHelper = require("./node-web-streams-helper");
  28. var _imageConfigContext = require("../shared/lib/image-config-context");
  29. var _stripAnsi = _interopRequireDefault(require("next/dist/compiled/strip-ansi"));
  30. var _utils1 = require("./utils");
  31. var _internalUtils = require("./internal-utils");
  32. function _interopRequireDefault(obj) {
  33. return obj && obj.__esModule ? obj : {
  34. default: obj
  35. };
  36. }
  37. let tryGetPreviewData;
  38. let warn;
  39. let postProcessHTML;
  40. const DOCTYPE = "<!DOCTYPE html>";
  41. const ReactDOMServer = _utils1.shouldUseReactRoot ? require("react-dom/server.browser") : require("react-dom/server");
  42. if (process.env.NEXT_RUNTIME !== "edge") {
  43. require("./node-polyfill-web-streams");
  44. tryGetPreviewData = require("./api-utils/node").tryGetPreviewData;
  45. warn = require("../build/output/log").warn;
  46. postProcessHTML = require("./post-process").postProcessHTML;
  47. } else {
  48. warn = console.warn.bind(console);
  49. postProcessHTML = async (_pathname, html)=>html;
  50. }
  51. function noRouter() {
  52. const message = 'No router instance found. you should only use "next/router" inside the client side of your app. https://nextjs.org/docs/messages/no-router-instance';
  53. throw new Error(message);
  54. }
  55. class ServerRouter {
  56. constructor(pathname, query, as, { isFallback }, isReady, basePath, locale, locales, defaultLocale, domainLocales, isPreview, isLocaleDomain){
  57. this.route = pathname.replace(/\/$/, "") || "/";
  58. this.pathname = pathname;
  59. this.query = query;
  60. this.asPath = as;
  61. this.isFallback = isFallback;
  62. this.basePath = basePath;
  63. this.locale = locale;
  64. this.locales = locales;
  65. this.defaultLocale = defaultLocale;
  66. this.isReady = isReady;
  67. this.domainLocales = domainLocales;
  68. this.isPreview = !!isPreview;
  69. this.isLocaleDomain = !!isLocaleDomain;
  70. }
  71. push() {
  72. noRouter();
  73. }
  74. replace() {
  75. noRouter();
  76. }
  77. reload() {
  78. noRouter();
  79. }
  80. back() {
  81. noRouter();
  82. }
  83. prefetch() {
  84. noRouter();
  85. }
  86. beforePopState() {
  87. noRouter();
  88. }
  89. }
  90. function enhanceComponents(options, App, Component) {
  91. // For backwards compatibility
  92. if (typeof options === "function") {
  93. return {
  94. App,
  95. Component: options(Component)
  96. };
  97. }
  98. return {
  99. App: options.enhanceApp ? options.enhanceApp(App) : App,
  100. Component: options.enhanceComponent ? options.enhanceComponent(Component) : Component
  101. };
  102. }
  103. function renderPageTree(App, Component, props) {
  104. return /*#__PURE__*/ _react.default.createElement(App, Object.assign({
  105. Component: Component
  106. }, props));
  107. }
  108. const invalidKeysMsg = (methodName, invalidKeys)=>{
  109. const docsPathname = `invalid-${methodName.toLocaleLowerCase()}-value`;
  110. return `Additional keys were returned from \`${methodName}\`. Properties intended for your component must be nested under the \`props\` key, e.g.:` + `\n\n\treturn { props: { title: 'My Title', content: '...' } }` + `\n\nKeys that need to be moved: ${invalidKeys.join(", ")}.` + `\nRead more: https://nextjs.org/docs/messages/${docsPathname}`;
  111. };
  112. function checkRedirectValues(redirect, req, method) {
  113. const { destination , permanent , statusCode , basePath } = redirect;
  114. let errors = [];
  115. const hasStatusCode = typeof statusCode !== "undefined";
  116. const hasPermanent = typeof permanent !== "undefined";
  117. if (hasPermanent && hasStatusCode) {
  118. errors.push(`\`permanent\` and \`statusCode\` can not both be provided`);
  119. } else if (hasPermanent && typeof permanent !== "boolean") {
  120. errors.push(`\`permanent\` must be \`true\` or \`false\``);
  121. } else if (hasStatusCode && !_redirectStatus.allowedStatusCodes.has(statusCode)) {
  122. errors.push(`\`statusCode\` must undefined or one of ${[
  123. ..._redirectStatus.allowedStatusCodes
  124. ].join(", ")}`);
  125. }
  126. const destinationType = typeof destination;
  127. if (destinationType !== "string") {
  128. errors.push(`\`destination\` should be string but received ${destinationType}`);
  129. }
  130. const basePathType = typeof basePath;
  131. if (basePathType !== "undefined" && basePathType !== "boolean") {
  132. errors.push(`\`basePath\` should be undefined or a false, received ${basePathType}`);
  133. }
  134. if (errors.length > 0) {
  135. throw new Error(`Invalid redirect object returned from ${method} for ${req.url}\n` + errors.join(" and ") + "\n" + `See more info here: https://nextjs.org/docs/messages/invalid-redirect-gssp`);
  136. }
  137. }
  138. function errorToJSON(err) {
  139. let source = "server";
  140. if (process.env.NEXT_RUNTIME !== "edge") {
  141. source = require("next/dist/compiled/@next/react-dev-overlay/dist/middleware").getErrorSource(err) || "server";
  142. }
  143. return {
  144. name: err.name,
  145. source,
  146. message: (0, _stripAnsi).default(err.message),
  147. stack: err.stack
  148. };
  149. }
  150. function serializeError(dev, err) {
  151. if (dev) {
  152. return errorToJSON(err);
  153. }
  154. return {
  155. name: "Internal Server Error.",
  156. message: "500 - Internal Server Error.",
  157. statusCode: 500
  158. };
  159. }
  160. async function renderToHTML(req, res, pathname, query, renderOpts) {
  161. var ref, ref1;
  162. // In dev we invalidate the cache by appending a timestamp to the resource URL.
  163. // This is a workaround to fix https://github.com/vercel/next.js/issues/5860
  164. // TODO: remove this workaround when https://bugs.webkit.org/show_bug.cgi?id=187726 is fixed.
  165. renderOpts.devOnlyCacheBusterQueryString = renderOpts.dev ? renderOpts.devOnlyCacheBusterQueryString || `?ts=${Date.now()}` : "";
  166. // don't modify original query object
  167. query = Object.assign({}, query);
  168. const { err , dev =false , ampPath ="" , pageConfig ={} , buildManifest , reactLoadableManifest , ErrorDebug , getStaticProps , getStaticPaths , getServerSideProps , isDataReq , params , previewProps , basePath , devOnlyCacheBusterQueryString , supportsDynamicHTML , images , runtime: globalRuntime , App , } = renderOpts;
  169. let Document = renderOpts.Document;
  170. // Component will be wrapped by ServerComponentWrapper for RSC
  171. let Component = renderOpts.Component;
  172. const OriginComponent = Component;
  173. let serverComponentsInlinedTransformStream = null;
  174. const isFallback = !!query.__nextFallback;
  175. const notFoundSrcPage = query.__nextNotFoundSrcPage;
  176. // next internal queries should be stripped out
  177. (0, _internalUtils).stripInternalQueries(query);
  178. const callMiddleware = async (method, args, props = false)=>{
  179. let results = props ? {} : [];
  180. if (Document[`${method}Middleware`]) {
  181. let middlewareFunc = await Document[`${method}Middleware`];
  182. middlewareFunc = middlewareFunc.default || middlewareFunc;
  183. const curResults = await middlewareFunc(...args);
  184. if (props) {
  185. for (const result of curResults){
  186. results = {
  187. ...results,
  188. ...result
  189. };
  190. }
  191. } else {
  192. results = curResults;
  193. }
  194. }
  195. return results;
  196. };
  197. const headTags = (...args)=>callMiddleware("headTags", args);
  198. const isSSG = !!getStaticProps;
  199. const isBuildTimeSSG = isSSG && renderOpts.nextExport;
  200. const defaultAppGetInitialProps = App.getInitialProps === App.origGetInitialProps;
  201. const hasPageGetInitialProps = !!((ref = Component) == null ? void 0 : ref.getInitialProps);
  202. const hasPageScripts = (ref1 = Component) == null ? void 0 : ref1.unstable_scriptLoader;
  203. const pageIsDynamic = (0, _isDynamic).isDynamicRoute(pathname);
  204. const defaultErrorGetInitialProps = pathname === "/_error" && Component.getInitialProps === Component.origGetInitialProps;
  205. if (renderOpts.nextExport && hasPageGetInitialProps && !defaultErrorGetInitialProps) {
  206. warn(`Detected getInitialProps on page '${pathname}'` + `while running "next export". It's recommended to use getStaticProps` + `which has a more correct behavior for static exporting.` + `\nRead more: https://nextjs.org/docs/messages/get-initial-props-export`);
  207. }
  208. const isAutoExport = !hasPageGetInitialProps && defaultAppGetInitialProps && !isSSG && !getServerSideProps;
  209. if (hasPageGetInitialProps && isSSG) {
  210. throw new Error(_constants.SSG_GET_INITIAL_PROPS_CONFLICT + ` ${pathname}`);
  211. }
  212. if (hasPageGetInitialProps && getServerSideProps) {
  213. throw new Error(_constants.SERVER_PROPS_GET_INIT_PROPS_CONFLICT + ` ${pathname}`);
  214. }
  215. if (getServerSideProps && isSSG) {
  216. throw new Error(_constants.SERVER_PROPS_SSG_CONFLICT + ` ${pathname}`);
  217. }
  218. if (getStaticPaths && !pageIsDynamic) {
  219. throw new Error(`getStaticPaths is only allowed for dynamic SSG pages and was found on '${pathname}'.` + `\nRead more: https://nextjs.org/docs/messages/non-dynamic-getstaticpaths-usage`);
  220. }
  221. if (!!getStaticPaths && !isSSG) {
  222. throw new Error(`getStaticPaths was added without a getStaticProps in ${pathname}. Without getStaticProps, getStaticPaths does nothing`);
  223. }
  224. if (isSSG && pageIsDynamic && !getStaticPaths) {
  225. throw new Error(`getStaticPaths is required for dynamic SSG pages and is missing for '${pathname}'.` + `\nRead more: https://nextjs.org/docs/messages/invalid-getstaticpaths-value`);
  226. }
  227. let asPath = renderOpts.resolvedAsPath || req.url;
  228. if (dev) {
  229. const { isValidElementType } = require("next/dist/compiled/react-is");
  230. if (!isValidElementType(Component)) {
  231. throw new Error(`The default export is not a React Component in page: "${pathname}"`);
  232. }
  233. if (!isValidElementType(App)) {
  234. throw new Error(`The default export is not a React Component in page: "/_app"`);
  235. }
  236. if (!isValidElementType(Document)) {
  237. throw new Error(`The default export is not a React Component in page: "/_document"`);
  238. }
  239. if (isAutoExport || isFallback) {
  240. // remove query values except ones that will be set during export
  241. query = {
  242. ...query.amp ? {
  243. amp: query.amp
  244. } : {}
  245. };
  246. asPath = `${pathname}${// ensure trailing slash is present for non-dynamic auto-export pages
  247. req.url.endsWith("/") && pathname !== "/" && !pageIsDynamic ? "/" : ""}`;
  248. req.url = pathname;
  249. }
  250. if (pathname === "/404" && (hasPageGetInitialProps || getServerSideProps)) {
  251. throw new Error(`\`pages/404\` ${_constants.STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR}`);
  252. }
  253. if (_constants1.STATIC_STATUS_PAGES.includes(pathname) && (hasPageGetInitialProps || getServerSideProps)) {
  254. throw new Error(`\`pages${pathname}\` ${_constants.STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR}`);
  255. }
  256. }
  257. for (const methodName of [
  258. "getStaticProps",
  259. "getServerSideProps",
  260. "getStaticPaths",
  261. ]){
  262. var ref2;
  263. if ((ref2 = Component) == null ? void 0 : ref2[methodName]) {
  264. throw new Error(`page ${pathname} ${methodName} ${_constants.GSSP_COMPONENT_MEMBER_ERROR}`);
  265. }
  266. }
  267. await _loadable.default.preloadAll() // Make sure all dynamic imports are loaded
  268. ;
  269. let isPreview;
  270. let previewData;
  271. if ((isSSG || getServerSideProps) && !isFallback && process.env.NEXT_RUNTIME !== "edge") {
  272. // Reads of this are cached on the `req` object, so this should resolve
  273. // instantly. There's no need to pass this data down from a previous
  274. // invoke, where we'd have to consider server & serverless.
  275. previewData = tryGetPreviewData(req, res, previewProps);
  276. isPreview = previewData !== false;
  277. }
  278. // url will always be set
  279. const routerIsReady = !!(getServerSideProps || hasPageGetInitialProps || !defaultAppGetInitialProps && !isSSG);
  280. const router = new ServerRouter(pathname, query, asPath, {
  281. isFallback: isFallback
  282. }, routerIsReady, basePath, renderOpts.locale, renderOpts.locales, renderOpts.defaultLocale, renderOpts.domainLocales, isPreview, (0, _requestMeta).getRequestMeta(req, "__nextIsLocaleDomain"));
  283. let scriptLoader = {};
  284. const jsxStyleRegistry = (0, _styledJsx).createStyleRegistry();
  285. const ampState = {
  286. ampFirst: pageConfig.amp === true,
  287. hasQuery: Boolean(query.amp),
  288. hybrid: pageConfig.amp === "hybrid"
  289. };
  290. // Disable AMP under the web environment
  291. const inAmpMode = process.env.NEXT_RUNTIME !== "edge" && (0, _ampMode).isInAmpMode(ampState);
  292. let head = (0, _head).defaultHead(inAmpMode);
  293. const reactLoadableModules = [];
  294. let initialScripts = {};
  295. if (hasPageScripts) {
  296. initialScripts.beforeInteractive = [].concat(hasPageScripts()).filter((script)=>script.props.strategy === "beforeInteractive").map((script)=>script.props);
  297. }
  298. const AppContainer = ({ children })=>/*#__PURE__*/ _react.default.createElement(_routerContext.RouterContext.Provider, {
  299. value: router
  300. }, /*#__PURE__*/ _react.default.createElement(_ampContext.AmpStateContext.Provider, {
  301. value: ampState
  302. }, /*#__PURE__*/ _react.default.createElement(_headManagerContext.HeadManagerContext.Provider, {
  303. value: {
  304. updateHead: (state)=>{
  305. head = state;
  306. },
  307. updateScripts: (scripts)=>{
  308. scriptLoader = scripts;
  309. },
  310. scripts: initialScripts,
  311. mountedInstances: new Set()
  312. }
  313. }, /*#__PURE__*/ _react.default.createElement(_loadableContext.LoadableContext.Provider, {
  314. value: (moduleName)=>reactLoadableModules.push(moduleName)
  315. }, /*#__PURE__*/ _react.default.createElement(_styledJsx.StyleRegistry, {
  316. registry: jsxStyleRegistry
  317. }, /*#__PURE__*/ _react.default.createElement(_imageConfigContext.ImageConfigContext.Provider, {
  318. value: images
  319. }, children))))));
  320. // The `useId` API uses the path indexes to generate an ID for each node.
  321. // To guarantee the match of hydration, we need to ensure that the structure
  322. // of wrapper nodes is isomorphic in server and client.
  323. // TODO: With `enhanceApp` and `enhanceComponents` options, this approach may
  324. // not be useful.
  325. // https://github.com/facebook/react/pull/22644
  326. const Noop = ()=>null;
  327. const AppContainerWithIsomorphicFiberStructure = ({ children })=>{
  328. return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(Noop, null), /*#__PURE__*/ _react.default.createElement(AppContainer, null, /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, dev ? /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, children, /*#__PURE__*/ _react.default.createElement(Noop, null)) : children, /*#__PURE__*/ _react.default.createElement(Noop, null))));
  329. };
  330. const ctx = {
  331. err,
  332. req: isAutoExport ? undefined : req,
  333. res: isAutoExport ? undefined : res,
  334. pathname,
  335. query,
  336. asPath,
  337. locale: renderOpts.locale,
  338. locales: renderOpts.locales,
  339. defaultLocale: renderOpts.defaultLocale,
  340. AppTree: (props)=>{
  341. return /*#__PURE__*/ _react.default.createElement(AppContainerWithIsomorphicFiberStructure, null, renderPageTree(App, OriginComponent, {
  342. ...props,
  343. router
  344. }));
  345. },
  346. defaultGetInitialProps: async (docCtx, options = {})=>{
  347. const enhanceApp = (AppComp)=>{
  348. return (props)=>/*#__PURE__*/ _react.default.createElement(AppComp, Object.assign({}, props));
  349. };
  350. const { html , head: renderPageHead } = await docCtx.renderPage({
  351. enhanceApp
  352. });
  353. const styles = jsxStyleRegistry.styles({
  354. nonce: options.nonce
  355. });
  356. jsxStyleRegistry.flush();
  357. return {
  358. html,
  359. head: renderPageHead,
  360. styles
  361. };
  362. }
  363. };
  364. let props1;
  365. const nextExport = !isSSG && (renderOpts.nextExport || dev && (isAutoExport || isFallback));
  366. const styledJsxFlushEffect = ()=>{
  367. const styles = jsxStyleRegistry.styles();
  368. jsxStyleRegistry.flush();
  369. return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, styles);
  370. };
  371. props1 = await (0, _utils).loadGetInitialProps(App, {
  372. AppTree: ctx.AppTree,
  373. Component,
  374. router,
  375. ctx
  376. });
  377. if ((isSSG || getServerSideProps) && isPreview) {
  378. props1.__N_PREVIEW = true;
  379. }
  380. if (isSSG) {
  381. props1[_constants1.STATIC_PROPS_ID] = true;
  382. }
  383. if (isSSG && !isFallback) {
  384. let data;
  385. try {
  386. data = await getStaticProps({
  387. ...pageIsDynamic ? {
  388. params: query
  389. } : undefined,
  390. ...isPreview ? {
  391. preview: true,
  392. previewData: previewData
  393. } : undefined,
  394. locales: renderOpts.locales,
  395. locale: renderOpts.locale,
  396. defaultLocale: renderOpts.defaultLocale
  397. });
  398. } catch (staticPropsError) {
  399. // remove not found error code to prevent triggering legacy
  400. // 404 rendering
  401. if (staticPropsError && staticPropsError.code === "ENOENT") {
  402. delete staticPropsError.code;
  403. }
  404. throw staticPropsError;
  405. }
  406. if (data == null) {
  407. throw new Error(_constants.GSP_NO_RETURNED_VALUE);
  408. }
  409. const invalidKeys = Object.keys(data).filter((key)=>key !== "revalidate" && key !== "props" && key !== "redirect" && key !== "notFound");
  410. if (invalidKeys.includes("unstable_revalidate")) {
  411. throw new Error(_constants.UNSTABLE_REVALIDATE_RENAME_ERROR);
  412. }
  413. if (invalidKeys.length) {
  414. throw new Error(invalidKeysMsg("getStaticProps", invalidKeys));
  415. }
  416. if (process.env.NODE_ENV !== "production") {
  417. if (typeof data.notFound !== "undefined" && typeof data.redirect !== "undefined") {
  418. throw new Error(`\`redirect\` and \`notFound\` can not both be returned from ${isSSG ? "getStaticProps" : "getServerSideProps"} at the same time. Page: ${pathname}\nSee more info here: https://nextjs.org/docs/messages/gssp-mixed-not-found-redirect`);
  419. }
  420. }
  421. if ("notFound" in data && data.notFound) {
  422. if (pathname === "/404") {
  423. throw new Error(`The /404 page can not return notFound in "getStaticProps", please remove it to continue!`);
  424. }
  425. renderOpts.isNotFound = true;
  426. }
  427. if ("redirect" in data && data.redirect && typeof data.redirect === "object") {
  428. checkRedirectValues(data.redirect, req, "getStaticProps");
  429. if (isBuildTimeSSG) {
  430. throw new Error(`\`redirect\` can not be returned from getStaticProps during prerendering (${req.url})\n` + `See more info here: https://nextjs.org/docs/messages/gsp-redirect-during-prerender`);
  431. }
  432. data.props = {
  433. __N_REDIRECT: data.redirect.destination,
  434. __N_REDIRECT_STATUS: (0, _redirectStatus).getRedirectStatus(data.redirect)
  435. };
  436. if (typeof data.redirect.basePath !== "undefined") {
  437. data.props.__N_REDIRECT_BASE_PATH = data.redirect.basePath;
  438. }
  439. renderOpts.isRedirect = true;
  440. }
  441. if ((dev || isBuildTimeSSG) && !renderOpts.isNotFound && !(0, _isSerializableProps).isSerializableProps(pathname, "getStaticProps", data.props)) {
  442. // this fn should throw an error instead of ever returning `false`
  443. throw new Error("invariant: getStaticProps did not return valid props. Please report this.");
  444. }
  445. if ("revalidate" in data) {
  446. if (typeof data.revalidate === "number") {
  447. if (!Number.isInteger(data.revalidate)) {
  448. throw new Error(`A page's revalidate option must be seconds expressed as a natural number for ${req.url}. Mixed numbers, such as '${data.revalidate}', cannot be used.` + `\nTry changing the value to '${Math.ceil(data.revalidate)}' or using \`Math.ceil()\` if you're computing the value.`);
  449. } else if (data.revalidate <= 0) {
  450. throw new Error(`A page's revalidate option can not be less than or equal to zero for ${req.url}. A revalidate option of zero means to revalidate after _every_ request, and implies stale data cannot be tolerated.` + `\n\nTo never revalidate, you can set revalidate to \`false\` (only ran once at build-time).` + `\nTo revalidate as soon as possible, you can set the value to \`1\`.`);
  451. } else if (data.revalidate > 31536000) {
  452. // if it's greater than a year for some reason error
  453. console.warn(`Warning: A page's revalidate option was set to more than a year for ${req.url}. This may have been done in error.` + `\nTo only run getStaticProps at build-time and not revalidate at runtime, you can set \`revalidate\` to \`false\`!`);
  454. }
  455. } else if (data.revalidate === true) {
  456. // When enabled, revalidate after 1 second. This value is optimal for
  457. // the most up-to-date page possible, but without a 1-to-1
  458. // request-refresh ratio.
  459. data.revalidate = 1;
  460. } else if (data.revalidate === false || typeof data.revalidate === "undefined") {
  461. // By default, we never revalidate.
  462. data.revalidate = false;
  463. } else {
  464. throw new Error(`A page's revalidate option must be seconds expressed as a natural number. Mixed numbers and strings cannot be used. Received '${JSON.stringify(data.revalidate)}' for ${req.url}`);
  465. }
  466. } else {
  467. data.revalidate = false;
  468. }
  469. props1.pageProps = Object.assign({}, props1.pageProps, "props" in data ? data.props : undefined);
  470. renderOpts.revalidate = "revalidate" in data ? data.revalidate : undefined;
  471. renderOpts.pageData = props1;
  472. // this must come after revalidate is added to renderOpts
  473. if (renderOpts.isNotFound) {
  474. return null;
  475. }
  476. }
  477. if (getServerSideProps) {
  478. props1[_constants1.SERVER_PROPS_ID] = true;
  479. }
  480. if (getServerSideProps && !isFallback) {
  481. let data;
  482. let canAccessRes = true;
  483. let resOrProxy = res;
  484. let deferredContent = false;
  485. if (process.env.NODE_ENV !== "production") {
  486. resOrProxy = new Proxy(res, {
  487. get: function(obj, prop, receiver) {
  488. if (!canAccessRes) {
  489. const message = `You should not access 'res' after getServerSideProps resolves.` + `\nRead more: https://nextjs.org/docs/messages/gssp-no-mutating-res`;
  490. if (deferredContent) {
  491. throw new Error(message);
  492. } else {
  493. warn(message);
  494. }
  495. }
  496. const value = Reflect.get(obj, prop, receiver);
  497. // since ServerResponse uses internal fields which
  498. // proxy can't map correctly we need to ensure functions
  499. // are bound correctly while being proxied
  500. if (typeof value === "function") {
  501. return value.bind(obj);
  502. }
  503. return value;
  504. }
  505. });
  506. }
  507. try {
  508. data = await getServerSideProps({
  509. req: req,
  510. res: resOrProxy,
  511. query,
  512. resolvedUrl: renderOpts.resolvedUrl,
  513. ...pageIsDynamic ? {
  514. params: params
  515. } : undefined,
  516. ...previewData !== false ? {
  517. preview: true,
  518. previewData: previewData
  519. } : undefined,
  520. locales: renderOpts.locales,
  521. locale: renderOpts.locale,
  522. defaultLocale: renderOpts.defaultLocale
  523. });
  524. canAccessRes = false;
  525. } catch (serverSidePropsError) {
  526. // remove not found error code to prevent triggering legacy
  527. // 404 rendering
  528. if ((0, _isError).default(serverSidePropsError) && serverSidePropsError.code === "ENOENT") {
  529. delete serverSidePropsError.code;
  530. }
  531. throw serverSidePropsError;
  532. }
  533. if (data == null) {
  534. throw new Error(_constants.GSSP_NO_RETURNED_VALUE);
  535. }
  536. if (data.props instanceof Promise) {
  537. deferredContent = true;
  538. }
  539. const invalidKeys = Object.keys(data).filter((key)=>key !== "props" && key !== "redirect" && key !== "notFound");
  540. if (data.unstable_notFound) {
  541. throw new Error(`unstable_notFound has been renamed to notFound, please update the field to continue. Page: ${pathname}`);
  542. }
  543. if (data.unstable_redirect) {
  544. throw new Error(`unstable_redirect has been renamed to redirect, please update the field to continue. Page: ${pathname}`);
  545. }
  546. if (invalidKeys.length) {
  547. throw new Error(invalidKeysMsg("getServerSideProps", invalidKeys));
  548. }
  549. if ("notFound" in data && data.notFound) {
  550. if (pathname === "/404") {
  551. throw new Error(`The /404 page can not return notFound in "getStaticProps", please remove it to continue!`);
  552. }
  553. renderOpts.isNotFound = true;
  554. return null;
  555. }
  556. if ("redirect" in data && typeof data.redirect === "object") {
  557. checkRedirectValues(data.redirect, req, "getServerSideProps");
  558. data.props = {
  559. __N_REDIRECT: data.redirect.destination,
  560. __N_REDIRECT_STATUS: (0, _redirectStatus).getRedirectStatus(data.redirect)
  561. };
  562. if (typeof data.redirect.basePath !== "undefined") {
  563. data.props.__N_REDIRECT_BASE_PATH = data.redirect.basePath;
  564. }
  565. renderOpts.isRedirect = true;
  566. }
  567. if (deferredContent) {
  568. data.props = await data.props;
  569. }
  570. if ((dev || isBuildTimeSSG) && !(0, _isSerializableProps).isSerializableProps(pathname, "getServerSideProps", data.props)) {
  571. // this fn should throw an error instead of ever returning `false`
  572. throw new Error("invariant: getServerSideProps did not return valid props. Please report this.");
  573. }
  574. props1.pageProps = Object.assign({}, props1.pageProps, data.props);
  575. renderOpts.pageData = props1;
  576. }
  577. if (!isSSG && !getServerSideProps && process.env.NODE_ENV !== "production" && Object.keys((props1 == null ? void 0 : props1.pageProps) || {}).includes("url")) {
  578. console.warn(`The prop \`url\` is a reserved prop in Next.js for legacy reasons and will be overridden on page ${pathname}\n` + `See more info here: https://nextjs.org/docs/messages/reserved-page-prop`);
  579. }
  580. // Avoid rendering page un-necessarily for getServerSideProps data request
  581. // and getServerSideProps/getStaticProps redirects
  582. if (isDataReq && !isSSG || renderOpts.isRedirect) {
  583. return _renderResult.default.fromStatic(JSON.stringify(props1));
  584. }
  585. // We don't call getStaticProps or getServerSideProps while generating
  586. // the fallback so make sure to set pageProps to an empty object
  587. if (isFallback) {
  588. props1.pageProps = {};
  589. }
  590. // the response might be finished on the getInitialProps call
  591. if ((0, _utils).isResSent(res) && !isSSG) return null;
  592. // we preload the buildManifest for auto-export dynamic pages
  593. // to speed up hydrating query values
  594. let filteredBuildManifest = buildManifest;
  595. if (isAutoExport && pageIsDynamic) {
  596. const page = (0, _denormalizePagePath).denormalizePagePath((0, _normalizePagePath).normalizePagePath(pathname));
  597. // This code would be much cleaner using `immer` and directly pushing into
  598. // the result from `getPageFiles`, we could maybe consider that in the
  599. // future.
  600. if (page in filteredBuildManifest.pages) {
  601. filteredBuildManifest = {
  602. ...filteredBuildManifest,
  603. pages: {
  604. ...filteredBuildManifest.pages,
  605. [page]: [
  606. ...filteredBuildManifest.pages[page],
  607. ...filteredBuildManifest.lowPriorityFiles.filter((f)=>f.includes("_buildManifest")),
  608. ]
  609. },
  610. lowPriorityFiles: filteredBuildManifest.lowPriorityFiles.filter((f)=>!f.includes("_buildManifest"))
  611. };
  612. }
  613. }
  614. const Body = ({ children })=>{
  615. return inAmpMode ? children : /*#__PURE__*/ _react.default.createElement("div", {
  616. id: "__next"
  617. }, children);
  618. };
  619. /**
  620. * Rules of Static & Dynamic HTML:
  621. *
  622. * 1.) We must generate static HTML unless the caller explicitly opts
  623. * in to dynamic HTML support.
  624. *
  625. * 2.) If dynamic HTML support is requested, we must honor that request
  626. * or throw an error. It is the sole responsibility of the caller to
  627. * ensure they aren't e.g. requesting dynamic HTML for an AMP page.
  628. *
  629. * These rules help ensure that other existing features like request caching,
  630. * coalescing, and ISR continue working as intended.
  631. */ const generateStaticHTML = supportsDynamicHTML !== true;
  632. const renderDocument = async ()=>{
  633. // For `Document`, there are two cases that we don't support:
  634. // 1. Using `Document.getInitialProps` in the Edge runtime.
  635. // 2. Using the class component `Document` with concurrent features.
  636. const BuiltinFunctionalDocument = Document[_constants1.NEXT_BUILTIN_DOCUMENT];
  637. if (process.env.NEXT_RUNTIME === "edge" && Document.getInitialProps) {
  638. // In the Edge runtime, `Document.getInitialProps` isn't supported.
  639. // We throw an error here if it's customized.
  640. if (!BuiltinFunctionalDocument) {
  641. throw new Error("`getInitialProps` in Document component is not supported with the Edge Runtime.");
  642. }
  643. }
  644. if (process.env.NEXT_RUNTIME === "edge" && Document.getInitialProps) {
  645. if (BuiltinFunctionalDocument) {
  646. Document = BuiltinFunctionalDocument;
  647. } else {
  648. throw new Error("`getInitialProps` in Document component is not supported with React Server Components.");
  649. }
  650. }
  651. async function loadDocumentInitialProps(renderShell) {
  652. const renderPage = (options = {})=>{
  653. if (ctx.err && ErrorDebug) {
  654. // Always start rendering the shell even if there's an error.
  655. if (renderShell) {
  656. renderShell(App, Component);
  657. }
  658. const html = ReactDOMServer.renderToString(/*#__PURE__*/ _react.default.createElement(Body, null, /*#__PURE__*/ _react.default.createElement(ErrorDebug, {
  659. error: ctx.err
  660. })));
  661. return {
  662. html,
  663. head
  664. };
  665. }
  666. if (dev && (props1.router || props1.Component)) {
  667. throw new Error(`'router' and 'Component' can not be returned in getInitialProps from _app.js https://nextjs.org/docs/messages/cant-override-next-props`);
  668. }
  669. const { App: EnhancedApp , Component: EnhancedComponent } = enhanceComponents(options, App, Component);
  670. if (renderShell) {
  671. return renderShell(EnhancedApp, EnhancedComponent).then(async (stream)=>{
  672. const forwardStream = (0, _nodeWebStreamsHelper).readableStreamTee(stream)[1];
  673. const html = await (0, _nodeWebStreamsHelper).streamToString(forwardStream);
  674. return {
  675. html,
  676. head
  677. };
  678. });
  679. }
  680. const html1 = ReactDOMServer.renderToString(/*#__PURE__*/ _react.default.createElement(Body, null, /*#__PURE__*/ _react.default.createElement(AppContainerWithIsomorphicFiberStructure, null, renderPageTree(EnhancedApp, EnhancedComponent, {
  681. ...props1,
  682. router
  683. }))));
  684. return {
  685. html: html1,
  686. head
  687. };
  688. };
  689. const documentCtx = {
  690. ...ctx,
  691. renderPage
  692. };
  693. const docProps = await (0, _utils).loadGetInitialProps(Document, documentCtx);
  694. // the response might be finished on the getInitialProps call
  695. if ((0, _utils).isResSent(res) && !isSSG) return null;
  696. if (!docProps || typeof docProps.html !== "string") {
  697. const message = `"${(0, _utils).getDisplayName(Document)}.getInitialProps()" should resolve to an object with a "html" prop set with a valid html string`;
  698. throw new Error(message);
  699. }
  700. return {
  701. docProps,
  702. documentCtx
  703. };
  704. }
  705. const renderContent = (_App, _Component)=>{
  706. const EnhancedApp = _App || App;
  707. const EnhancedComponent = _Component || Component;
  708. return ctx.err && ErrorDebug ? /*#__PURE__*/ _react.default.createElement(Body, null, /*#__PURE__*/ _react.default.createElement(ErrorDebug, {
  709. error: ctx.err
  710. })) : /*#__PURE__*/ _react.default.createElement(Body, null, /*#__PURE__*/ _react.default.createElement(AppContainerWithIsomorphicFiberStructure, null, renderPageTree(EnhancedApp, EnhancedComponent, {
  711. ...props1,
  712. router
  713. })));
  714. };
  715. if (!process.env.__NEXT_REACT_ROOT) {
  716. // Enabling react legacy rendering mode: __NEXT_REACT_ROOT = false
  717. if (Document.getInitialProps) {
  718. const documentInitialProps = await loadDocumentInitialProps();
  719. if (documentInitialProps === null) return null;
  720. const { docProps , documentCtx } = documentInitialProps;
  721. return {
  722. bodyResult: (suffix)=>(0, _nodeWebStreamsHelper).streamFromArray([
  723. docProps.html,
  724. suffix
  725. ]),
  726. documentElement: (htmlProps)=>/*#__PURE__*/ _react.default.createElement(Document, Object.assign({}, htmlProps, docProps)),
  727. head: docProps.head,
  728. headTags: await headTags(documentCtx),
  729. styles: docProps.styles
  730. };
  731. } else {
  732. const content = renderContent(App, Component);
  733. // for non-concurrent rendering we need to ensure App is rendered
  734. // before _document so that updateHead is called/collected before
  735. // rendering _document's head
  736. const result = ReactDOMServer.renderToString(content);
  737. const bodyResult = (suffix)=>(0, _nodeWebStreamsHelper).streamFromArray([
  738. result,
  739. suffix
  740. ]);
  741. const styles = jsxStyleRegistry.styles();
  742. jsxStyleRegistry.flush();
  743. return {
  744. bodyResult,
  745. documentElement: ()=>Document(),
  746. head,
  747. headTags: [],
  748. styles
  749. };
  750. }
  751. } else {
  752. // Enabling react concurrent rendering mode: __NEXT_REACT_ROOT = true
  753. const renderShell = async (EnhancedApp, EnhancedComponent)=>{
  754. const content = renderContent(EnhancedApp, EnhancedComponent);
  755. return await (0, _nodeWebStreamsHelper).renderToInitialStream({
  756. ReactDOMServer,
  757. element: content
  758. });
  759. };
  760. const createBodyResult = (initialStream, suffix)=>{
  761. // this must be called inside bodyResult so appWrappers is
  762. // up to date when `wrapApp` is called
  763. const flushEffectHandler = ()=>{
  764. const flushed = ReactDOMServer.renderToString(styledJsxFlushEffect());
  765. return flushed;
  766. };
  767. return (0, _nodeWebStreamsHelper).continueFromInitialStream(initialStream, {
  768. suffix,
  769. dataStream: serverComponentsInlinedTransformStream == null ? void 0 : serverComponentsInlinedTransformStream.readable,
  770. generateStaticHTML,
  771. flushEffectHandler,
  772. flushEffectsToHead: false
  773. });
  774. };
  775. const hasDocumentGetInitialProps = !(process.env.NEXT_RUNTIME === "edge" || !Document.getInitialProps);
  776. let bodyResult;
  777. // If it has getInitialProps, we will render the shell in `renderPage`.
  778. // Otherwise we do it right now.
  779. let documentInitialPropsRes;
  780. if (hasDocumentGetInitialProps) {
  781. documentInitialPropsRes = await loadDocumentInitialProps(renderShell);
  782. if (documentInitialPropsRes === null) return null;
  783. const { docProps } = documentInitialPropsRes;
  784. // includes suffix in initial html stream
  785. bodyResult = (suffix)=>createBodyResult((0, _nodeWebStreamsHelper).streamFromArray([
  786. docProps.html,
  787. suffix
  788. ]));
  789. } else {
  790. const stream = await renderShell(App, Component);
  791. bodyResult = (suffix)=>createBodyResult(stream, suffix);
  792. documentInitialPropsRes = {};
  793. }
  794. const { docProps } = documentInitialPropsRes || {};
  795. const documentElement = (htmlProps)=>{
  796. if (process.env.NEXT_RUNTIME === "edge") {
  797. return Document();
  798. } else {
  799. return /*#__PURE__*/ _react.default.createElement(Document, Object.assign({}, htmlProps, docProps));
  800. }
  801. };
  802. let styles;
  803. if (hasDocumentGetInitialProps) {
  804. styles = docProps.styles;
  805. head = docProps.head;
  806. } else {
  807. styles = jsxStyleRegistry.styles();
  808. jsxStyleRegistry.flush();
  809. }
  810. return {
  811. bodyResult,
  812. documentElement,
  813. head,
  814. headTags: [],
  815. styles
  816. };
  817. }
  818. };
  819. const documentResult = await renderDocument();
  820. if (!documentResult) {
  821. return null;
  822. }
  823. const dynamicImportsIds = new Set();
  824. const dynamicImports = new Set();
  825. for (const mod of reactLoadableModules){
  826. const manifestItem = reactLoadableManifest[mod];
  827. if (manifestItem) {
  828. dynamicImportsIds.add(manifestItem.id);
  829. manifestItem.files.forEach((item)=>{
  830. dynamicImports.add(item);
  831. });
  832. }
  833. }
  834. const hybridAmp = ampState.hybrid;
  835. const docComponentsRendered = {};
  836. const { assetPrefix , buildId , customServer , defaultLocale , disableOptimizedLoading , domainLocales , locale , locales , runtimeConfig , } = renderOpts;
  837. const htmlProps1 = {
  838. __NEXT_DATA__: {
  839. props: props1,
  840. page: pathname,
  841. query,
  842. buildId,
  843. assetPrefix: assetPrefix === "" ? undefined : assetPrefix,
  844. runtimeConfig,
  845. nextExport: nextExport === true ? true : undefined,
  846. autoExport: isAutoExport === true ? true : undefined,
  847. isFallback,
  848. dynamicIds: dynamicImportsIds.size === 0 ? undefined : Array.from(dynamicImportsIds),
  849. err: renderOpts.err ? serializeError(dev, renderOpts.err) : undefined,
  850. gsp: !!getStaticProps ? true : undefined,
  851. gssp: !!getServerSideProps ? true : undefined,
  852. customServer,
  853. gip: hasPageGetInitialProps ? true : undefined,
  854. appGip: !defaultAppGetInitialProps ? true : undefined,
  855. locale,
  856. locales,
  857. defaultLocale,
  858. domainLocales,
  859. isPreview: isPreview === true ? true : undefined,
  860. notFoundSrcPage: notFoundSrcPage && dev ? notFoundSrcPage : undefined
  861. },
  862. buildManifest: filteredBuildManifest,
  863. docComponentsRendered,
  864. dangerousAsPath: router.asPath,
  865. canonicalBase: !renderOpts.ampPath && (0, _requestMeta).getRequestMeta(req, "__nextStrippedLocale") ? `${renderOpts.canonicalBase || ""}/${renderOpts.locale}` : renderOpts.canonicalBase,
  866. ampPath,
  867. inAmpMode,
  868. isDevelopment: !!dev,
  869. hybridAmp,
  870. dynamicImports: Array.from(dynamicImports),
  871. assetPrefix,
  872. // Only enabled in production as development mode has features relying on HMR (style injection for example)
  873. unstable_runtimeJS: process.env.NODE_ENV === "production" ? pageConfig.unstable_runtimeJS : undefined,
  874. unstable_JsPreload: pageConfig.unstable_JsPreload,
  875. devOnlyCacheBusterQueryString,
  876. scriptLoader,
  877. locale,
  878. disableOptimizedLoading,
  879. head: documentResult.head,
  880. headTags: documentResult.headTags,
  881. styles: documentResult.styles,
  882. crossOrigin: renderOpts.crossOrigin,
  883. optimizeCss: renderOpts.optimizeCss,
  884. optimizeFonts: renderOpts.optimizeFonts,
  885. nextScriptWorkers: renderOpts.nextScriptWorkers,
  886. runtime: globalRuntime,
  887. largePageDataBytes: renderOpts.largePageDataBytes
  888. };
  889. const document = /*#__PURE__*/ _react.default.createElement(_ampContext.AmpStateContext.Provider, {
  890. value: ampState
  891. }, /*#__PURE__*/ _react.default.createElement(_htmlContext.HtmlContext.Provider, {
  892. value: htmlProps1
  893. }, documentResult.documentElement(htmlProps1)));
  894. const documentHTML = ReactDOMServer.renderToStaticMarkup(document);
  895. if (process.env.NODE_ENV !== "production") {
  896. const nonRenderedComponents = [];
  897. const expectedDocComponents = [
  898. "Main",
  899. "Head",
  900. "NextScript",
  901. "Html"
  902. ];
  903. for (const comp of expectedDocComponents){
  904. if (!docComponentsRendered[comp]) {
  905. nonRenderedComponents.push(comp);
  906. }
  907. }
  908. if (nonRenderedComponents.length) {
  909. const missingComponentList = nonRenderedComponents.map((e)=>`<${e} />`).join(", ");
  910. const plural = nonRenderedComponents.length !== 1 ? "s" : "";
  911. console.warn(`Your custom Document (pages/_document) did not render all the required subcomponent${plural}.\n` + `Missing component${plural}: ${missingComponentList}\n` + "Read how to fix here: https://nextjs.org/docs/messages/missing-document-component");
  912. }
  913. }
  914. const [renderTargetPrefix, renderTargetSuffix] = documentHTML.split("<next-js-internal-body-render-target></next-js-internal-body-render-target>");
  915. const prefix = [];
  916. if (!documentHTML.startsWith(DOCTYPE)) {
  917. prefix.push(DOCTYPE);
  918. }
  919. prefix.push(renderTargetPrefix);
  920. if (inAmpMode) {
  921. prefix.push("<!-- __NEXT_DATA__ -->");
  922. }
  923. const streams = [
  924. (0, _nodeWebStreamsHelper).streamFromArray(prefix),
  925. await documentResult.bodyResult(renderTargetSuffix),
  926. ];
  927. const postOptimize = (html)=>postProcessHTML(pathname, html, renderOpts, {
  928. inAmpMode,
  929. hybridAmp
  930. });
  931. if (generateStaticHTML) {
  932. const html = await (0, _nodeWebStreamsHelper).streamToString((0, _nodeWebStreamsHelper).chainStreams(streams));
  933. const optimizedHtml = await postOptimize(html);
  934. return new _renderResult.default(optimizedHtml);
  935. }
  936. return new _renderResult.default((0, _nodeWebStreamsHelper).chainStreams(streams).pipeThrough((0, _nodeWebStreamsHelper).createBufferedTransformStream(postOptimize)));
  937. }
  938. //# sourceMappingURL=render.js.map