diff --git a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts index beefd6dcb861411..8fa95529ea3a2ec 100644 --- a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts +++ b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts @@ -4,7 +4,6 @@ import type { BuildManifest } from '../../../../server/get-page-files' import type { ReactLoadableManifest } from '../../../../server/load-components' import { NextRequest } from '../../../../server/web/spec-extension/request' -import { toNodeHeaders } from '../../../../server/web/utils' import WebServer from '../../../../server/web-server' import { @@ -12,20 +11,6 @@ import { WebNextResponse, } from '../../../../server/base-http/web' -const createHeaders = (args?: any) => ({ - ...args, - 'x-middleware-ssr': '1', - 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', -}) - -function sendError(req: any, error: Error) { - const defaultMessage = 'An error occurred while rendering ' + req.url + '.' - return new Response((error && error.message) || defaultMessage, { - status: 500, - headers: createHeaders(), - }) -} - // Polyfilled for `path-browserify` inside the Web Server. process.cwd = () => '' @@ -123,31 +108,20 @@ export function getRender({ const requestHandler = server.getRequestHandler() return async function render(request: NextRequest) { - const { nextUrl: url, cookies, headers } = request - const { pathname, searchParams } = url - + const { nextUrl: url } = request + const { searchParams } = url const query = Object.fromEntries(searchParams) - const req = { - url: pathname, - cookies, - headers: toNodeHeaders(headers), - } // Preflight request if (request.method === 'HEAD') { + // Hint the client that the matched route is a SSR page. return new Response(null, { - headers: createHeaders(), + headers: { + 'x-middleware-ssr': '1', + }, }) } - // @TODO: We should move this into server/render. - if (Document.getInitialProps) { - const err = new Error( - '`getInitialProps` in Document component is not supported with the Edge Runtime.' - ) - return sendError(req, err) - } - const renderServerComponentData = isServerComponent ? query.__flight__ !== undefined : false diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index 92847d189629c92..0c6454f8072bc64 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -336,6 +336,8 @@ export default class HotReloader { ) ) + const hasEdgeRuntimePages = this.runtime === 'edge' + return webpackConfigSpan .traceChild('generate-webpack-config') .traceAsyncFn(() => @@ -363,7 +365,7 @@ export default class HotReloader { }), // For the edge runtime, we need an extra compiler to generate the // web-targeted server bundle for now. - this.runtime === 'edge' + hasEdgeRuntimePages ? getBaseWebpackConfig(this.dir, { dev: true, isServer: true, diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index c5be24e7da9c543..e4f121fdcd6148c 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -1,10 +1,29 @@ -import { IncomingMessage, ServerResponse } from 'http' -import { ParsedUrlQuery, stringify as stringifyQuery } from 'querystring' +import type { IncomingMessage, ServerResponse } from 'http' +import type { NextRouter } from '../shared/lib/router/router' +import type { HtmlProps } from '../shared/lib/html-context' +import type { DomainLocale } from './config' +import type { + AppType, + DocumentInitialProps, + DocumentProps, + DocumentContext, + NextComponentType, + RenderPage, + RenderPageResult, +} from '../shared/lib/utils' +import type { ImageConfigComplete } from './image-config' +import type { Redirect } from '../lib/load-custom-routes' +import type { NextApiRequestCookies, __ApiPreviewProps } from './api-utils' +import type { FontManifest } from './font-utils' +import type { LoadComponentsReturnType, ManifestItem } from './load-components' +import type { GetServerSideProps, GetStaticProps, PreviewData } from '../types' +import type { UnwrapPromise } from '../lib/coalesced-function' + import React from 'react' +import { ParsedUrlQuery, stringify as stringifyQuery } from 'querystring' import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-webpack' import { renderToReadableStream } from 'next/dist/compiled/react-server-dom-webpack/writer.browser.server' import { StyleRegistry, createStyleRegistry } from 'styled-jsx' -import { UnwrapPromise } from '../lib/coalesced-function' import { GSP_NO_RETURNED_VALUE, GSSP_COMPONENT_MEMBER_ERROR, @@ -15,56 +34,38 @@ import { SSG_GET_INITIAL_PROPS_CONFLICT, UNSTABLE_REVALIDATE_RENAME_ERROR, } from '../lib/constants' -import { isSerializableProps } from '../lib/is-serializable-props' -import { GetServerSideProps, GetStaticProps, PreviewData } from '../types' -import { isInAmpMode } from '../shared/lib/amp' -import { AmpStateContext } from '../shared/lib/amp-context' import { SERVER_PROPS_ID, STATIC_PROPS_ID, STATIC_STATUS_PAGES, } from '../shared/lib/constants' +import { isSerializableProps } from '../lib/is-serializable-props' +import { isInAmpMode } from '../shared/lib/amp' +import { AmpStateContext } from '../shared/lib/amp-context' import { defaultHead } from '../shared/lib/head' import { HeadManagerContext } from '../shared/lib/head-manager-context' import Loadable from '../shared/lib/loadable' import { LoadableContext } from '../shared/lib/loadable-context' import { RouterContext } from '../shared/lib/router-context' -import { NextRouter } from '../shared/lib/router/router' import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic' import { - AppType, ComponentsEnhancer, - DocumentInitialProps, - DocumentProps, - DocumentContext, getDisplayName, isResSent, loadGetInitialProps, - NextComponentType, - RenderPage, - RenderPageResult, } from '../shared/lib/utils' - import { HtmlContext } from '../shared/lib/html-context' -import type { HtmlProps } from '../shared/lib/html-context' - -import type { NextApiRequestCookies, __ApiPreviewProps } from './api-utils' import { denormalizePagePath } from './denormalize-page-path' -import type { FontManifest } from './font-utils' -import type { LoadComponentsReturnType, ManifestItem } from './load-components' import { normalizePagePath } from './normalize-page-path' import { getRequestMeta, NextParsedUrlQuery } from './request-meta' import { allowedStatusCodes, getRedirectStatus, - Redirect, } from '../lib/load-custom-routes' -import { DomainLocale } from './config' import RenderResult from './render-result' import isError from '../lib/is-error' import { readableStreamTee } from './web/utils' import { ImageConfigContext } from '../shared/lib/image-config-context' -import { ImageConfigComplete } from './image-config' import { FlushEffectsContext } from '../shared/lib/flush-effects' let optimizeAmp: typeof import('./optimize-amp').default @@ -1248,6 +1249,13 @@ export async function renderToHTML( */ const generateStaticHTML = supportsDynamicHTML !== true const renderDocument = async () => { + if (runtime === 'edge' && Document.getInitialProps) { + // In the Edge runtime, Document.getInitialProps isn't supported. + throw new Error( + '`getInitialProps` in Document component is not supported with the Edge Runtime.' + ) + } + if (!runtime && Document.getInitialProps) { const renderPage: RenderPage = ( options: ComponentsEnhancer = {} diff --git a/test/integration/react-streaming-and-server-components/test/index.test.js b/test/integration/react-streaming-and-server-components/test/index.test.js index 8f8e7e0fb805ffc..826ca4d5d1428a5 100644 --- a/test/integration/react-streaming-and-server-components/test/index.test.js +++ b/test/integration/react-streaming-and-server-components/test/index.test.js @@ -247,12 +247,7 @@ const documentSuite = { runTests: (context) => { it('should error when custom _document has getInitialProps method', async () => { const res = await fetchViaHTTP(context.appPort, '/') - const html = await res.text() - expect(res.status).toBe(500) - expect(html).toContain( - '`getInitialProps` in Document component is not supported with the Edge Runtime.' - ) }) }, beforeAll: () => documentPage.write(documentWithGip),