From 7d4d08a6fd37f1a786a35e37cbace0fb258a1f78 Mon Sep 17 00:00:00 2001
From: Mischa Spiegelmock <me@mish.dev>
Date: Thu, 22 Dec 2022 09:41:11 +0200
Subject: [PATCH] fix: Output paths (#62)

* Clearer paths for output

* chore: self mutation

Signed-off-by: github-actions <github-actions@github.com>

* Fixing server output path

* chore: self mutation

Signed-off-by: github-actions <github-actions@github.com>

* Fix server handler path in lambda function

* comment

Signed-off-by: github-actions <github-actions@github.com>
Co-authored-by: github-actions <github-actions@github.com>
---
 API.md              | 170 ++++++++++++++++++++++++++++++++++++++++----
 src/NextjsBase.ts   |   8 ++-
 src/NextjsBuild.ts  |  55 ++++++++++++--
 src/NextjsLambda.ts |  11 ++-
 4 files changed, 219 insertions(+), 25 deletions(-)

diff --git a/API.md b/API.md
index 235fab0a..8ed6cf31 100644
--- a/API.md
+++ b/API.md
@@ -1520,11 +1520,14 @@ Any object.
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.buildPath">buildPath</a></code> | <code>string</code> | The path to the directory where the server build artifacts are stored. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextDir">nextDir</a></code> | <code>string</code> | *No description.* |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextDirRelative">nextDirRelative</a></code> | <code>string</code> | Relative path from project root to nextjs project. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextPublicDir">nextPublicDir</a></code> | <code>string</code> | Public static files. |
-| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextStandaloneBuildDir">nextStandaloneBuildDir</a></code> | <code>string</code> | NextJS project inside of standalone build. |
-| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextStandaloneDir">nextStandaloneDir</a></code> | <code>string</code> | Entire NextJS build output directory. |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextStandaloneBuildDir">nextStandaloneBuildDir</a></code> | <code>string</code> | NextJS build inside of standalone build. |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextStandaloneDir">nextStandaloneDir</a></code> | <code>string</code> | NextJS project inside of standalone build. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.nextStaticDir">nextStaticDir</a></code> | <code>string</code> | Static files containing client-side code. |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.projectRoot">projectRoot</a></code> | <code>string</code> | *No description.* |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.props">props</a></code> | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps">NextjsBuildProps</a></code> | *No description.* |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.standaloneDir">standaloneDir</a></code> | <code>string</code> | Entire NextJS build output directory. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuild.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | *No description.* |
 
 ---
@@ -1563,6 +1566,20 @@ public readonly nextDir: string;
 
 ---
 
+##### `nextDirRelative`<sup>Required</sup> <a name="nextDirRelative" id="cdk-nextjs-standalone.NextjsBuild.property.nextDirRelative"></a>
+
+```typescript
+public readonly nextDirRelative: string;
+```
+
+- *Type:* string
+
+Relative path from project root to nextjs project.
+
+e.g. 'web' or 'packages/web' or '.'
+
+---
+
 ##### `nextPublicDir`<sup>Required</sup> <a name="nextPublicDir" id="cdk-nextjs-standalone.NextjsBuild.property.nextPublicDir"></a>
 
 ```typescript
@@ -1585,7 +1602,7 @@ public readonly nextStandaloneBuildDir: string;
 
 - *Type:* string
 
-NextJS project inside of standalone build.
+NextJS build inside of standalone build.
 
 Contains server code and manifests.
 
@@ -1599,9 +1616,9 @@ public readonly nextStandaloneDir: string;
 
 - *Type:* string
 
-Entire NextJS build output directory.
+NextJS project inside of standalone build.
 
-Contains server and client code and manifests.
+Contains .next build and server code and traced dependencies.
 
 ---
 
@@ -1617,6 +1634,16 @@ Static files containing client-side code.
 
 ---
 
+##### `projectRoot`<sup>Required</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsBuild.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+---
+
 ##### `props`<sup>Required</sup> <a name="props" id="cdk-nextjs-standalone.NextjsBuild.property.props"></a>
 
 ```typescript
@@ -1627,6 +1654,20 @@ public readonly props: NextjsBuildProps;
 
 ---
 
+##### `standaloneDir`<sup>Required</sup> <a name="standaloneDir" id="cdk-nextjs-standalone.NextjsBuild.property.standaloneDir"></a>
+
+```typescript
+public readonly standaloneDir: string;
+```
+
+- *Type:* string
+
+Entire NextJS build output directory.
+
+Contains server and client code and manifests.
+
+---
+
 ##### `tempBuildDir`<sup>Required</sup> <a name="tempBuildDir" id="cdk-nextjs-standalone.NextjsBuild.property.tempBuildDir"></a>
 
 ```typescript
@@ -2639,6 +2680,7 @@ const imageOptimizationProps: ImageOptimizationProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 | <code><a href="#cdk-nextjs-standalone.ImageOptimizationProps.property.bucket">bucket</a></code> | <code>aws-cdk-lib.aws_s3.IBucket</code> | The S3 bucket holding application images. |
@@ -2672,7 +2714,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -2729,6 +2771,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.ImageOptimizationProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.ImageOptimizationProps.property.quiet"></a>
 
 ```typescript
@@ -2870,6 +2926,7 @@ const nextjsAssetsDeploymentProps: NextjsAssetsDeploymentProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 | <code><a href="#cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.bucket">bucket</a></code> | <code>aws-cdk-lib.aws_s3.IBucket</code> | Properties for the S3 bucket containing the NextJS assets. |
@@ -2904,7 +2961,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -2961,6 +3018,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsAssetsDeploymentProps.property.quiet"></a>
 
 ```typescript
@@ -3071,6 +3142,7 @@ const nextjsBaseProps: NextjsBaseProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBaseProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 
@@ -3100,7 +3172,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -3157,6 +3229,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsBaseProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsBaseProps.property.quiet"></a>
 
 ```typescript
@@ -3203,6 +3289,7 @@ const nextjsBuildProps: NextjsBuildProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsBuildProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 
@@ -3232,7 +3319,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -3289,6 +3376,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsBuildProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsBuildProps.property.quiet"></a>
 
 ```typescript
@@ -3492,6 +3593,7 @@ const nextjsDistributionProps: NextjsDistributionProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 | <code><a href="#cdk-nextjs-standalone.NextjsDistributionProps.property.imageOptFunction">imageOptFunction</a></code> | <code>aws-cdk-lib.aws_lambda.IFunction</code> | Lambda function to optimize images. |
@@ -3530,7 +3632,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -3587,6 +3689,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsDistributionProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsDistributionProps.property.quiet"></a>
 
 ```typescript
@@ -3877,6 +3993,7 @@ const nextjsLambdaProps: NextjsLambdaProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 | <code><a href="#cdk-nextjs-standalone.NextjsLambdaProps.property.nextBuild">nextBuild</a></code> | <code><a href="#cdk-nextjs-standalone.NextjsBuild">NextjsBuild</a></code> | Built nextJS application. |
@@ -3908,7 +4025,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -3965,6 +4082,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsLambdaProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsLambdaProps.property.quiet"></a>
 
 ```typescript
@@ -4046,6 +4177,7 @@ const nextjsProps: NextjsProps = { ... }
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.environment">environment</a></code> | <code>{[ key: string ]: string}</code> | Custom environment variables to pass to the NextJS build and runtime. |
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.isPlaceholder">isPlaceholder</a></code> | <code>boolean</code> | Skip building app and deploy a placeholder. |
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.nodeEnv">nodeEnv</a></code> | <code>string</code> | Optional value for NODE_ENV during build and runtime. |
+| <code><a href="#cdk-nextjs-standalone.NextjsProps.property.projectRoot">projectRoot</a></code> | <code>string</code> | Root of your project, if different from `nextjsPath`. |
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.quiet">quiet</a></code> | <code>boolean</code> | Less build output. |
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.tempBuildDir">tempBuildDir</a></code> | <code>string</code> | Directory to store temporary build files in. |
 | <code><a href="#cdk-nextjs-standalone.NextjsProps.property.defaults">defaults</a></code> | <code><a href="#cdk-nextjs-standalone.NextjsDefaultsProps">NextjsDefaultsProps</a></code> | Allows you to override defaults for the resources created by this construct. |
@@ -4077,7 +4209,7 @@ public readonly buildPath: string;
 
 The directory to execute `npm run build` from.
 
-By default, it uses `nextjsPath`.
+By default, it is `nextjsPath`.
 Can be overridden, particularly useful for monorepos where `build` is expected to run
 at the root of the project.
 
@@ -4134,6 +4266,20 @@ Optional value for NODE_ENV during build and runtime.
 
 ---
 
+##### `projectRoot`<sup>Optional</sup> <a name="projectRoot" id="cdk-nextjs-standalone.NextjsProps.property.projectRoot"></a>
+
+```typescript
+public readonly projectRoot: string;
+```
+
+- *Type:* string
+
+Root of your project, if different from `nextjsPath`.
+
+Defaults to current working directory.
+
+---
+
 ##### `quiet`<sup>Optional</sup> <a name="quiet" id="cdk-nextjs-standalone.NextjsProps.property.quiet"></a>
 
 ```typescript
diff --git a/src/NextjsBase.ts b/src/NextjsBase.ts
index 1e557337..98a48e8f 100644
--- a/src/NextjsBase.ts
+++ b/src/NextjsBase.ts
@@ -15,12 +15,18 @@ export interface NextjsBaseProps {
   readonly nextjsPath: string;
 
   /**
-   * The directory to execute `npm run build` from. By default, it uses `nextjsPath`.
+   * The directory to execute `npm run build` from. By default, it is `nextjsPath`.
    * Can be overridden, particularly useful for monorepos where `build` is expected to run
    * at the root of the project.
    */
   readonly buildPath?: string;
 
+  /**
+   * Root of your project, if different from `nextjsPath`.
+   * Defaults to current working directory.
+   */
+  readonly projectRoot?: string;
+
   /**
    * Custom environment variables to pass to the NextJS build and runtime.
    */
diff --git a/src/NextjsBuild.ts b/src/NextjsBuild.ts
index 4b749153..b2bd8513 100644
--- a/src/NextjsBuild.ts
+++ b/src/NextjsBuild.ts
@@ -33,9 +33,14 @@ export class NextjsBuild extends Construct {
    * Entire NextJS build output directory.
    * Contains server and client code and manifests.
    */
-  public nextStandaloneDir: string;
+  public standaloneDir: string;
   /**
    * NextJS project inside of standalone build.
+   * Contains .next build and server code and traced dependencies.
+   */
+  public nextStandaloneDir: string;
+  /**
+   * NextJS build inside of standalone build.
    * Contains server code and manifests.
    */
   public nextStandaloneBuildDir: string;
@@ -48,12 +53,18 @@ export class NextjsBuild extends Construct {
    * E.g. robots.txt, favicon.ico, etc.
    */
   public nextPublicDir: string;
+  /**
+   * Relative path from project root to nextjs project.
+   * e.g. 'web' or 'packages/web' or '.'
+   */
+  public nextDirRelative: string;
 
   public props: NextjsBuildProps;
 
   public tempBuildDir: string;
 
   public nextDir: string;
+  public projectRoot: string;
 
   constructor(scope: Construct, id: string, props: NextjsBuildProps) {
     super(scope, id);
@@ -68,6 +79,9 @@ export class NextjsBuild extends Construct {
     const baseOutputDir = path.resolve(this.props.nextjsPath);
     if (!fs.existsSync(baseOutputDir)) throw new Error(`NextJS application not found at "${baseOutputDir}"`);
 
+    // root of project
+    this.projectRoot = props.projectRoot ? path.resolve(props.projectRoot) : path.resolve();
+
     // build app
     this.runNpmBuild();
 
@@ -77,8 +91,10 @@ export class NextjsBuild extends Construct {
       throw new Error(`No server build output found at "${serverBuildDir}"`);
 
     // our outputs
+    this.standaloneDir = this._getStandaloneDir();
     this.nextStandaloneDir = this._getNextStandaloneDir();
     this.nextStandaloneBuildDir = this._getNextStandaloneBuildDir();
+    this.nextDirRelative = this._getNextDirRelative();
     this.nextPublicDir = this._getNextPublicDir();
     this.nextStaticDir = this._getNextStaticDir();
     this.buildPath = this.nextStandaloneBuildDir;
@@ -107,10 +123,11 @@ export class NextjsBuild extends Construct {
     }
 
     // build environment vars
+    const outputTracingRoot = this.projectRoot;
     const buildEnv = {
       ...process.env,
       [NEXTJS_BUILD_STANDALONE_ENV]: 'true',
-      [NEXTJS_BUILD_OUTPUTTRACEROOT_ENV]: path.resolve(),
+      [NEXTJS_BUILD_OUTPUTTRACEROOT_ENV]: outputTracingRoot,
       ...getBuildCmdEnvironment(this.props.environment),
       ...(this.props.nodeEnv ? { NODE_ENV: this.props.nodeEnv } : {}),
     };
@@ -138,7 +155,7 @@ export class NextjsBuild extends Construct {
     return listDirectory(publicDir).map((file) => path.join('/', path.relative(publicDir, file)));
   }
 
-  // get the path to the directory containing the nextjs project
+  // get the absolute path to the directory containing the nextjs project
   // it may be the project root or a subdirectory in a monorepo setup
   private _getNextDir() {
     const { nextjsPath } = this.props; // path to nextjs dir inside project
@@ -149,13 +166,21 @@ export class NextjsBuild extends Construct {
     return absolutePath;
   }
 
+  // get relative path from root of the project to the nextjs project
+  // e.g. 'web' or 'packages/web'
+  private _getNextDirRelative() {
+    const absNextDir = this._getNextDir();
+    const absProjectDir = this.projectRoot;
+    return path.relative(absProjectDir, absNextDir);
+  }
+
   // .next
   private _getNextBuildDir() {
     return path.join(this._getNextDir(), NEXTJS_BUILD_DIR);
   }
 
   // output of nextjs standalone build
-  private _getNextStandaloneDir() {
+  private _getStandaloneDir() {
     const nextDir = this._getNextBuildDir();
     const standaloneDir = path.join(nextDir, NEXTJS_BUILD_STANDALONE_DIR);
 
@@ -165,10 +190,23 @@ export class NextjsBuild extends Construct {
     return standaloneDir;
   }
 
-  // nextjs project inside of standalone build
+  // .next/ directory inside of standalone build output directory
   // contains manifests and server code
   private _getNextStandaloneBuildDir() {
-    return path.join(this._getNextStandaloneDir(), this.props.nextjsPath, NEXTJS_BUILD_DIR);
+    return path.join(this._getNextStandaloneDir(), NEXTJS_BUILD_DIR); // e.g. /home/me/myapp/web/.next/standalone/web/.next
+  }
+
+  // nextjs project inside of standalone build
+  // contains manifests and server code
+  private _getNextStandaloneDir() {
+    const standaloneDir = this._getStandaloneDir();
+
+    // if the project is at /home/me/myapp and the nextjs project is at /home/me/myapp/web
+    // the standalone build of the web app will be at /home/me/myapp/web/.next/standalone/web
+    // so we need to get the relative path from the standalone dir to the nextjsPath
+    const relativePath = this._getNextDirRelative(); // e.g. 'web
+    const standaloneProjectDir = path.join(standaloneDir, relativePath); // e.g. /home/me/myapp/web/.next/standalone/web
+    return standaloneProjectDir;
   }
 
   // contains static files
@@ -206,6 +244,11 @@ export function createArchive({
   // get output path
   const zipFilePath = path.join(zipOutDir, zipFileName);
 
+  // delete existing zip file
+  if (fs.existsSync(zipFilePath)) {
+    fs.unlinkSync(zipFilePath);
+  }
+
   // run script to create zipfile, preserving symlinks for node_modules (e.g. pnpm structure)
   const result = spawn.sync(
     'bash', // getting ENOENT when specifying 'node' here for some reason
diff --git a/src/NextjsLambda.ts b/src/NextjsLambda.ts
index f15d1e6c..9ba32ebd 100644
--- a/src/NextjsLambda.ts
+++ b/src/NextjsLambda.ts
@@ -50,10 +50,9 @@ export class NextJsLambda extends Construct {
   constructor(scope: Construct, id: string, props: NextjsLambdaProps) {
     super(scope, id);
     const { nextBuild, lambda: functionOptions, isPlaceholder } = props;
-
     // bundle server handler
     // delete default nextjs handler if it exists
-    const defaultServerPath = path.join(nextBuild.nextStandaloneDir, props.nextjsPath, 'server.js');
+    const defaultServerPath = path.join(nextBuild.nextStandaloneDir, 'server.js');
     if (fs.existsSync(defaultServerPath)) {
       fs.unlinkSync(defaultServerPath);
     }
@@ -61,10 +60,10 @@ export class NextJsLambda extends Construct {
     // build our server handler in build.nextStandaloneDir
     const serverHandler = path.resolve(__dirname, '../assets/lambda/NextJsHandler.ts');
     // server should live in the same dir as the nextjs app to access deps properly
-    const serverPath = path.join(props.nextjsPath, 'server.cjs');
+    const serverPath = path.join(nextBuild.nextStandaloneDir, 'server.js');
     bundleFunction({
       inputPath: serverHandler,
-      outputPath: path.join(nextBuild.nextStandaloneDir, serverPath),
+      outputPath: serverPath,
       bundleOptions: {
         bundle: true,
         minify: false,
@@ -83,7 +82,7 @@ export class NextJsLambda extends Construct {
         : fs.mkdtempSync(path.join(os.tmpdir(), 'standalone-'))
     );
     const zipFilePath = createArchive({
-      directory: nextBuild.nextStandaloneDir,
+      directory: nextBuild.standaloneDir,
       zipFileName: 'standalone.zip',
       zipOutDir,
       fileGlob: '*',
@@ -105,7 +104,7 @@ export class NextJsLambda extends Construct {
       memorySize: functionOptions?.memorySize || 1024,
       timeout: functionOptions?.timeout ?? Duration.seconds(10),
       runtime: LAMBDA_RUNTIME,
-      handler: path.join(props.nextjsPath, 'server.handler'),
+      handler: path.join(nextBuild.nextDirRelative, 'server.handler'),
       code,
       environment,