11import path from "node:path" ;
22
3+ import type { RouteDefinition } from "types/next-types" ;
34import { debug } from "../logger" ;
45import {
56 loadAppPathRoutesManifest ,
@@ -11,6 +12,7 @@ import {
1112 loadFunctionsConfigManifest ,
1213 loadHtmlPages ,
1314 loadMiddlewareManifest ,
15+ loadPagesManifest ,
1416 loadPrerenderManifest ,
1517 loadRoutesManifest ,
1618} from "./util.js" ;
@@ -39,3 +41,38 @@ export const AppPathRoutesManifest =
3941
4042export const FunctionsConfigManifest =
4143 /* @__PURE__ */ loadFunctionsConfigManifest ( NEXT_DIR ) ;
44+
45+ /**
46+ * Returns static API routes for both app and pages router cause Next will filter them out in staticRoutes in `routes-manifest.json`.
47+ * We also need to filter out page files that are under `app/api/*` as those would not be present in the routes manifest either.
48+ * This line from Next.js skips it:
49+ * https://github.com/vercel/next.js/blob/ded56f952154a40dcfe53bdb38c73174e9eca9e5/packages/next/src/build/index.ts#L1299
50+ *
51+ * Without it handleFallbackFalse will 404 on static API routes if there is a catch-all route on root level.
52+ */
53+ export function getStaticAPIRoutes ( ) : RouteDefinition [ ] {
54+ const createRouteDefinition = ( route : string ) => ( {
55+ page : route ,
56+ regex : `^${ route } (?:/)?$` ,
57+ } ) ;
58+ const dynamicRoutePages = new Set (
59+ RoutesManifest . routes . dynamic . map ( ( { page } ) => page ) ,
60+ ) ;
61+ const PagesManifest = loadPagesManifest ( NEXT_DIR ) ;
62+ const pagesStaticAPIRoutes = Object . keys ( PagesManifest )
63+ . filter (
64+ ( route ) => route . startsWith ( "/api/" ) && ! dynamicRoutePages . has ( route ) ,
65+ )
66+ . map ( createRouteDefinition ) ;
67+
68+ // We filter out both static API and page routes from the app paths manifest
69+ const appPathsStaticAPIRoutes = Object . values ( AppPathRoutesManifest )
70+ . filter (
71+ ( route ) =>
72+ route . startsWith ( "/api/" ) ||
73+ ( route === "/api" && ! dynamicRoutePages . has ( route ) ) ,
74+ )
75+ . map ( createRouteDefinition ) ;
76+
77+ return [ ...pagesStaticAPIRoutes , ...appPathsStaticAPIRoutes ] ;
78+ }
0 commit comments