Deploy Next.js to AWS Amplify: Step-by-Step Guide (2026)
On this page
AWS Amplify has become one of the most reliable ways to deploy Next.js applications outside of Vercel. With Amplify Gen 2, AWS now supports the App Router, Server Components, ISR, and middleware. This guide walks you through the entire process from zero to production.
TL;DR: A practical guide to deploying Next.js applications on AWS Amplify Gen 2 with custom domains, environment variables, and CI/CD.
Prerequisites
- An AWS account
- A Next.js application (App Router or Pages Router)
- Your code in a Git repository (GitHub, GitLab, or Bitbucket)
- AWS CLI installed and configured (optional but helpful)
Step 1: Prepare Your Next.js App
Before deploying, ensure your next.config.js is Amplify-compatible:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
output: 'standalone',
images: {
unoptimized: false, // Amplify supports Next.js image optimization
},
};
export default nextConfig;
The standalone output mode is recommended for Amplify as it produces a self-contained build that includes only the necessary dependencies.
Check Your Node Version
Create or update your .nvmrc file:
20
Amplify uses this to determine which Node.js version to use during builds.
Step 2: Connect Your Repository
- Open the AWS Amplify Console
- Click Create new app
- Select your Git provider and authorize access
- Choose your repository and branch
- Amplify automatically detects Next.js and configures the build settings
Build Settings
Amplify generates an amplify.yml file. Here is a production-ready configuration:
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
- .next/cache/**/*
The .next/cache entry is important. It caches build artifacts between deployments, significantly reducing build times for subsequent deploys.
Step 3: Configure Environment Variables
In the Amplify Console, go to App settings > Environment variables. Add your variables:
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgresql://user:pass@host:5432/db
NEXTAUTH_SECRET=your-secret-here
NEXTAUTH_URL=https://yourdomain.com
Variables prefixed with NEXT_PUBLIC_ are exposed to the client bundle. All others are server-only.
Per-Branch Environment Variables
Amplify supports branch-specific overrides. Set different API URLs for staging and production:
# main branch
NEXT_PUBLIC_API_URL=https://api.example.com
# develop branch (override)
NEXT_PUBLIC_API_URL=https://api-staging.example.com
Step 4: Custom Domain Setup
Using an Amplify-Managed Domain
- Go to App settings > Domain management
- Click Add domain
- Enter your domain name
- Amplify will provide DNS records to add to your registrar
Using Route 53
If your domain is in Route 53, Amplify can configure DNS automatically:
- Select your Route 53 hosted zone
- Amplify creates the necessary A and CNAME records
- SSL certificates are provisioned automatically via ACM
Subdomain Configuration
Map branches to subdomains:
main → yourdomain.com, www.yourdomain.com
develop → dev.yourdomain.com
staging → staging.yourdomain.com
Step 5: Handling Common Deployment Issues
Issue: Build Fails with Memory Error
Next.js builds can be memory-intensive. Increase the build memory:
# amplify.yml
frontend:
phases:
build:
commands:
- NODE_OPTIONS=--max-old-space-size=4096 npm run build
Issue: API Routes Return 500 Errors
Check that your environment variables are correctly set. A common mistake is forgetting to add DATABASE_URL or other server-side variables in the Amplify Console.
Verify your API route works locally first:
npm run build && npm start
curl http://localhost:3000/api/health
Issue: Images Not Loading
If using next/image with external sources, add them to your config:
// next.config.ts
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.example.com',
pathname: '/uploads/**',
},
],
},
};
Issue: Middleware Not Working
Amplify Gen 2 supports Next.js middleware. Ensure your middleware.ts is at the root of your project (not inside app/ or src/):
// middleware.ts (project root)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const authToken = request.cookies.get('auth-token');
if (!authToken && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*'],
};
Step 6: CI/CD Pipeline
Every push to your connected branch triggers an automatic build and deploy. Monitor builds in the Amplify Console under Build history.
Build Notifications
Set up email or Slack notifications for build events:
- Go to App settings > Notifications
- Add an email address or SNS topic
- Choose which events to notify on (build started, succeeded, failed)
Preview Deployments
Enable pull request previews for code review:
- Go to App settings > Previews
- Enable previews
- Each PR gets a unique URL like
pr-42.d1234abc.amplifyapp.com
Step 7: Monitoring and Logs
Access Logs
Amplify provides access logs via CloudWatch. Enable them in App settings > Monitoring.
Custom CloudWatch Alarms
Set up alarms for error rates:
aws cloudwatch put-metric-alarm \
--alarm-name "amplify-5xx-errors" \
--metric-name "5xxErrors" \
--namespace "AWS/AmplifyHosting" \
--dimensions "Name=App,Value=YOUR_APP_ID" \
--statistic Sum \
--period 300 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions "arn:aws:sns:region:account:topic"
Step 8: Performance Optimization
Enable Caching Headers
Configure caching in your Next.js app for static assets:
// next.config.ts
const nextConfig: NextConfig = {
async headers() {
return [
{
source: '/_next/static/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
];
},
};
ISR on Amplify
Incremental Static Regeneration works on Amplify. Use it for pages that change periodically:
// app/products/page.tsx
export const revalidate = 3600; // Revalidate every hour
async function ProductsPage() {
const products = await fetchProducts();
return <ProductList products={products} />;
}
Cost Considerations
Amplify pricing is based on:
- Build minutes: ~$0.01 per build minute
- Hosting: ~$0.15 per GB served
- SSR requests: ~$0.20 per million requests
For a typical Next.js app with moderate traffic (100K page views/month), expect $5-15/month. This is competitive with Vercel's Pro plan and significantly cheaper at scale.
Pro Tips
- Use
standaloneoutput mode to reduce deployment size and cold start times. - Cache
node_modulesand.next/cachein your build settings to cut build times by 50% or more. - Set
NODE_OPTIONS=--max-old-space-size=4096if builds fail with memory errors. - Use preview deployments for every PR. The automatic cleanup saves you from managing staging environments.
- Monitor CloudWatch logs after deployment. The first few hours often reveal issues that local testing misses.
Key Takeaways
- AWS Amplify Gen 2 fully supports Next.js App Router, Server Components, ISR, and middleware
- Use
standaloneoutput mode and cache your builds for optimal performance - Set up custom domains with automatic SSL via ACM
- Preview deployments make code review significantly easier
- Amplify is cost-effective compared to Vercel, especially at higher traffic volumes
Sources
Looking for more? Check out Adaptels.
Related Articles
How to Debug Node.js Memory Leaks (Step-by-Step Guide)
Learn how to detect, diagnose, and fix Node.js memory leaks using heap snapshots, Chrome DevTools, and clinic.js — with real code examples.
How to Set Up GitHub Actions for CI/CD (Beginner-Friendly Guide)
Learn how to set up GitHub Actions for CI/CD pipelines — from your first workflow file to automated deployments with real YAML examples.
Running Local LLMs With Ollama: Developer Setup Guide
Set up Ollama to run local LLMs on your machine. Covers installation, model selection, API usage, and integrating local models into your dev workflow.