
Deploying Next.js 15 to AWS CloudFront with CDK
Stewart Moreland
What You'll Learn
In this guide, we will walk through deploying a Next.js 15 application to AWS CloudFront using the AWS CDK and the cdk-nextjs construct, covering project initialization, installing the construct, configuring Next.js for standalone output, defining the CDK stack (with CloudFront, S3, Lambda), setting up a custom domain with ACM in us-east-1 and Route 53 alias records, and finally executing cdk deploy to launch the infrastructure.
Prerequisites
Required Setup
Before starting this deployment guide, ensure you have the following prerequisites configured:
- AWS Account with permissions to create CloudFormation stacks, S3 buckets, Lambda functions, CloudFront distributions, ACM certificates, and Route 53 records.
- AWS CLI configured with appropriate credentials (
aws configure). - AWS CDK v2 CLI installed globally:
npm install -g aws-cdk
Verify with cdk --version (docs.aws.amazon.com).
- Node.js (LTS recommended) and npm installed.
- Docker installed if you plan to build containerized Lambda functions (optional for
NextjsGlobalFunctions) (github.com). - Route 53 Hosted Zone for your custom domain (optional, if using a custom domain).
Make sure to bootstrap your AWS environment once per account/region before proceeding with deployment.
Initialize Your CDK Project
Step 1: Create Project Structure
mkdir infrastructurecd infrastructurecdk init app --language typescript
This bootstraps a basic CDK project with bin/ and lib/ folders (docs.aws.amazon.com).
Step 2: Bootstrap AWS Environment
cdk bootstrap
Bootstrap Purpose
This creates the CDK toolkit stack with resources CDK needs to deploy. This step is required once per account/region combination.
Install and Configure cdk-nextjs
Install the Package
npm install cdk-nextjs
This library provides high-level constructs for deploying Next.js apps on AWS (github.com).
Configure Next.js for Standalone Output
In your Next.js application root (outside infrastructure/), update next.config.js:
/** @type {import('next').NextConfig} */const nextConfig = {output: 'standalone',reactStrictMode: true,};module.exports = nextConfig;
The standalone output ensures your build artifacts can run independently of Next.js internals, which is required for Lambda deployment.
Define the CDK Stack with NextjsGlobalFunctions
Create your main stack configuration in lib/nextjs-stack.ts:
import { App, Stack, StackProps } from 'aws-cdk-lib';import { Construct } from 'constructs';import { NextjsGlobalFunctions } from 'cdk-nextjs';import { join } from 'path';export class NextjsStack extends Stack {constructor(scope: Construct, id: string, props?: StackProps) {super(scope, id, props);new NextjsGlobalFunctions(this, 'NextJsApp', {// Path to your Next.js project rootbuildContext: join(__dirname, '..', 'path-to-next-app'),// (Optional) health check endpointhealthCheckPath: '/api/health',// (Optional) overrides for fine-tuning CloudFront / Lambda// overrides: { nextjsDistribution: { ... }, nextjsFunctions: { ... } },});}}const app = new App();new NextjsStack(app, 'NextJsStack');
What NextjsGlobalFunctions Provides
Infrastructure Components
The NextjsGlobalFunctions construct automatically sets up:
- CloudFront Distribution for global CDN delivery
- Amazon S3 for static asset storage (JS/CSS/public files)
- AWS Lambda functions for dynamic SSR routes
CloudFront supports a maximum of 25 behaviors. Group static assets under /static to avoid exceeding this limit.
Alternative Constructs
You can choose other constructs based on your architecture needs:
NextjsGlobalContainers- For containerized deploymentsNextjsRegionalContainers- For single-region container deployments
Add Custom Domain and SSL (ACM + Route 53)
Step 1: Request ACM Certificate
Critical: US East Region
ACM certificates used by CloudFront must be in the us-east-1 (N. Virginia) region. This is a CloudFront requirement.
aws acm request-certificate \--domain-name example.com \--validation-method DNS \--region us-east-1
Step 2: DNS Validation
Validate the certificate by adding the CNAME records ACM returns into your Route 53 hosted zone.
Step 3: Configure Domain in CDK
Update your stack to include custom domain configuration:
import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';new NextjsGlobalFunctions(this, 'NextJsApp', {buildContext: join(__dirname, '..', 'path-to-next-app'),domainNames: ['example.com', 'www.example.com'],certificate: Certificate.fromCertificateArn(this,'SiteCert','arn:aws:acm:us-east-1:123456789012:certificate/abcd-efgh-...'),});
Step 4: Route 53 Alias Record
ALIAS vs CNAME
Using Route 53's ALIAS record lets you map apex domains (example.com) directly, unlike CNAME records which cannot be used for apex domains.
Create an ALIAS A record pointing example.com → your CloudFront distribution domain. In Route 53:
- Choose "Alias to CloudFront distribution"
- Select your distribution
- Region will pre-select us-east-1
Deploy Your Application
Synthesize and Deploy
cdk synth
Deployment Complete
Once deployment completes, the stack outputs will include your CloudFront URL and (if configured) your custom domain. Visit your domain over HTTPS to see your Next.js 15 app live.
Post-Deployment Considerations
Cache Invalidation
For ISR (revalidation) or content updates, manually create invalidations:
aws cloudfront create-invalidation \--distribution-id YOUR_DISTRIBUTION_ID \--paths '/*'
Wire a CodeBuild/CodePipeline step to automate cache invalidation on each deploy for seamless updates.
Monitoring & Logging
Observability Setup
Configure proper monitoring and logging for production deployments:
- Enable CloudFront Access Logs for request analytics
- Set up Lambda Function Logs in CloudWatch for troubleshooting
- Create CloudWatch Alarms for 5xx errors and high latency
- Monitor costs with AWS Cost Explorer
Security Enhancements
import { WebAcl } from 'aws-cdk-lib/aws-wafv2';const webAcl = new WebAcl(this, 'WebAcl', {scope: Scope.CLOUDFRONT,defaultAction: WafAction.allow(),rules: [// Add rate limiting and IP blocking rules],});
Troubleshooting Common Issues
Build Failures
Common Build Issues
- Memory limits: Increase Lambda memory for large Next.js bundles
- Timeout errors: Extend Lambda timeout for complex SSR operations
- Dependencies: Ensure all dependencies are properly bundled
Domain Configuration
Remember: ACM certificates for CloudFront must be in us-east-1, regardless of your application's primary region.
Deployment Success
By following these steps, you'll have a fully managed, globally distributed Next.js 15 application running on AWS, with infrastructure defined entirely in CDK and taking full advantage of the cdk-nextjs construct's best practices.
Consider setting up automated CI/CD pipelines and monitoring dashboards to complete your production deployment workflow.