Skip to content
← All posts
·2 min read

Deploying a Next.js Static Site on AWS S3 + CloudFront (Beginner-Friendly Guide)

By Sagar Kumar Sethi

If you’re building a Next.js blog or marketing site and want fast global delivery at the lowest possible cost, hosting it on AWS S3 with CloudFront is one of the best setups you can choose.

In this guide, we’ll walk through why this setup works, how it’s structured, and common mistakes to avoid—especially if you’re doing this for the first time.


Why Use S3 + CloudFront?

Let’s keep it simple:

  • S3 → stores your static files (HTML, CSS, JS, images)
  • CloudFront → delivers them quickly via a global CDN
  • Route 53 → connects your custom domain

Benefits

  • ⚡ Extremely fast worldwide
  • 💸 Very cheap (often ₹50–₹300/month for small sites)
  • 🔒 Secure with HTTPS
  • 📈 Scales automatically (no servers to manage)

Perfect for blogs, portfolios, landing pages, and documentation sites.


Step 1: Build Your Next.js App

For static hosting, you’ll need a static export.

javascript
npm run build
npm run export

This creates an out/ folder containing plain HTML and assets.

⚠️ If you use App Router, make sure pages are static or use generateStaticParams.


Step 2: Create an S3 Bucket

Key points while creating the bucket:

  • Bucket name = your domain name
  • Example: dailydrifthub.com
  • Disable Block all public access
  • Enable Static website hosting

Set:

  • Index document → index.html
  • Error document → index.html (important for routing)

Bucket Policy (Public Read)

javascript
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::dailydrifthub.com/*"
    }
  ]
}

Step 3: Upload Files to S3

Upload everything inside out/, not the folder itself.

Your bucket root should look like:

javascript
index.html
/_next
/assets
/posts

Step 4: Set Up CloudFront

Create a new distribution:

  • Origin domain → S3 website endpoint (not the bucket ARN)
  • Viewer protocol policy → Redirect HTTP to HTTPS
  • Default root object → index.html

Fix 404 Errors for Routes (Very Important)

Add Custom Error Responses:

Error Code

Response Page

HTTP Code

403

/index.html

200

404

/index.html

200

This fixes errors when users refresh /posts/some-article.


Step 5: Connect Your Domain (Route 53)

  • Create an A Record
  • Alias → CloudFront distribution
  • TTL → Auto

Wait a few minutes and your site should load on your domain 🎉


Do You Need CloudFront Invalidation?

Short answer: usually no.

  • New files → update automatically
  • Changed files → cached for TTL duration

Free tier gives 1,000 invalidation paths/month, so occasional invalidations won’t cost you.


Common Mistakes to Avoid

❌ Uploading the out folder instead of its contents

❌ Using S3 REST endpoint instead of website endpoint

❌ Forgetting error page routing

❌ Blocking public access accidentally

❌ Expecting SSR features on static hosting


Final Thoughts

This setup is:

  • Production-grade
  • Low maintenance
  • Cost-effective
  • Perfect for tech blogs like Daily Drift Hub

If you don’t need real-time server logic, S3 + CloudFront beats most hosting platforms on price and performance.

Related Posts

Useful Tools For This Topic

Explore all tools

JSON Formatter

Format, validate, and beautify JSON instantly.

Open Tool →

JWT Decoder / Encoder

Decode payloads, verify signatures, test secrets, and generate JWT tokens.

Open Tool →

Timestamp Converter

Convert between Unix timestamps and dates.

Open Tool →

UUID Generator

Generate unique UUIDs for your applications.

Open Tool →