Skip to content

Commit

Permalink
On NextJS deploy check if not-found is static (#6558)
Browse files Browse the repository at this point in the history
  • Loading branch information
leoortizz authored Dec 2, 2023
1 parent 9f5d1ce commit ede17a1
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Added the ability to deploy Angular apps using [the new application-builder](https://angular.dev/tools/cli/esbuild). (#6480)
- Fixed an issue where `--non-interactive` flag is not respected in Firestore indexes deploys. (#6539)
- Fixed an issue where `login:use` would not work outside of a Firebase project directory. (#6526)
- Prevent app router static `not-found` requiring a Cloud Function in Next.js deployments. (#6558)
8 changes: 8 additions & 0 deletions src/frameworks/next/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
getHeadersFromMetaFiles,
cleanI18n,
getNextVersion,
hasStaticAppNotFoundComponent,
} from "./utils";
import { NODE_VERSION, NPM_COMMAND_TIMEOUT_MILLIES, SHARP_VERSION, I18N_ROOT } from "../constants";
import type {
Expand Down Expand Up @@ -215,6 +216,13 @@ export async function build(dir: string): Promise<BuildResult> {
dynamicRoutes
);

if (
unrenderedServerComponents.has("/_not-found") &&
(await hasStaticAppNotFoundComponent(dir, distDir))
) {
unrenderedServerComponents.delete("/_not-found");
}

for (const key of unrenderedServerComponents) {
reasonsForBackend.add(`non-static component ${key}`);
}
Expand Down
18 changes: 16 additions & 2 deletions src/frameworks/next/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export function getNonStaticServerComponents(
appPathRoutesManifest: AppPathRoutesManifest,
prerenderedRoutes: string[],
dynamicRoutes: string[]
): string[] {
): Set<string> {
const nonStaticServerComponents = Object.entries(appPathsManifest)
.filter(([it, src]) => {
if (extname(src) !== ".js") return;
Expand All @@ -347,7 +347,7 @@ export function getNonStaticServerComponents(
})
.map(([it]) => it);

return nonStaticServerComponents;
return new Set(nonStaticServerComponents);
}

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

return nextVersionSemver.toString();
}

/**
* Whether the Next.js project has a static `not-found` page in the app directory.
*
* The Next.js build manifests are misleading regarding the existence of a static
* `not-found` component. Therefore, we check if a `_not-found.html` file exists
* in the generated app directory files to know whether `not-found` is static.
*/
export async function hasStaticAppNotFoundComponent(
sourceDir: string,
distDir: string
): Promise<boolean> {
return pathExists(join(sourceDir, distDir, "server", "app", "_not-found.html"));
}
2 changes: 1 addition & 1 deletion src/test/frameworks/next/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ describe("Next.js utils", () => {
Object.keys(prerenderManifest.routes),
Object.keys(prerenderManifest.dynamicRoutes)
)
).to.deep.equal(["/api/test/route"]);
).to.deep.equal(new Set(["/api/test/route"]));
});
});

Expand Down

0 comments on commit ede17a1

Please sign in to comment.