Skip to content
Draft
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion packages/vinext/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3044,6 +3044,7 @@ hydrate();
) {
const apiRoutes = await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
const handled = await handleApiRoute(
getPagesRunner(),
server,
req,
res,
Expand Down Expand Up @@ -3082,7 +3083,7 @@ hydrate();
return;
}

const handler = createSSRHandler(server, routes, pagesDir, nextConfig?.i18n, fileMatcher);
const handler = createSSRHandler(getPagesRunner(), server, routes, pagesDir, nextConfig?.i18n, fileMatcher);
const mwStatus = (req as any).__vinextRewriteStatus as number | undefined;

// Try rendering the resolved URL
Expand Down
6 changes: 4 additions & 2 deletions packages/vinext/src/server/api-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Next.js extensions: req.query, req.body, res.json(), res.status(), etc.
*/
import type { ViteDevServer } from "vite";
import type { ModuleRunner } from "vite/module-runner";
import type { IncomingMessage, ServerResponse } from "node:http";
import { type Route, matchRoute } from "../routing/pages-router.js";
import { reportRequestError } from "./instrumentation.js";
Expand Down Expand Up @@ -163,6 +164,7 @@ function enhanceApiObjects(
* Returns true if the request was handled, false if no API route matched.
*/
export async function handleApiRoute(
runner: ModuleRunner,
server: ViteDevServer,
req: IncomingMessage,
res: ServerResponse,
Expand All @@ -176,7 +178,7 @@ export async function handleApiRoute(

try {
// Load the API route module through Vite
const apiModule = await server.ssrLoadModule(route.filePath);
const apiModule = await runner.import(route.filePath);
const handler = apiModule.default;

if (typeof handler !== "function") {
Expand Down Expand Up @@ -206,7 +208,7 @@ export async function handleApiRoute(
await handler(apiReq, apiRes);
return true;
} catch (e) {
server.ssrFixStacktrace(e as Error);
server.ssrFixStacktrace?.(e as Error);
console.error(e);
reportRequestError(
e instanceof Error ? e : new Error(String(e)),
Expand Down
43 changes: 23 additions & 20 deletions packages/vinext/src/server/dev-server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ViteDevServer } from "vite";
import type { ModuleRunner } from "vite/module-runner";
import type { IncomingMessage, ServerResponse } from "node:http";
import type { Route } from "../routing/pages-router.js";
import { matchRoute, patternToNextFormat } from "../routing/pages-router.js";
Expand Down Expand Up @@ -64,7 +65,7 @@ async function streamPageToResponse(
element: React.ReactElement,
options: {
url: string;
server: ViteDevServer;
server: ViteDevServer; // needed only for transformIndexHtml
fontHeadHTML: string;
scripts: string;
DocumentComponent: React.ComponentType | null;
Expand Down Expand Up @@ -272,6 +273,7 @@ export function parseCookieLocale(
* 5. Wrap in _document shell and send response
*/
export function createSSRHandler(
runner: ModuleRunner,
server: ViteDevServer,
routes: Route[],
pagesDir: string,
Expand Down Expand Up @@ -344,7 +346,7 @@ export function createSSRHandler(

if (!match) {
// No route matched — try to render custom 404 page
await renderErrorPage(server, req, res, url, pagesDir, 404, undefined, matcher);
await renderErrorPage(runner, server, req, res, url, pagesDir, 404, undefined, matcher);
return;
}

Expand All @@ -360,7 +362,7 @@ export function createSSRHandler(
try {
// Set SSR context for the router shim so useRouter() returns
// the correct URL and params during server-side rendering.
const routerShim = await server.ssrLoadModule("next/router");
const routerShim = await runner.import("next/router");
if (typeof routerShim.setSSRContext === "function") {
routerShim.setSSRContext({
pathname: localeStrippedUrl.split("?")[0],
Expand All @@ -381,7 +383,7 @@ export function createSSRHandler(

// Load the page module through Vite's SSR pipeline
// This gives us HMR and transform support for free
const pageModule = await server.ssrLoadModule(route.filePath);
const pageModule = await runner.import(route.filePath);
// Mark end of compile phase: everything from here is rendering.
_compileEnd = now();

Expand Down Expand Up @@ -422,7 +424,7 @@ export function createSSRHandler(
});

if (!isValidPath) {
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, matcher);
await renderErrorPage(runner, server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext as ((el: React.ReactElement) => React.ReactElement) | undefined, matcher);
return;
}
}
Expand Down Expand Up @@ -483,7 +485,7 @@ export function createSSRHandler(
return;
}
if (result && "notFound" in result && result.notFound) {
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
await renderErrorPage(runner, server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext as ((el: React.ReactElement) => React.ReactElement) | undefined);
return;
}
// Preserve any status code set by gSSP (e.g. res.statusCode = 201).
Expand Down Expand Up @@ -511,11 +513,11 @@ export function createSSRHandler(
let earlyFontLinkHeader = "";
try {
const earlyPreloads: Array<{ href: string; type: string }> = [];
const fontGoogleEarly = await server.ssrLoadModule("next/font/google");
const fontGoogleEarly = await runner.import("next/font/google");
if (typeof fontGoogleEarly.getSSRFontPreloads === "function") {
earlyPreloads.push(...fontGoogleEarly.getSSRFontPreloads());
}
const fontLocalEarly = await server.ssrLoadModule("next/font/local");
const fontLocalEarly = await runner.import("next/font/local");
if (typeof fontLocalEarly.getSSRFontPreloads === "function") {
earlyPreloads.push(...fontLocalEarly.getSSRFontPreloads());
}
Expand Down Expand Up @@ -607,7 +609,7 @@ export function createSSRHandler(
return;
}
if (result && "notFound" in result && result.notFound) {
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
await renderErrorPage(runner, server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext as ((el: React.ReactElement) => React.ReactElement) | undefined);
return;
}

Expand All @@ -623,7 +625,7 @@ export function createSSRHandler(
const appPath = path.join(pagesDir, "_app");
if (findFileWithExtensions(appPath, matcher)) {
try {
const appModule = await server.ssrLoadModule(appPath);
const appModule = await runner.import(appPath);
AppComponent = appModule.default ?? null;
} catch {
// _app exists but failed to load
Expand Down Expand Up @@ -654,13 +656,13 @@ export function createSSRHandler(
}

// Reset SSR head collector before rendering so <Head> tags are captured
const headShim = await server.ssrLoadModule("next/head");
const headShim = await runner.import("next/head");
if (typeof headShim.resetSSRHead === "function") {
headShim.resetSSRHead();
}

// Flush any pending dynamic() preloads so components are ready
const dynamicShim = await server.ssrLoadModule("next/dynamic");
const dynamicShim = await runner.import("next/dynamic");
if (typeof dynamicShim.flushPreloads === "function") {
await dynamicShim.flushPreloads();
}
Expand All @@ -674,7 +676,7 @@ export function createSSRHandler(
const allFontStyles: string[] = [];
const allFontPreloads: Array<{ href: string; type: string }> = [];
try {
const fontGoogle = await server.ssrLoadModule("next/font/google");
const fontGoogle = await runner.import("next/font/google");
if (typeof fontGoogle.getSSRFontLinks === "function") {
const fontUrls = fontGoogle.getSSRFontLinks();
for (const fontUrl of fontUrls) {
Expand All @@ -693,7 +695,7 @@ export function createSSRHandler(
// next/font/google not used — skip
}
try {
const fontLocal = await server.ssrLoadModule("next/font/local");
const fontLocal = await runner.import("next/font/local");
if (typeof fontLocal.getSSRFontStyles === "function") {
allFontStyles.push(...fontLocal.getSSRFontStyles());
}
Expand Down Expand Up @@ -777,7 +779,7 @@ hydrate();
let DocumentComponent: any = null;
if (findFileWithExtensions(docPath, matcher)) {
try {
const docModule = await server.ssrLoadModule(docPath);
const docModule = await runner.import(docPath);
DocumentComponent = docModule.default ?? null;
} catch {
// _document exists but failed to load
Expand Down Expand Up @@ -865,7 +867,7 @@ hydrate();
).catch(() => { /* ignore reporting errors */ });
// Try to render custom 500 error page
try {
await renderErrorPage(server, req, res, url, pagesDir, 500, undefined, matcher);
await renderErrorPage(runner, server, req, res, url, pagesDir, 500, undefined, matcher);
} catch (fallbackErr) {
// If error page itself fails, fall back to plain text.
// This is a dev-only code path (prod uses prod-server.ts), so
Expand Down Expand Up @@ -894,6 +896,7 @@ hydrate();
* - other: pages/_error.tsx -> default
*/
async function renderErrorPage(
runner: ModuleRunner,
server: ViteDevServer,
_req: IncomingMessage,
res: ServerResponse,
Expand All @@ -917,7 +920,7 @@ async function renderErrorPage(
const candidatePath = path.join(pagesDir, candidate);
if (!findFileWithExtensions(candidatePath, matcher)) continue;

const errorModule = await server.ssrLoadModule(candidatePath);
const errorModule = await runner.import(candidatePath);
const ErrorComponent = errorModule.default;
if (!ErrorComponent) continue;

Expand All @@ -926,7 +929,7 @@ async function renderErrorPage(
const appPathErr = path.join(pagesDir, "_app");
if (findFileWithExtensions(appPathErr, matcher)) {
try {
const appModule = await server.ssrLoadModule(appPathErr);
const appModule = await runner.import(appPathErr);
AppComponent = appModule.default ?? null;
} catch {
// _app exists but failed to load
Expand All @@ -941,7 +944,7 @@ async function renderErrorPage(
let wrapFn = wrapWithRouterContext;
if (!wrapFn) {
try {
const errRouterShim = await server.ssrLoadModule("next/router");
const errRouterShim = await runner.import("next/router");
wrapFn = errRouterShim.wrapWithRouterContext;
} catch {
// router shim not available — continue without it
Expand Down Expand Up @@ -970,7 +973,7 @@ async function renderErrorPage(
const docPathErr = path.join(pagesDir, "_document");
if (findFileWithExtensions(docPathErr, matcher)) {
try {
const docModule = await server.ssrLoadModule(docPathErr);
const docModule = await runner.import(docPathErr);
DocumentComponent = docModule.default ?? null;
} catch {
// _document exists but failed to load
Expand Down
Loading
Loading