Skip to content

Commit ede17a1

Browse files
authored
On NextJS deploy check if not-found is static (#6558)
1 parent 9f5d1ce commit ede17a1

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
- Added the ability to deploy Angular apps using [the new application-builder](https://angular.dev/tools/cli/esbuild). (#6480)
22
- Fixed an issue where `--non-interactive` flag is not respected in Firestore indexes deploys. (#6539)
33
- Fixed an issue where `login:use` would not work outside of a Firebase project directory. (#6526)
4+
- Prevent app router static `not-found` requiring a Cloud Function in Next.js deployments. (#6558)

src/frameworks/next/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
getHeadersFromMetaFiles,
4848
cleanI18n,
4949
getNextVersion,
50+
hasStaticAppNotFoundComponent,
5051
} from "./utils";
5152
import { NODE_VERSION, NPM_COMMAND_TIMEOUT_MILLIES, SHARP_VERSION, I18N_ROOT } from "../constants";
5253
import type {
@@ -215,6 +216,13 @@ export async function build(dir: string): Promise<BuildResult> {
215216
dynamicRoutes
216217
);
217218

219+
if (
220+
unrenderedServerComponents.has("/_not-found") &&
221+
(await hasStaticAppNotFoundComponent(dir, distDir))
222+
) {
223+
unrenderedServerComponents.delete("/_not-found");
224+
}
225+
218226
for (const key of unrenderedServerComponents) {
219227
reasonsForBackend.add(`non-static component ${key}`);
220228
}

src/frameworks/next/utils.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export function getNonStaticServerComponents(
338338
appPathRoutesManifest: AppPathRoutesManifest,
339339
prerenderedRoutes: string[],
340340
dynamicRoutes: string[]
341-
): string[] {
341+
): Set<string> {
342342
const nonStaticServerComponents = Object.entries(appPathsManifest)
343343
.filter(([it, src]) => {
344344
if (extname(src) !== ".js") return;
@@ -347,7 +347,7 @@ export function getNonStaticServerComponents(
347347
})
348348
.map(([it]) => it);
349349

350-
return nonStaticServerComponents;
350+
return new Set(nonStaticServerComponents);
351351
}
352352

353353
/**
@@ -407,3 +407,17 @@ export function getNextVersion(cwd: string): string | undefined {
407407

408408
return nextVersionSemver.toString();
409409
}
410+
411+
/**
412+
* Whether the Next.js project has a static `not-found` page in the app directory.
413+
*
414+
* The Next.js build manifests are misleading regarding the existence of a static
415+
* `not-found` component. Therefore, we check if a `_not-found.html` file exists
416+
* in the generated app directory files to know whether `not-found` is static.
417+
*/
418+
export async function hasStaticAppNotFoundComponent(
419+
sourceDir: string,
420+
distDir: string
421+
): Promise<boolean> {
422+
return pathExists(join(sourceDir, distDir, "server", "app", "_not-found.html"));
423+
}

src/test/frameworks/next/utils.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ describe("Next.js utils", () => {
461461
Object.keys(prerenderManifest.routes),
462462
Object.keys(prerenderManifest.dynamicRoutes)
463463
)
464-
).to.deep.equal(["/api/test/route"]);
464+
).to.deep.equal(new Set(["/api/test/route"]));
465465
});
466466
});
467467

0 commit comments

Comments
 (0)