Next.js 16 SSG on AWS Amplify: A Practical, Cost-Effective Deployment Guide

Deploying Next.js Static Site Generation (SSG) applications to AWS Amplify can be challenging without the right configuration. While Vercel offers a seamless experience, AWS Amplify may provide a cost-effective alternative with up to 96% savings for smaller sites and 20-30% for medium-traffic applications. In this comprehensive guide, we'll walk through the exact steps to successfully deploy your Next.js 16 SSG site to AWS Amplify.
Why AWS Amplify for SSG?
AWS Amplify is particularly attractive for SSG deployments because:
- Lower costs than Vercel, especially for commercial use (see our detailed cost comparison)
- No per-seat pricing for team collaboration
- Generous free tier for the first 12 months
- Standard AWS infrastructure (S3 + CloudFront) with no vendor lock-in
Note on static export limitations: Static Site Generation pre-generates all pages at build time. This means no server-side rendering (SSR), no Incremental Static Regeneration (ISR), and no API routes. If you need these features, you'll need a different deployment strategy.
Prerequisites
Before we begin, ensure you have:
- Node.js 22.x or later installed
- Next.js 16 project using App Router
- An AWS account (free tier eligible for 12 months)
- Git repository (GitHub, GitLab, Bitbucket, or AWS CodeCommit)
- Basic familiarity with Next.js App Router
Step 1: Configure Next.js 16 for SSG
Update next.config.ts
Create or modify your next.config.ts file to enable static export:
import type { NextConfig } from "next"; const nextConfig: NextConfig = { output: "export", images: { unoptimized: true, }, }; export default nextConfig;
Key Points:
output: 'export'disables the Next.js runtime and enforces a full static export. This ensures your site can be deployed as plain static HTML/CSS/JS.images.unoptimized: truedisables Next.js Image Optimization API (required for static export)
Handle Image Optimization
Since Next.js Image Optimization doesn't work with static exports, choose one of these options:
Option 1: Unoptimized images (simplest for testing)
import Image from "next/image"; <Image src="/images/photo.jpg" width={500} height={300} alt="Description" />;
Option 2: Standard HTML img tags
<img src="/images/photo.jpg" width={500} height={300} alt="Description" />
Option 3: Third-party CDN (recommended for production)
Use services like Cloudflare Images, Cloudinary, or imgix. See our guide on optimizing S3 images with Cloudflare Images.
const imageLoader = ({ src, width, quality, }: { src: string; width: number; quality?: number; }) => { return `https://your-cdn.com/${src}?w=${width}&q=${quality || 75}`; }; <Image loader={imageLoader} src="photo.jpg" width={500} height={300} alt="Description" />;
Verify SSG Compatibility
Ensure your project doesn't use these incompatible features:
Cannot use:
- Route Handlers (API Routes) - require server runtime
- Server-Side Rendering (SSR) - e.g.,
cache: 'no-store'in fetches - Incremental Static Regeneration (ISR) -
revalidateproperty - Dynamic data without
generateStaticParams— including any data fetched from “dynamic APIs” that depend on runtime values (see Next.js guide on dynamic rendering)
Must implement:
- All dynamic routes need
generateStaticParamsto pre-generate pages - Use
cache: 'force-cache'for data fetching at build time
Example for dynamic routes:
// app/blog/[slug]/page.tsx export async function generateStaticParams() { return [{ slug: "first-post" }, { slug: "second-post" }]; } export default async function BlogPost({ params, }: { params: Promise<{ slug: string }>; }) { const { slug } = await params; return <h1>Blog Post: {slug}</h1>; }
Test Locally
Verify your static export works:
npm run build npx serve out
Visit http://localhost:3000 to ensure everything renders correctly.
Step 2: Deploy to AWS Amplify
Push to Git
git add . git commit -m "Configure Next.js for SSG deployment" git push origin main
Access AWS Amplify Console
- Log into AWS Console
- Search for "Amplify" in the services search bar
- Click "Get Started" under "Amplify Hosting"
Connect Your Repository
- Select your Git provider (GitHub, GitLab, Bitbucket, or AWS CodeCommit)
- Authorize AWS Amplify to access your repositories
- Choose the repository and branch to deploy
- Click "Next"
Configure Build Settings
Amplify should auto-detect Next.js, but verify your amplify.yml:
version: 1 frontend: phases: preBuild: commands: - npm ci build: commands: - npm run build artifacts: baseDirectory: out files: - "**/*" cache: paths: - node_modules/**/*
Critical settings:
baseDirectory: out- Next.js static export directorynpm ci- Consistent, reproducible builds- Cache
node_modulesfor faster builds
Add Environment Variables (Optional)
If your app needs environment variables, add them in "Advanced settings":
NEXT_PUBLIC_API_URL=https://api.example.com NEXT_PUBLIC_ANALYTICS_ID=G-XXXXXXXXXX
Remember: Only NEXT_PUBLIC_* variables are accessible in the browser. Server-side variables are available during build time only.
Deploy
- Review settings
- Click "Save and deploy"
- Monitor the build progress (typically 3-5 minutes)
Once complete, you'll get a URL like: https://[branch].[app-id].amplifyapp.com
Step 3: Configure Redirects & Routing
Fix 404 Pages
Configure redirects in Amplify console under "Rewrites and redirects":
Rule 1: Custom 404 page
Source: </^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|woff2|ttf|map|json|webp)$)([^.]+$)/> Target: /404.html Status: 404
Rule 2: Client-side routing fallback
Source: /<*> Target: /index.html Status: 200 (Rewrite)
Important: Place Rule 2 last - Amplify processes rules in order.
Step 4: Handle Common Considerations
Environment Variables
Client Components (with "use client"):
- Can only access
NEXT_PUBLIC_*variables - Variables are embedded in the build output
Server Components (default):
- Can access all environment variables at build time
- Never expose secrets in
NEXT_PUBLIC_*variables
Forms and Interactive Features
SSG sites need external services for dynamic functionality:
- Forms: Formspree, Web3Forms, AWS Lambda
- Search: FlexSearch, Fuse.js, Algolia, Meilisearch
- Comments: Giscus, Utterances, Disqus
- Authentication: Clerk, Auth0, AWS Cognito
Next.js 16 App Router Features
Works perfectly with SSG:
- Metadata API
- Route Groups
- Loading and Error UI
- Server Components (data fetched at build time)
Requires pre-generation:
- Dynamic routes (use
generateStaticParams) - Parallel and Intercepting Routes (all combinations must be pre-generated)
Troubleshooting Common Issues
Build Fails: "Output directory not found"
Fix: Verify amplify.yml has baseDirectory: out and next.config.ts has output: 'export'
Images Not Loading
Fix: Ensure images.unoptimized: true in config. Images should be in public/ directory and referenced without the public prefix.
Blank Page After Deployment
Fix: Check browser console for errors. Usually means:
- Missing
NEXT_PUBLIC_prefix on environment variables - Client-side JavaScript error
- Incorrect build output
Dynamic Routes Return 404
Fix:
- Implement
generateStaticParamsfor all dynamic routes - Configure redirect rules in Amplify console
Environment Variables Not Working
Fix:
- Client-side variables must use
NEXT_PUBLIC_prefix - Set in Amplify Console under "Environment variables"
- Rebuild after adding new variables
When NOT to Use This Approach
Consider alternatives if you need:
- Incremental Static Regeneration (ISR): Requires Node.js server
- Server-Side Rendering (SSR): Real-time, per-request rendering
- API Routes: Need serverless functions
- On-demand Revalidation: Dynamic content updates without rebuilds
- Edge Middleware: Complex routing logic at the edge
For these use cases, consider Vercel, AWS Amplify with SSR configuration, or AWS App Runner/ECS.
Next Steps
After deployment:
- Add custom domain: In Amplify console under "Domain management"
- Set up monitoring: Use CloudWatch for build and deployment alerts
- Configure preview deployments: For pull requests and feature branches
- Optimize costs: Review bandwidth usage and optimize images
- Test thoroughly: Verify all pages and features work as expected
Conclusion
AWS Amplify provides a cost-effective platform for deploying Next.js 16 SSG applications with proper configuration. The key is understanding SSG limitations, configuring Next.js correctly, and setting up Amplify's build and routing properly.
While the setup requires more configuration than Vercel, the cost savings (up to 96% for small sites) and lack of per-seat pricing make it an excellent choice for businesses looking to optimize their hosting costs without sacrificing performance or reliability.






