Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 46 additions & 17 deletions crates/next-core/js/src/internal/page-server-handler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
import { renderToHTML, RenderOpts } from "next/dist/server/render";
import { getRedirectStatus } from "next/dist/lib/redirect-status";
import { PERMANENT_REDIRECT_STATUS } from "next/dist/shared/lib/constants";
import { buildStaticPaths } from "next/dist/build/utils";
import type { BuildManifest } from "next/dist/server/get-page-files";
import type { ReactLoadableManifest } from "next/dist/server/load-components";

Expand Down Expand Up @@ -79,6 +80,30 @@ export default function startHandler({
async function runOperation(
renderData: RenderData
): Promise<IpcOutgoingMessage> {
if ("getStaticPaths" in otherExports) {
const {
paths: prerenderRoutes,
fallback: prerenderFallback,
encodedPaths: _encodedPrerenderRoutes,
} = await buildStaticPaths({
page: renderData.path,
getStaticPaths: otherExports.getStaticPaths,
// TODO(alexkirsz) Provide the correct next.config.js path.
configFileName: "next.config.js",
});

// We provide a dummy base URL to the URL constructor so that it doesn't
// throw when we pass a relative URL.
const resolvedPath = new URL(renderData.url, "next://").pathname;
if (
prerenderFallback === false &&
// TODO(alexkirsz) Strip basePath.
!prerenderRoutes.includes(resolvedPath)
) {
return createNotFoundResponse(isDataReq);
}
}

// TODO(alexkirsz) This is missing *a lot* of data, but it's enough to get a
// basic render working.

Expand Down Expand Up @@ -203,23 +228,7 @@ export default function startHandler({
const isNotFound = (renderOpts as any).isNotFound;

if (isNotFound) {
if (isDataReq) {
return {
type: "response",
// Returning a 404 status code is required for the client-side router
// to redirect to the error page.
statusCode: 404,
body: '{"notFound":true}',
headers: [["Content-Type", MIME_APPLICATION_JAVASCRIPT]],
};
}

return {
type: "rewrite",
// _next/404 is a Turbopack-internal route that will always redirect to
// the 404 page.
path: "/_next/404",
};
return createNotFoundResponse(isDataReq);
}

// Set when `getStaticProps` returns `redirect: { destination, permanent, statusCode }`.
Expand Down Expand Up @@ -290,6 +299,26 @@ export default function startHandler({
}
}

function createNotFoundResponse(isDataReq: boolean): IpcOutgoingMessage {
if (isDataReq) {
return {
type: "response",
// Returning a 404 status code is required for the client-side router
// to redirect to the error page.
statusCode: 404,
body: '{"notFound":true}',
headers: [["Content-Type", MIME_APPLICATION_JAVASCRIPT]],
};
}

return {
type: "rewrite",
// /_next/404 is a Turbopack-internal route that will always redirect to
// the 404 page.
path: "/_next/404",
};
}

type ManifestItem = {
id: string;
chunks: string[];
Expand Down