Skip to content

Commit 0ec0135

Browse files
authored
Detect OpenNext version based on Next.js version (#6406)
1 parent 6256694 commit 0ec0135

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

platform/src/components/aws/nextjs.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { VisibleError } from "../error.js";
77
import type { Input } from "../input.js";
88
import { Queue } from "./queue.js";
99
import { dynamodb, getRegionOutput, lambda } from "@pulumi/aws";
10-
import { isALteB } from "../../util/compare-semver.js";
10+
import { isALteB, isALtB } from "../../util/compare-semver.js";
1111
import { Plan, SsrSite, SsrSiteArgs } from "./ssr-site.js";
1212
import { Bucket, BucketArgs } from "./bucket.js";
1313
import { CdnArgs } from "./cdn.js";
1414
import { transform, Transform } from "../component.js";
1515

16-
const DEFAULT_OPEN_NEXT_VERSION = "3.9.8";
16+
const DEFAULT_OPEN_NEXT_VERSION = "3.9.14";
17+
const DEFAULT_OPEN_NEXT_VERSION_NEXT14 = "3.6.6";
1718

1819
type BaseFunction = {
1920
handler: string;
@@ -401,13 +402,15 @@ export interface NextjsArgs extends SsrSiteArgs {
401402
* Configure the [OpenNext](https://opennext.js.org) version used to build the Next.js app.
402403
*
403404
* :::note
404-
* This does not automatically update to the latest OpenNext version. It remains pinned to the version of SST you have.
405+
* The default OpenNext version is auto-detected based on your Next.js version and pinned to the version of SST you have.
405406
* :::
406407
*
407-
* By default, this is pinned to the version of OpenNext that was released with the SST version you are using. You can [find this in the source](https://github.com/sst/sst/blob/dev/platform/src/components/aws/nextjs.ts#L30) under `DEFAULT_OPEN_NEXT_VERSION`.
408+
* By default, SST auto-detects the Next.js version from your `package.json` and picks a compatible OpenNext version. For Next.js 15+, it uses `3.9.14`. For Next.js 14, it uses `3.6.6` since newer versions of OpenNext dropped Next.js 14 support. If set, this overrides the auto-detection.
409+
*
410+
* You can [find the defaults in the source](https://github.com/sst/sst/blob/dev/platform/src/components/aws/nextjs.ts#L30) under `DEFAULT_OPEN_NEXT_VERSION`.
408411
* OpenNext changed its package name from `open-next` to `@opennextjs/aws` in version `3.1.4`. SST will choose the correct one based on the version you provide.
409412
*
410-
* @default The latest version of OpenNext pinned to the version of SST you are using.
413+
* @default Auto-detected based on your Next.js version.
411414
* @example
412415
* ```js
413416
* {
@@ -592,10 +595,26 @@ export class Nextjs extends SsrSite {
592595
}
593596

594597
protected normalizeBuildCommand(args: NextjsArgs) {
595-
return all([args?.buildCommand, args?.openNextVersion]).apply(
596-
([buildCommand, openNextVersion]) => {
598+
return all([args?.buildCommand, args?.openNextVersion, args?.path]).apply(
599+
([buildCommand, openNextVersion, sitePath]) => {
597600
if (buildCommand) return buildCommand;
598-
const version = openNextVersion ?? DEFAULT_OPEN_NEXT_VERSION;
601+
602+
function detectDefaultOpenNextVersion() {
603+
try {
604+
const pkgPath = path.join(sitePath ?? ".", "package.json");
605+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
606+
const nextVersion =
607+
pkg.dependencies?.next ?? pkg.devDependencies?.next;
608+
if (nextVersion && isALtB(nextVersion, "15.0.0")) {
609+
return DEFAULT_OPEN_NEXT_VERSION_NEXT14;
610+
}
611+
} catch {
612+
console.warn(`Failed to detect Next.js version. Using OpenNext v${DEFAULT_OPEN_NEXT_VERSION} as default.`);
613+
}
614+
return DEFAULT_OPEN_NEXT_VERSION;
615+
}
616+
617+
const version = openNextVersion ?? detectDefaultOpenNextVersion();
599618
const packageName = isALteB(version, "3.1.3")
600619
? "open-next"
601620
: "@opennextjs/aws";

0 commit comments

Comments
 (0)