cdk-nextjs 0.7.11 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +310 -100
- package/.jsii.tabl.json +1 -1
- package/API.md +211 -3
- package/README.md +116 -101
- package/docs/breaking-changes.md +36 -2
- package/docs/development-guide.md +10 -0
- package/docs/next-build-output-guide.md +1 -1
- package/lib/adapter/adapter.mjs +4 -1
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +21 -0
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
- package/lib/nextjs-api.js +1 -1
- package/lib/nextjs-build/nextjs-build.js +1 -1
- package/lib/nextjs-cache.js +1 -1
- package/lib/nextjs-compute/nextjs-containers.js +1 -1
- package/lib/nextjs-compute/nextjs-functions.js +1 -1
- package/lib/nextjs-distribution.d.ts +71 -2
- package/lib/nextjs-distribution.js +156 -107
- package/lib/nextjs-distribution.test.js +361 -12
- package/lib/nextjs-post-deploy.js +1 -1
- package/lib/nextjs-static-assets.d.ts +74 -5
- package/lib/nextjs-static-assets.js +276 -41
- package/lib/nextjs-static-assets.test.js +298 -1
- package/lib/root-constructs/nextjs-base-construct.d.ts +5 -4
- package/lib/root-constructs/nextjs-base-construct.js +17 -8
- package/lib/root-constructs/nextjs-global-containers.d.ts +16 -1
- package/lib/root-constructs/nextjs-global-containers.js +4 -2
- package/lib/root-constructs/nextjs-global-functions.d.ts +16 -1
- package/lib/root-constructs/nextjs-global-functions.js +4 -2
- package/lib/root-constructs/nextjs-regional-containers.js +1 -1
- package/lib/root-constructs/nextjs-regional-functions.js +1 -1
- package/lib/runtime/image-utils.d.ts +1 -0
- package/lib/runtime/image-utils.js +2 -1
- package/lib/runtime/image-utils.test.js +17 -1
- package/lib/runtime/image.js +5 -2
- package/lib/runtime/image.test.js +21 -1
- package/lib/runtime/lambda.mjs +9 -2
- package/lib/runtime/server.mjs +9 -2
- package/lib/utils/viewer-request-functions.d.ts +53 -0
- package/lib/utils/viewer-request-functions.js +172 -0
- package/lib/utils/viewer-request-functions.test.d.ts +1 -0
- package/lib/utils/viewer-request-functions.test.js +43 -0
- package/package.json +4 -1
- package/scripts/e2e-harness/app.js +7 -2
- package/scripts/render-diagrams.mjs +121 -0
package/API.md
CHANGED
|
@@ -2606,8 +2606,11 @@ Any object.
|
|
|
2606
2606
|
| --- | --- | --- |
|
|
2607
2607
|
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
|
|
2608
2608
|
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.keyPrefix">keyPrefix</a></code> | <code>string</code> | S3 key prefix the assets are actually uploaded under, normalized to a bare path segment (empty when they live at the bucket root). |
|
|
2609
|
+
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.publicDeployment">publicDeployment</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeployment</code> | Uploads `public/`, separately from `staticDeployment` because its files keep their names when they change and so can't be `immutable`. |
|
|
2610
|
+
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.serviceWorkerDeployment">serviceWorkerDeployment</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeployment</code> | Uploads `.next/static/service-worker` with `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it: a service worker keeps its URL across builds, so it can't be `immutable`. Absent if the build has no service worker. |
|
|
2611
|
+
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.staticDeployment">staticDeployment</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeployment</code> | Uploads `.next/static` to `_next/static/` with `Cache-Control: public, max-age=31536000, immutable`, except for `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has no `.next/static`. |
|
|
2609
2612
|
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.bucket">bucket</a></code> | <code>aws-cdk-lib.aws_s3.IBucket</code> | *No description.* |
|
|
2610
|
-
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.deployment">deployment</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeployment</code> |
|
|
2613
|
+
| <code><a href="#cdk-nextjs.NextjsStaticAssets.property.deployment">deployment</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeployment</code> | The first of `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment` the build has files for. |
|
|
2611
2614
|
|
|
2612
2615
|
---
|
|
2613
2616
|
|
|
@@ -2643,6 +2646,45 @@ bytes were uploaded.
|
|
|
2643
2646
|
|
|
2644
2647
|
---
|
|
2645
2648
|
|
|
2649
|
+
##### `publicDeployment`<sup>Optional</sup> <a name="publicDeployment" id="cdk-nextjs.NextjsStaticAssets.property.publicDeployment"></a>
|
|
2650
|
+
|
|
2651
|
+
```typescript
|
|
2652
|
+
public readonly publicDeployment: BucketDeployment;
|
|
2653
|
+
```
|
|
2654
|
+
|
|
2655
|
+
- *Type:* aws-cdk-lib.aws_s3_deployment.BucketDeployment
|
|
2656
|
+
|
|
2657
|
+
Uploads `public/`, separately from `staticDeployment` because its files keep their names when they change and so can't be `immutable`.
|
|
2658
|
+
|
|
2659
|
+
Absent if
|
|
2660
|
+
the build has no `public` directory.
|
|
2661
|
+
|
|
2662
|
+
---
|
|
2663
|
+
|
|
2664
|
+
##### `serviceWorkerDeployment`<sup>Optional</sup> <a name="serviceWorkerDeployment" id="cdk-nextjs.NextjsStaticAssets.property.serviceWorkerDeployment"></a>
|
|
2665
|
+
|
|
2666
|
+
```typescript
|
|
2667
|
+
public readonly serviceWorkerDeployment: BucketDeployment;
|
|
2668
|
+
```
|
|
2669
|
+
|
|
2670
|
+
- *Type:* aws-cdk-lib.aws_s3_deployment.BucketDeployment
|
|
2671
|
+
|
|
2672
|
+
Uploads `.next/static/service-worker` with `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it: a service worker keeps its URL across builds, so it can't be `immutable`. Absent if the build has no service worker.
|
|
2673
|
+
|
|
2674
|
+
---
|
|
2675
|
+
|
|
2676
|
+
##### `staticDeployment`<sup>Optional</sup> <a name="staticDeployment" id="cdk-nextjs.NextjsStaticAssets.property.staticDeployment"></a>
|
|
2677
|
+
|
|
2678
|
+
```typescript
|
|
2679
|
+
public readonly staticDeployment: BucketDeployment;
|
|
2680
|
+
```
|
|
2681
|
+
|
|
2682
|
+
- *Type:* aws-cdk-lib.aws_s3_deployment.BucketDeployment
|
|
2683
|
+
|
|
2684
|
+
Uploads `.next/static` to `_next/static/` with `Cache-Control: public, max-age=31536000, immutable`, except for `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has no `.next/static`.
|
|
2685
|
+
|
|
2686
|
+
---
|
|
2687
|
+
|
|
2646
2688
|
##### `bucket`<sup>Required</sup> <a name="bucket" id="cdk-nextjs.NextjsStaticAssets.property.bucket"></a>
|
|
2647
2689
|
|
|
2648
2690
|
```typescript
|
|
@@ -2653,7 +2695,11 @@ public readonly bucket: IBucket;
|
|
|
2653
2695
|
|
|
2654
2696
|
---
|
|
2655
2697
|
|
|
2656
|
-
#####
|
|
2698
|
+
##### ~~`deployment`~~<sup>Required</sup> <a name="deployment" id="cdk-nextjs.NextjsStaticAssets.property.deployment"></a>
|
|
2699
|
+
|
|
2700
|
+
- *Deprecated:* The assets are uploaded by up to three deployments, and this
|
|
2701
|
+
is only one of them: a dependency on it doesn't wait for the others. Use
|
|
2702
|
+
`staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`.
|
|
2657
2703
|
|
|
2658
2704
|
```typescript
|
|
2659
2705
|
public readonly deployment: BucketDeployment;
|
|
@@ -2661,6 +2707,8 @@ public readonly deployment: BucketDeployment;
|
|
|
2661
2707
|
|
|
2662
2708
|
- *Type:* aws-cdk-lib.aws_s3_deployment.BucketDeployment
|
|
2663
2709
|
|
|
2710
|
+
The first of `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment` the build has files for.
|
|
2711
|
+
|
|
2664
2712
|
---
|
|
2665
2713
|
|
|
2666
2714
|
|
|
@@ -4384,6 +4432,8 @@ const nextjsDistributionProps: NextjsDistributionProps = { ... }
|
|
|
4384
4432
|
| <code><a href="#cdk-nextjs.NextjsDistributionProps.property.loadBalancer">loadBalancer</a></code> | <code>aws-cdk-lib.aws_elasticloadbalancingv2.IApplicationLoadBalancer</code> | Required if `NextjsType.GLOBAL_CONTAINERS` or `NextjsType.REGIONAL_CONTAINERS`. |
|
|
4385
4433
|
| <code><a href="#cdk-nextjs.NextjsDistributionProps.property.maxCacheBehaviors">maxCacheBehaviors</a></code> | <code>number</code> | The most cache behaviors the distribution may have, the default one included. |
|
|
4386
4434
|
| <code><a href="#cdk-nextjs.NextjsDistributionProps.property.overrides">overrides</a></code> | <code><a href="#cdk-nextjs.NextjsDistributionOverrides">NextjsDistributionOverrides</a></code> | Override props for every construct. |
|
|
4435
|
+
| <code><a href="#cdk-nextjs.NextjsDistributionProps.property.viewerRequestFunctionCode">viewerRequestFunctionCode</a></code> | <code>aws-cdk-lib.aws_cloudfront.FunctionCode</code> | CloudFront Function code run first on every viewer request, on every behavior cdk-nextjs adds, static assets included — HTTP Basic auth on a pre-launch site, geo-gating. |
|
|
4436
|
+
| <code><a href="#cdk-nextjs.NextjsDistributionProps.property.viewerRequestKeyValueStore">viewerRequestKeyValueStore</a></code> | <code>aws-cdk-lib.aws_cloudfront.IKeyValueStore</code> | A CloudFront KeyValueStore associated with every viewer-request function {@link viewerRequestFunctionCode} is copied into (up to three, one per kind of behavior), so values it reads — Basic auth credentials, an allowlist — live outside the CloudFormation template and change without a deploy. |
|
|
4387
4437
|
|
|
4388
4438
|
---
|
|
4389
4439
|
|
|
@@ -4572,6 +4622,47 @@ Override props for every construct.
|
|
|
4572
4622
|
|
|
4573
4623
|
---
|
|
4574
4624
|
|
|
4625
|
+
##### `viewerRequestFunctionCode`<sup>Optional</sup> <a name="viewerRequestFunctionCode" id="cdk-nextjs.NextjsDistributionProps.property.viewerRequestFunctionCode"></a>
|
|
4626
|
+
|
|
4627
|
+
```typescript
|
|
4628
|
+
public readonly viewerRequestFunctionCode: FunctionCode;
|
|
4629
|
+
```
|
|
4630
|
+
|
|
4631
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.FunctionCode
|
|
4632
|
+
- *Default:* none
|
|
4633
|
+
|
|
4634
|
+
CloudFront Function code run first on every viewer request, on every behavior cdk-nextjs adds, static assets included — HTTP Basic auth on a pre-launch site, geo-gating.
|
|
4635
|
+
|
|
4636
|
+
It must define `viewerRequest(event)` (a function, sync or async, or a
|
|
4637
|
+
`var`/`let`/`const`): return a response to answer the viewer, or the
|
|
4638
|
+
request (or nothing) to carry on. It is spliced into cdk-nextjs's own
|
|
4639
|
+
viewer-request functions, ahead of their logic, so it may not use the
|
|
4640
|
+
name `handler`, and the combined function must fit CloudFront's 10 KB.
|
|
4641
|
+
It runs on `cloudfront-js-2.0`, so it may be async and read
|
|
4642
|
+
{@link viewerRequestKeyValueStore} with `cf.kvs()`. A bring-your-own
|
|
4643
|
+
{@link distribution}'s default behavior isn't covered.
|
|
4644
|
+
|
|
4645
|
+
> [https://github.com/cdklabs/cdk-nextjs#running-code-on-every-viewer-request](https://github.com/cdklabs/cdk-nextjs#running-code-on-every-viewer-request)
|
|
4646
|
+
|
|
4647
|
+
---
|
|
4648
|
+
|
|
4649
|
+
##### `viewerRequestKeyValueStore`<sup>Optional</sup> <a name="viewerRequestKeyValueStore" id="cdk-nextjs.NextjsDistributionProps.property.viewerRequestKeyValueStore"></a>
|
|
4650
|
+
|
|
4651
|
+
```typescript
|
|
4652
|
+
public readonly viewerRequestKeyValueStore: IKeyValueStore;
|
|
4653
|
+
```
|
|
4654
|
+
|
|
4655
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.IKeyValueStore
|
|
4656
|
+
- *Default:* none
|
|
4657
|
+
|
|
4658
|
+
A CloudFront KeyValueStore associated with every viewer-request function {@link viewerRequestFunctionCode} is copied into (up to three, one per kind of behavior), so values it reads — Basic auth credentials, an allowlist — live outside the CloudFormation template and change without a deploy.
|
|
4659
|
+
|
|
4660
|
+
Read it with `cf.kvs()`, no ID needed.
|
|
4661
|
+
|
|
4662
|
+
> [https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-custom-methods.html](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-custom-methods.html)
|
|
4663
|
+
|
|
4664
|
+
---
|
|
4665
|
+
|
|
4575
4666
|
### NextjsFunctionGroup <a name="NextjsFunctionGroup" id="cdk-nextjs.NextjsFunctionGroup"></a>
|
|
4576
4667
|
|
|
4577
4668
|
A set of routes to package into their own Lambda function.
|
|
@@ -5248,6 +5339,8 @@ const nextjsGlobalContainersProps: NextjsGlobalContainersProps = { ... }
|
|
|
5248
5339
|
| <code><a href="#cdk-nextjs.NextjsGlobalContainersProps.property.distribution">distribution</a></code> | <code>aws-cdk-lib.aws_cloudfront.Distribution</code> | Bring your own distribution. |
|
|
5249
5340
|
| <code><a href="#cdk-nextjs.NextjsGlobalContainersProps.property.ecsCluster">ecsCluster</a></code> | <code>aws-cdk-lib.aws_ecs.ICluster</code> | Bring your own ECS cluster. |
|
|
5250
5341
|
| <code><a href="#cdk-nextjs.NextjsGlobalContainersProps.property.overrides">overrides</a></code> | <code><a href="#cdk-nextjs.NextjsGlobalContainersOverrides">NextjsGlobalContainersOverrides</a></code> | Override props of any construct. |
|
|
5342
|
+
| <code><a href="#cdk-nextjs.NextjsGlobalContainersProps.property.viewerRequestFunctionCode">viewerRequestFunctionCode</a></code> | <code>aws-cdk-lib.aws_cloudfront.FunctionCode</code> | CloudFront Function code run first on every viewer request, static assets included — HTTP Basic auth on a pre-launch site, say. |
|
|
5343
|
+
| <code><a href="#cdk-nextjs.NextjsGlobalContainersProps.property.viewerRequestKeyValueStore">viewerRequestKeyValueStore</a></code> | <code>aws-cdk-lib.aws_cloudfront.IKeyValueStore</code> | A CloudFront KeyValueStore `viewerRequestFunctionCode` can read with `cf.kvs()`, so credentials stay out of the template. |
|
|
5251
5344
|
|
|
5252
5345
|
---
|
|
5253
5346
|
|
|
@@ -5519,6 +5612,39 @@ Override props of any construct.
|
|
|
5519
5612
|
|
|
5520
5613
|
---
|
|
5521
5614
|
|
|
5615
|
+
##### `viewerRequestFunctionCode`<sup>Optional</sup> <a name="viewerRequestFunctionCode" id="cdk-nextjs.NextjsGlobalContainersProps.property.viewerRequestFunctionCode"></a>
|
|
5616
|
+
|
|
5617
|
+
```typescript
|
|
5618
|
+
public readonly viewerRequestFunctionCode: FunctionCode;
|
|
5619
|
+
```
|
|
5620
|
+
|
|
5621
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.FunctionCode
|
|
5622
|
+
- *Default:* none
|
|
5623
|
+
|
|
5624
|
+
CloudFront Function code run first on every viewer request, static assets included — HTTP Basic auth on a pre-launch site, say.
|
|
5625
|
+
|
|
5626
|
+
It must define
|
|
5627
|
+
`viewerRequest(event)`, as a function or a `var`/`let`/`const`.
|
|
5628
|
+
|
|
5629
|
+
> [NextjsDistributionProps.viewerRequestFunctionCode *](NextjsDistributionProps.viewerRequestFunctionCode *)
|
|
5630
|
+
|
|
5631
|
+
---
|
|
5632
|
+
|
|
5633
|
+
##### `viewerRequestKeyValueStore`<sup>Optional</sup> <a name="viewerRequestKeyValueStore" id="cdk-nextjs.NextjsGlobalContainersProps.property.viewerRequestKeyValueStore"></a>
|
|
5634
|
+
|
|
5635
|
+
```typescript
|
|
5636
|
+
public readonly viewerRequestKeyValueStore: IKeyValueStore;
|
|
5637
|
+
```
|
|
5638
|
+
|
|
5639
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.IKeyValueStore
|
|
5640
|
+
- *Default:* none
|
|
5641
|
+
|
|
5642
|
+
A CloudFront KeyValueStore `viewerRequestFunctionCode` can read with `cf.kvs()`, so credentials stay out of the template.
|
|
5643
|
+
|
|
5644
|
+
> [NextjsDistributionProps.viewerRequestKeyValueStore *](NextjsDistributionProps.viewerRequestKeyValueStore *)
|
|
5645
|
+
|
|
5646
|
+
---
|
|
5647
|
+
|
|
5522
5648
|
### NextjsGlobalFunctionsConstructOverrides <a name="NextjsGlobalFunctionsConstructOverrides" id="cdk-nextjs.NextjsGlobalFunctionsConstructOverrides"></a>
|
|
5523
5649
|
|
|
5524
5650
|
#### Initializer <a name="Initializer" id="cdk-nextjs.NextjsGlobalFunctionsConstructOverrides.Initializer"></a>
|
|
@@ -5705,6 +5831,8 @@ const nextjsGlobalFunctionsProps: NextjsGlobalFunctionsProps = { ... }
|
|
|
5705
5831
|
| <code><a href="#cdk-nextjs.NextjsGlobalFunctionsProps.property.distribution">distribution</a></code> | <code>aws-cdk-lib.aws_cloudfront.Distribution</code> | Bring your own distribution. |
|
|
5706
5832
|
| <code><a href="#cdk-nextjs.NextjsGlobalFunctionsProps.property.functionGroups">functionGroups</a></code> | <code><a href="#cdk-nextjs.NextjsFunctionGroup">NextjsFunctionGroup</a>[]</code> | Package sets of routes into separate Lambda functions, each fronted by its own CloudFront behaviors. |
|
|
5707
5833
|
| <code><a href="#cdk-nextjs.NextjsGlobalFunctionsProps.property.overrides">overrides</a></code> | <code><a href="#cdk-nextjs.NextjsGlobalFunctionsOverrides">NextjsGlobalFunctionsOverrides</a></code> | Override props of any construct. |
|
|
5834
|
+
| <code><a href="#cdk-nextjs.NextjsGlobalFunctionsProps.property.viewerRequestFunctionCode">viewerRequestFunctionCode</a></code> | <code>aws-cdk-lib.aws_cloudfront.FunctionCode</code> | CloudFront Function code run first on every viewer request, static assets included — HTTP Basic auth on a pre-launch site, say. |
|
|
5835
|
+
| <code><a href="#cdk-nextjs.NextjsGlobalFunctionsProps.property.viewerRequestKeyValueStore">viewerRequestKeyValueStore</a></code> | <code>aws-cdk-lib.aws_cloudfront.IKeyValueStore</code> | A CloudFront KeyValueStore `viewerRequestFunctionCode` can read with `cf.kvs()`, so credentials stay out of the template. |
|
|
5708
5836
|
|
|
5709
5837
|
---
|
|
5710
5838
|
|
|
@@ -5934,6 +6062,39 @@ Override props of any construct.
|
|
|
5934
6062
|
|
|
5935
6063
|
---
|
|
5936
6064
|
|
|
6065
|
+
##### `viewerRequestFunctionCode`<sup>Optional</sup> <a name="viewerRequestFunctionCode" id="cdk-nextjs.NextjsGlobalFunctionsProps.property.viewerRequestFunctionCode"></a>
|
|
6066
|
+
|
|
6067
|
+
```typescript
|
|
6068
|
+
public readonly viewerRequestFunctionCode: FunctionCode;
|
|
6069
|
+
```
|
|
6070
|
+
|
|
6071
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.FunctionCode
|
|
6072
|
+
- *Default:* none
|
|
6073
|
+
|
|
6074
|
+
CloudFront Function code run first on every viewer request, static assets included — HTTP Basic auth on a pre-launch site, say.
|
|
6075
|
+
|
|
6076
|
+
It must define
|
|
6077
|
+
`viewerRequest(event)`, as a function or a `var`/`let`/`const`.
|
|
6078
|
+
|
|
6079
|
+
> [NextjsDistributionProps.viewerRequestFunctionCode *](NextjsDistributionProps.viewerRequestFunctionCode *)
|
|
6080
|
+
|
|
6081
|
+
---
|
|
6082
|
+
|
|
6083
|
+
##### `viewerRequestKeyValueStore`<sup>Optional</sup> <a name="viewerRequestKeyValueStore" id="cdk-nextjs.NextjsGlobalFunctionsProps.property.viewerRequestKeyValueStore"></a>
|
|
6084
|
+
|
|
6085
|
+
```typescript
|
|
6086
|
+
public readonly viewerRequestKeyValueStore: IKeyValueStore;
|
|
6087
|
+
```
|
|
6088
|
+
|
|
6089
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.IKeyValueStore
|
|
6090
|
+
- *Default:* none
|
|
6091
|
+
|
|
6092
|
+
A CloudFront KeyValueStore `viewerRequestFunctionCode` can read with `cf.kvs()`, so credentials stay out of the template.
|
|
6093
|
+
|
|
6094
|
+
> [NextjsDistributionProps.viewerRequestKeyValueStore *](NextjsDistributionProps.viewerRequestKeyValueStore *)
|
|
6095
|
+
|
|
6096
|
+
---
|
|
6097
|
+
|
|
5937
6098
|
### NextjsPostDeployOverrides <a name="NextjsPostDeployOverrides" id="cdk-nextjs.NextjsPostDeployOverrides"></a>
|
|
5938
6099
|
|
|
5939
6100
|
#### Initializer <a name="Initializer" id="cdk-nextjs.NextjsPostDeployOverrides.Initializer"></a>
|
|
@@ -6974,7 +7135,7 @@ const nextjsStaticAssetsOverrides: NextjsStaticAssetsOverrides = { ... }
|
|
|
6974
7135
|
|
|
6975
7136
|
| **Name** | **Type** | **Description** |
|
|
6976
7137
|
| --- | --- | --- |
|
|
6977
|
-
| <code><a href="#cdk-nextjs.NextjsStaticAssetsOverrides.property.bucketDeploymentProps">bucketDeploymentProps</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeploymentProps</code> |
|
|
7138
|
+
| <code><a href="#cdk-nextjs.NextjsStaticAssetsOverrides.property.bucketDeploymentProps">bucketDeploymentProps</a></code> | <code>aws-cdk-lib.aws_s3_deployment.BucketDeploymentProps</code> | Applied to every upload (`public/`, `_next/static/` and `_next/static/service-worker/`), except that the two `_next/static` uploads always keep the `Cache-Control` Next.js sends for them. So a `cacheControl` here sets the header for `public/` files only, while anything else, such as a `distribution` to invalidate, applies to each upload in turn. |
|
|
6978
7139
|
| <code><a href="#cdk-nextjs.NextjsStaticAssetsOverrides.property.bucketProps">bucketProps</a></code> | <code>aws-cdk-lib.aws_s3.BucketProps</code> | *No description.* |
|
|
6979
7140
|
|
|
6980
7141
|
---
|
|
@@ -6987,6 +7148,14 @@ public readonly bucketDeploymentProps: BucketDeploymentProps;
|
|
|
6987
7148
|
|
|
6988
7149
|
- *Type:* aws-cdk-lib.aws_s3_deployment.BucketDeploymentProps
|
|
6989
7150
|
|
|
7151
|
+
Applied to every upload (`public/`, `_next/static/` and `_next/static/service-worker/`), except that the two `_next/static` uploads always keep the `Cache-Control` Next.js sends for them. So a `cacheControl` here sets the header for `public/` files only, while anything else, such as a `distribution` to invalidate, applies to each upload in turn.
|
|
7152
|
+
|
|
7153
|
+
`sources` and `destinationBucket`, which the type requires, are ignored:
|
|
7154
|
+
the uploads are always the build's assets, to the bucket CloudFront and
|
|
7155
|
+
API Gateway read from (pass `bucket` to bring your own). `prune: true` and
|
|
7156
|
+
`retainOnDelete: false` are rejected, since each would break the other
|
|
7157
|
+
uploads.
|
|
7158
|
+
|
|
6990
7159
|
---
|
|
6991
7160
|
|
|
6992
7161
|
##### `bucketProps`<sup>Optional</sup> <a name="bucketProps" id="cdk-nextjs.NextjsStaticAssetsOverrides.property.bucketProps"></a>
|
|
@@ -10862,6 +11031,8 @@ const optionalNextjsDistributionProps: OptionalNextjsDistributionProps = { ... }
|
|
|
10862
11031
|
| <code><a href="#cdk-nextjs.OptionalNextjsDistributionProps.property.maxCacheBehaviors">maxCacheBehaviors</a></code> | <code>number</code> | The most cache behaviors the distribution may have, the default one included. |
|
|
10863
11032
|
| <code><a href="#cdk-nextjs.OptionalNextjsDistributionProps.property.nextjsType">nextjsType</a></code> | <code><a href="#cdk-nextjs.NextjsType">NextjsType</a></code> | *No description.* |
|
|
10864
11033
|
| <code><a href="#cdk-nextjs.OptionalNextjsDistributionProps.property.publicDirEntries">publicDirEntries</a></code> | <code><a href="#cdk-nextjs.PublicDirEntry">PublicDirEntry</a>[]</code> | Entries (files/directories) within Next.js app's public directory. Used to add static behaviors to distribution. |
|
|
11034
|
+
| <code><a href="#cdk-nextjs.OptionalNextjsDistributionProps.property.viewerRequestFunctionCode">viewerRequestFunctionCode</a></code> | <code>aws-cdk-lib.aws_cloudfront.FunctionCode</code> | CloudFront Function code run first on every viewer request, on every behavior cdk-nextjs adds, static assets included — HTTP Basic auth on a pre-launch site, geo-gating. |
|
|
11035
|
+
| <code><a href="#cdk-nextjs.OptionalNextjsDistributionProps.property.viewerRequestKeyValueStore">viewerRequestKeyValueStore</a></code> | <code>aws-cdk-lib.aws_cloudfront.IKeyValueStore</code> | A CloudFront KeyValueStore associated with every viewer-request function {@link viewerRequestFunctionCode} is copied into (up to three, one per kind of behavior), so values it reads — Basic auth credentials, an allowlist — live outside the CloudFormation template and change without a deploy. |
|
|
10865
11036
|
|
|
10866
11037
|
---
|
|
10867
11038
|
|
|
@@ -11010,6 +11181,43 @@ Entries (files/directories) within Next.js app's public directory. Used to add s
|
|
|
11010
11181
|
|
|
11011
11182
|
---
|
|
11012
11183
|
|
|
11184
|
+
##### `viewerRequestFunctionCode`<sup>Optional</sup> <a name="viewerRequestFunctionCode" id="cdk-nextjs.OptionalNextjsDistributionProps.property.viewerRequestFunctionCode"></a>
|
|
11185
|
+
|
|
11186
|
+
```typescript
|
|
11187
|
+
public readonly viewerRequestFunctionCode: FunctionCode;
|
|
11188
|
+
```
|
|
11189
|
+
|
|
11190
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.FunctionCode
|
|
11191
|
+
- *Default:* none
|
|
11192
|
+
|
|
11193
|
+
CloudFront Function code run first on every viewer request, on every behavior cdk-nextjs adds, static assets included — HTTP Basic auth on a pre-launch site, geo-gating.
|
|
11194
|
+
|
|
11195
|
+
It must define `viewerRequest(event)` (a function, sync or async, or a
|
|
11196
|
+
`var`/`let`/`const`): return a response to answer the viewer, or the
|
|
11197
|
+
request (or nothing) to carry on. It is spliced into cdk-nextjs's own
|
|
11198
|
+
viewer-request functions, ahead of their logic, so it may not use the
|
|
11199
|
+
name `handler`, and the combined function must fit CloudFront's 10 KB.
|
|
11200
|
+
It runs on `cloudfront-js-2.0`, so it may be async and read
|
|
11201
|
+
{@link viewerRequestKeyValueStore} with `cf.kvs()`. A bring-your-own
|
|
11202
|
+
{@link distribution}'s default behavior isn't covered.
|
|
11203
|
+
|
|
11204
|
+
---
|
|
11205
|
+
|
|
11206
|
+
##### `viewerRequestKeyValueStore`<sup>Optional</sup> <a name="viewerRequestKeyValueStore" id="cdk-nextjs.OptionalNextjsDistributionProps.property.viewerRequestKeyValueStore"></a>
|
|
11207
|
+
|
|
11208
|
+
```typescript
|
|
11209
|
+
public readonly viewerRequestKeyValueStore: IKeyValueStore;
|
|
11210
|
+
```
|
|
11211
|
+
|
|
11212
|
+
- *Type:* aws-cdk-lib.aws_cloudfront.IKeyValueStore
|
|
11213
|
+
- *Default:* none
|
|
11214
|
+
|
|
11215
|
+
A CloudFront KeyValueStore associated with every viewer-request function {@link viewerRequestFunctionCode} is copied into (up to three, one per kind of behavior), so values it reads — Basic auth credentials, an allowlist — live outside the CloudFormation template and change without a deploy.
|
|
11216
|
+
|
|
11217
|
+
Read it with `cf.kvs()`, no ID needed.
|
|
11218
|
+
|
|
11219
|
+
---
|
|
11220
|
+
|
|
11013
11221
|
### OptionalNextjsPostDeployProps <a name="OptionalNextjsPostDeployProps" id="cdk-nextjs.OptionalNextjsPostDeployProps"></a>
|
|
11014
11222
|
|
|
11015
11223
|
OptionalNextjsPostDeployProps.
|
package/README.md
CHANGED
|
@@ -36,6 +36,17 @@ Deploy [Next.js](https://nextjs.org/) apps on [AWS](https://aws.amazon.com/) wit
|
|
|
36
36
|
- [Bring Your Own Resources](#bring-your-own-resources) — import existing AWS resources (CloudFront distributions, ECS clusters, ALBs, S3 buckets, DynamoDB tables).
|
|
37
37
|
- [AWS GovCloud (US)](https://aws.amazon.com/govcloud-us) compatible with `NextjsRegionalFunctions` and `NextjsRegionalContainers`.
|
|
38
38
|
|
|
39
|
+
## Why
|
|
40
|
+
|
|
41
|
+
The simplest path to deploy Next.js is on [Vercel](https://vercel.com/) - the Platform-as-a-Service company behind Next.js. However, deploying to Vercel can be expensive and some developers want all of their workloads running _directly_ on AWS. Developers can deploy Next.js on AWS through [AWS Amplify Hosting](https://docs.aws.amazon.com/amplify/latest/userguide/ssr-Amplifysupport.html), but Amplify does not support all Next.js features and manages AWS resources for you so they cannot be customized. If Amplify meets your requirements we recommend you use it, but if you want to use all Next.js features or want more visibility into the AWS resources then this construct is for you.
|
|
42
|
+
|
|
43
|
+
## Design Principles
|
|
44
|
+
|
|
45
|
+
- Integrate through Next.js's official interfaces. Build on the [Deployment Adapter](https://nextjs.org/docs/app/guides/deployment-adapters) API and [`@next/routing`](https://www.npmjs.com/package/@next/routing) rather than Next.js internals, so new Next.js versions rarely break this construct. Where no public interface exists yet, the dependency is listed in [Next.js private APIs](docs/nextjs-private-apis.md).
|
|
46
|
+
- Security first.
|
|
47
|
+
- One architecture does not fit all.
|
|
48
|
+
- Enable customization everywhere.
|
|
49
|
+
|
|
39
50
|
## Prerequisites
|
|
40
51
|
|
|
41
52
|
- Next.js app running v16.3 or higher (`next build` fails on older versions). If you don't have one yet - follow [these steps](https://nextjs.org/docs/getting-started) to create one.
|
|
@@ -102,6 +113,34 @@ new WebStack(app, "web-stack");
|
|
|
102
113
|
|
|
103
114
|
See [examples/](./examples/) for more usage examples.
|
|
104
115
|
|
|
116
|
+
## Architecture
|
|
117
|
+
|
|
118
|
+
How requests are served inside the compute — the adapter runtime, and where it deliberately differs from `next start` — is in [docs/adapter-runtime.md](./docs/adapter-runtime.md).
|
|
119
|
+
|
|
120
|
+
### `NextjsGlobalFunctions`
|
|
121
|
+
|
|
122
|
+
Architecture includes [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) Functions to respond to dynamic requests and [CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) Distribution to globally serve requests and distribute static assets. Use this construct when you have unpredictable traffic, can afford occasional latency (i.e. cold starts - [typically 1% of production traffic](https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-1/)), and/or want the most granular pricing model. ([code](./src/root-constructs/nextjs-global-functions.ts))
|
|
123
|
+
|
|
124
|
+

|
|
125
|
+
|
|
126
|
+
### `NextjsGlobalContainers`
|
|
127
|
+
|
|
128
|
+
Architecture includes [ECS Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html) containers to respond to dynamic requests and [CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) Distribution to globally serve requests and distribute static assets. Use this option when you have predictable traffic, need the lowest latency, and/or can afford a less granular pricing model. ([code](./src/root-constructs/nextjs-global-containers.ts))
|
|
129
|
+
|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
### `NextjsRegionalContainers`
|
|
133
|
+
|
|
134
|
+
Architecture includes [ECS Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html) containers to respond to dynamic requests and [Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/) to regionally serve requests. Use this options when you cannot use Amazon CloudFront (i.e. [AWS GovCloud](https://aws.amazon.com/govcloud-us/?whats-new.sort-by=item.additionalFields.postDateTime&whats-new.sort-order=desc)). ([code](./src/root-constructs/nextjs-regional-containers.ts#L41))
|
|
135
|
+
|
|
136
|
+

|
|
137
|
+
|
|
138
|
+
### `NextjsRegionalFunctions`
|
|
139
|
+
|
|
140
|
+
Architecture includes [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) Functions to respond to dynamic requests and [API Gateway REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html) to regionally serve requests and distribute static assets. Use this options when you cannot use Amazon CloudFront (i.e. [AWS GovCloud](https://aws.amazon.com/govcloud-us/?whats-new.sort-by=item.additionalFields.postDateTime&whats-new.sort-order=desc)). ([code](./src/root-constructs/nextjs-regional-functions.ts))
|
|
141
|
+
|
|
142
|
+

|
|
143
|
+
|
|
105
144
|
## Configuration
|
|
106
145
|
|
|
107
146
|
The variables below are read at runtime by the cache handler inside your deployed
|
|
@@ -415,114 +454,90 @@ Notes:
|
|
|
415
454
|
- Per-group `overrides` let you size each function independently:
|
|
416
455
|
`{ name: "reports", routes: [...], overrides: { functionProps: { memorySize: 2048 } } }`.
|
|
417
456
|
|
|
418
|
-
##
|
|
457
|
+
## Running Code on Every Viewer Request
|
|
419
458
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
```mermaid
|
|
427
|
-
architecture-beta
|
|
428
|
-
group aws(cloud)[AWS Cloud]
|
|
429
|
-
group cache[Cache Layer] in aws
|
|
430
|
-
|
|
431
|
-
service user(internet)[User]
|
|
432
|
-
service cloudfront(server)[CloudFront Distribution] in aws
|
|
433
|
-
service s3static(disk)[S3 Static Assets] in aws
|
|
434
|
-
service lambda(server)[Lambda Function] in aws
|
|
435
|
-
service dynamodb(database)[DynamoDB Table] in cache
|
|
436
|
-
service s3cache(disk)[S3 Cache Bucket] in cache
|
|
437
|
-
|
|
438
|
-
user:R --> L:cloudfront
|
|
439
|
-
cloudfront:R --> L:s3static
|
|
440
|
-
cloudfront:R --> L:lambda
|
|
441
|
-
lambda:R --> L:dynamodb
|
|
442
|
-
lambda:R --> L:s3cache
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### `NextjsGlobalContainers`
|
|
446
|
-
|
|
447
|
-
Architecture includes [ECS Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html) containers to respond to dynamic requests and [CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) Distribution to globally serve requests and distribute static assets. Use this option when you have predictable traffic, need the lowest latency, and/or can afford a less granular pricing model. ([code](./src/root-constructs/nextjs-global-containers.ts))
|
|
448
|
-
|
|
449
|
-
```mermaid
|
|
450
|
-
architecture-beta
|
|
451
|
-
group aws(cloud)[AWS Cloud]
|
|
452
|
-
group vpc[VPC] in aws
|
|
453
|
-
group cache[Cache Layer] in aws
|
|
454
|
-
|
|
455
|
-
service user(internet)[User]
|
|
456
|
-
service cloudfront(server)[CloudFront Distribution] in aws
|
|
457
|
-
service s3static(disk)[S3 Static Assets] in aws
|
|
458
|
-
service alb(server)[Application Load Balancer] in vpc
|
|
459
|
-
service fargate(server)[ECS Fargate Containers] in vpc
|
|
460
|
-
service dynamodb(database)[DynamoDB Table] in cache
|
|
461
|
-
service s3cache(disk)[S3 Cache Bucket] in cache
|
|
462
|
-
|
|
463
|
-
user:R --> L:cloudfront
|
|
464
|
-
cloudfront:R --> L:s3static
|
|
465
|
-
cloudfront:R --> L:alb
|
|
466
|
-
alb:R --> L:fargate
|
|
467
|
-
fargate:R --> L:dynamodb
|
|
468
|
-
fargate:R --> L:s3cache
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### `NextjsRegionalContainers`
|
|
459
|
+
`NextjsGlobalFunctions` and `NextjsGlobalContainers` take a
|
|
460
|
+
`viewerRequestFunctionCode` prop: CloudFront Function code that runs first on
|
|
461
|
+
every request, on every behavior cdk-nextjs adds — pages, API routes,
|
|
462
|
+
`_next/image`, `_next/static` and `public/` files alike. It's the place for a
|
|
463
|
+
gate the whole site has to pass, such as HTTP Basic auth before launch:
|
|
472
464
|
|
|
473
|
-
|
|
465
|
+
```ts
|
|
466
|
+
import { FunctionCode, KeyValueStore } from "aws-cdk-lib/aws-cloudfront";
|
|
474
467
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
468
|
+
const credentials = new KeyValueStore(this, "Credentials");
|
|
469
|
+
new NextjsGlobalFunctions(this, "Nextjs", {
|
|
470
|
+
buildDirectory: join(import.meta.dirname),
|
|
471
|
+
viewerRequestKeyValueStore: credentials,
|
|
472
|
+
viewerRequestFunctionCode: FunctionCode.fromInline(`
|
|
473
|
+
import cf from "cloudfront";
|
|
474
|
+
const kvs = cf.kvs();
|
|
475
|
+
async function viewerRequest(event) {
|
|
476
|
+
const auth = event.request.headers.authorization;
|
|
477
|
+
try {
|
|
478
|
+
if (auth && auth.value === "Basic " + (await kvs.get("basic-auth"))) {
|
|
479
|
+
// verified: don't pass the site's credentials on to the origin
|
|
480
|
+
delete event.request.headers.authorization;
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
} catch (e) {
|
|
484
|
+
// no "basic-auth" key yet: stay locked
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
statusCode: 401,
|
|
488
|
+
statusDescription: "Unauthorized",
|
|
489
|
+
headers: { "www-authenticate": { value: 'Basic realm="preview"' } },
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
`),
|
|
493
|
+
});
|
|
491
494
|
```
|
|
492
495
|
|
|
493
|
-
|
|
496
|
+
Then put the credentials in the store, outside the template:
|
|
494
497
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
service user(internet)[User]
|
|
503
|
-
service apigateway(server)[API Gateway REST API] in aws
|
|
504
|
-
service s3static(disk)[S3 Static Assets] in aws
|
|
505
|
-
service lambda(server)[Lambda Function] in aws
|
|
506
|
-
service dynamodb(database)[DynamoDB Table] in cache
|
|
507
|
-
service s3cache(disk)[S3 Cache Bucket] in cache
|
|
508
|
-
|
|
509
|
-
user:R --> L:apigateway
|
|
510
|
-
apigateway:R --> L:s3static
|
|
511
|
-
apigateway:R --> L:lambda
|
|
512
|
-
lambda:R --> L:dynamodb
|
|
513
|
-
lambda:R --> L:s3cache
|
|
498
|
+
```sh
|
|
499
|
+
KVS_ARN=... # the store's ARN
|
|
500
|
+
aws cloudfront-keyvaluestore put-key --kvs-arn "$KVS_ARN" \
|
|
501
|
+
--key basic-auth --value "$(printf 'user:pass' | base64 | tr -d '\n')" \
|
|
502
|
+
--if-match "$(aws cloudfront-keyvaluestore describe-key-value-store \
|
|
503
|
+
--kvs-arn "$KVS_ARN" --query ETag --output text)"
|
|
514
504
|
```
|
|
515
505
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
-
|
|
524
|
-
-
|
|
525
|
-
-
|
|
506
|
+
The code must define `viewerRequest(event)`, as a function (`async` or not)
|
|
507
|
+
or a `var`/`let`/`const`. It's a CloudFront Function handler in all but name:
|
|
508
|
+
return a response to answer the viewer, or the request (or nothing) to carry
|
|
509
|
+
on.
|
|
510
|
+
|
|
511
|
+
Why not a function of your own on viewer-request? CloudFront allows one per
|
|
512
|
+
event type per behavior, and on Global Functions cdk-nextjs's own one
|
|
513
|
+
overwrites `X-Forwarded-Host` and redirects repeated slashes. So your code is
|
|
514
|
+
spliced into that function, ahead of cdk-nextjs's logic, which still runs after
|
|
515
|
+
it, so your code can't undo the `X-Forwarded-Host` overwrite. Middleware can't
|
|
516
|
+
do this instead: on Global Functions CloudFront signs the request to the
|
|
517
|
+
Function URL with the `Authorization` header, and static assets never reach the
|
|
518
|
+
server at all.
|
|
519
|
+
|
|
520
|
+
- cdk-nextjs's CloudFront Functions run on `cloudfront-js-2.0`, so your code
|
|
521
|
+
can be `async`, and `import cf from "cloudfront"` works when it comes first,
|
|
522
|
+
as it does above.
|
|
523
|
+
- `viewerRequestKeyValueStore` is associated with every viewer-request function
|
|
524
|
+
your code is copied into (up to three, one per kind of behavior), so
|
|
525
|
+
`cf.kvs()` reads it with no ID wherever the code runs. Credentials written
|
|
526
|
+
inline in the code instead end up in the CloudFormation template.
|
|
527
|
+
- The combined function, cdk-nextjs's code included, must fit CloudFront's
|
|
528
|
+
10 KB limit; synth fails if it doesn't (or warns, if the code contains a
|
|
529
|
+
CDK token, whose size isn't known until deploy).
|
|
530
|
+
- Your code shares the file with cdk-nextjs's `handler`, so it can't use the
|
|
531
|
+
name `handler` at all, even in a comment or a string; synth refuses it.
|
|
532
|
+
- A viewer-request association in `overrides.*BehaviorOptions.functionAssociations`
|
|
533
|
+
on a behavior this covers is refused at synth; put that logic in
|
|
534
|
+
`viewerRequestFunctionCode` instead. So is
|
|
535
|
+
`overrides.distributionProps.defaultBehavior` without a `basePath`, since it
|
|
536
|
+
would replace the default behavior the code runs on; customize it through
|
|
537
|
+
`overrides.dynamicBehaviorOptions`.
|
|
538
|
+
- A bring-your-own `distribution`'s default behavior is yours, so it isn't
|
|
539
|
+
covered. Only the behaviors cdk-nextjs adds are; under a `basePath`, those
|
|
540
|
+
include the ones that stand in for the default behavior.
|
|
526
541
|
|
|
527
542
|
## Bring Your Own Resources
|
|
528
543
|
|
|
@@ -542,7 +557,7 @@ cdk-nextjs supports importing existing AWS resources instead of creating new one
|
|
|
542
557
|
### Resource Isolation
|
|
543
558
|
|
|
544
559
|
- **Cache bucket and DynamoDB table** must be dedicated to one deployment. Sharing either between deployments (branches, stages, apps) is not supported: each deploy's post-deploy step prunes every cache object and revalidation entry that isn't from its own current build, so deploying one branch wipes the others' caches. Buckets and tables are cheap, so give each deployment its own, or leave `cacheBucket`/`revalidationTable` unset and let cdk-nextjs create them (they are removed with the stack).
|
|
545
|
-
- **Static assets bucket** can be shared, but only between deployments with different `basePath`s, which become their S3 key prefixes. Pruning only looks at `<basePath>/_next/`, so it never touches another prefix. Two deployments under the same prefix (for example two subdomain previews both at the root) overwrite each other's `public/` files and prune each other's `_next/` assets once they are past the prune TTL (30 days by default), so give those their own buckets. `NextjsGlobalFunctions` and `NextjsGlobalContainers` read the `basePath` out of your Next.js build and use it as the S3 key prefix, since CloudFront serves assets from S3 by request path and the two can't differ. Set the `basePath` prop only if you want to be explicit about it; a value that disagrees with your app's fails at synth.
|
|
560
|
+
- **Static assets bucket** can be shared, but only between deployments with different `basePath`s, which become their S3 key prefixes. Pruning only looks at `<basePath>/_next/`, so it never touches another prefix. Two deployments under the same prefix (for example two subdomain previews both at the root) overwrite each other's `public/` files and prune each other's `_next/` assets once they are past the prune TTL (30 days by default), so give those their own buckets. `NextjsGlobalFunctions` and `NextjsGlobalContainers` read the `basePath` out of your Next.js build and use it as the S3 key prefix, since CloudFront serves assets from S3 by request path and the two can't differ. Set the `basePath` prop only if you want to be explicit about it; a value that disagrees with your app's fails at synth. Each deployment also adds an ownership tag per static asset upload (1 to 3, by whether the build has `public/` files and service workers) to a bucket created in your CDK app; an imported bucket gets none. S3 allows 50 tags per bucket, so such a bucket holds at least 16 deployments.
|
|
546
561
|
|
|
547
562
|
### Shared ALB and `removeAutoCreatedListener()`
|
|
548
563
|
|
package/docs/breaking-changes.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Breaking Changes
|
|
2
2
|
|
|
3
|
+
## 0.7.12
|
|
4
|
+
|
|
5
|
+
### Static assets are uploaded by one deployment per `Cache-Control`
|
|
6
|
+
|
|
7
|
+
`NextjsStaticAssets` now uploads `_next/static/` with
|
|
8
|
+
`public, max-age=31536000, immutable` and `_next/static/service-worker/` with
|
|
9
|
+
`public, max-age=0, must-revalidate`, the headers Next.js sends for them, and
|
|
10
|
+
`public/` separately. Before, a single `BucketDeployment` uploaded everything
|
|
11
|
+
with no `Cache-Control`. Nothing changes unless you set
|
|
12
|
+
`overrides.nextjsStaticAssets.bucketDeploymentProps` or read
|
|
13
|
+
`NextjsStaticAssets.deployment`:
|
|
14
|
+
|
|
15
|
+
- **`prune: true` and `retainOnDelete: false` fail synth.** Each override now
|
|
16
|
+
reaches every upload. `prune: true` would make each one delete the files the
|
|
17
|
+
others uploaded. With `retainOnDelete: false`, a change of key prefix makes
|
|
18
|
+
each upload delete the old prefix while the others are writing theirs.
|
|
19
|
+
**Migration:** drop both. Old assets are already pruned after deploy by
|
|
20
|
+
`NextjsPostDeploy`, once they are past its TTL (`overrides.nextjsPostDeploy`).
|
|
21
|
+
- **`sources` and `destinationBucket` are ignored.** CDK's type requires them,
|
|
22
|
+
but either one replaced the build's assets, or sent them to a bucket
|
|
23
|
+
CloudFront and API Gateway don't read from. **Migration:** pass your bucket
|
|
24
|
+
as `staticAssetsBucket` instead, and add your own `BucketDeployment` for
|
|
25
|
+
extra files.
|
|
26
|
+
- **`cacheControl` applies to `public/` files only.** The `_next/static` uploads
|
|
27
|
+
always keep Next.js's headers.
|
|
28
|
+
- **`NextjsStaticAssets.deployment` is deprecated.** It is now the
|
|
29
|
+
`_next/static` upload alone (or the first upload the build has), so a
|
|
30
|
+
dependency on it no longer waits for `public/`. **Migration:** depend on
|
|
31
|
+
`staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`, each
|
|
32
|
+
present only when the build has files for it. `NextjsPostDeploy` already
|
|
33
|
+
waits for all of them.
|
|
34
|
+
|
|
3
35
|
## 0.7.0
|
|
4
36
|
|
|
5
37
|
### Requests are served through the adapter runtime, not `next start`
|
|
@@ -415,8 +447,10 @@ absolute URLs, cached for other viewers). Now:
|
|
|
415
447
|
|
|
416
448
|
- associations on other event types (viewer-response, say) are added next to it;
|
|
417
449
|
- an association on viewer-request throws at synth, since CloudFront allows one
|
|
418
|
-
function per event type per behavior. Move that logic
|
|
419
|
-
|
|
450
|
+
function per event type per behavior. Move that logic into the
|
|
451
|
+
`viewerRequestFunctionCode` prop, which runs it inside cdk-nextjs's own
|
|
452
|
+
viewer-request function on every behavior, static assets included (see
|
|
453
|
+
[Running Code on Every Viewer Request](../README.md#running-code-on-every-viewer-request)).
|
|
420
454
|
|
|
421
455
|
The runtime trusts `X-Forwarded-Host` only on a request Lambda reports as
|
|
422
456
|
IAM-authenticated, so a Function URL overridden to `authType: NONE` builds its
|
|
@@ -66,3 +66,13 @@ Both `build` and `dev` chain it explicitly (`npm run sync-cdk-nextjs && next …
|
|
|
66
66
|
For iterative development, just run `pnpm build` from the root to rebuild the adapter, then `pnpm build` in the example app—the sync step will copy the latest version.
|
|
67
67
|
|
|
68
68
|
Note that `pnpm install` recreates the `link:../..` symlink, so always go through `pnpm build` / `pnpm dev`. Invoking `next build` or `next dev` directly skips the sync and Turbopack then fails on the symlinked path, e.g. `FileSystemPath("app-playground").join("./../../lib/adapter/cache-handler.mjs") leaves the filesystem root`.
|
|
69
|
+
|
|
70
|
+
## Architecture Diagrams
|
|
71
|
+
|
|
72
|
+
The README's architecture diagrams are Mermaid [`architecture-beta`](https://mermaid.js.org/syntax/architecture.html) sources in [`docs/diagrams/`](./diagrams/), rendered to SVG with AWS icons from the Iconify [`logos`](https://icon-sets.iconify.design/logos/?keyword=aws) set (`logos:aws-lambda`, `logos:aws-cloudfront`, ...). After editing a `.mmd` file:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pnpm diagrams
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Commit the `.mmd` and the regenerated `.svg` together. `pnpm test` fails if an SVG is stale against its source. The README links the SVGs on `main`, so a PR's README preview shows the old diagrams until it merges; open the SVG in the PR's files view to see the new one.
|