๐Ÿš€ Deploying a React App to AWS S3 with Route 53, ACM, and CloudFront โ€” Step-by-Step Guide

Deploying a React application to the cloud has never been easier. In this tutorial, Iโ€™ll walk you through deploying a React project to AWS S3 for static hosting, setting up a custom domain via Route 53, managing SSL certificates with AWS Certificate Manager (ACM), and optimizing delivery using CloudFront.

By the end, youโ€™ll have a production-ready, globally distributed, secure React application.

๐Ÿ“Œ Prerequisites

Before we start, ensure you have:

  • AWS account (Sign up here)

  • React application ready (you can create one with npx create-react-app myapp)

  • Registered domain (can be purchased through Route 53 or another registrar)

  • AWS CLI installed and configured

  • Basic knowledge of AWS services


Step 1 โ€” Build Your React App

  1. Navigate to your React project folder:

     cd Desktop
     npx create-react-app demoreactapp
    

     cd demoreactapp
     npm start
    

  2. Build the production version of your React app:

     npm run build
    
  3. This will create a build folder containing optimized static files.


Step 2 โ€” Create an S3 Bucket for Hosting


Step 3 โ€” Enable Static Website Hosting in S3


Step 4 โ€” Upload Your React Build Files to S3


Step 2,3 and 4 can be done using bellow shell script:

Create a IAM user attatch Administrator access and generate access key and secretkey and configure aws cli.

aws configure

vi s3.sh
#!/bin/bash
# Variables
BUCKET_NAME="mydomain.com"
REGION="us-east-1"   # Change this to your region (if not sure, leave us-east-1)
BUILD_DIR="./build"

# 1๏ธโƒฃ Create S3 Bucket
if [ "$REGION" = "us-east-1" ]; then
    aws s3api create-bucket \
        --bucket $BUCKET_NAME \
        --region $REGION
else
    aws s3api create-bucket \
        --bucket $BUCKET_NAME \
        --region $REGION \
        --create-bucket-configuration LocationConstraint=$REGION
fi

# 2๏ธโƒฃ Enable static website hosting
aws s3 website s3://$BUCKET_NAME/ \
    --index-document index.html \
    --error-document index.html

# 3๏ธโƒฃ Disable Block Public Access
aws s3api put-public-access-block \
    --bucket $BUCKET_NAME \
    --public-access-block-configuration \
        BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false

# 4๏ธโƒฃ Create & attach bucket policy for public-read
cat > bucket-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::$BUCKET_NAME/*"
    }
  ]
}
EOF

aws s3api put-bucket-policy \
    --bucket $BUCKET_NAME \
    --policy file://bucket-policy.json

# 5๏ธโƒฃ Upload React build files
aws s3 sync $BUILD_DIR s3://$BUCKET_NAME --delete

# 6๏ธโƒฃ Output Website URL
echo "Website URL: http://$BUCKET_NAME.s3-website-$REGION.amazonaws.com"
bash s3.sh

What this script does

โœ… Creates S3 bucket (handles us-east-1 special case)
โœ… Enables static website hosting
โœ… Removes Block Public Access
โœ… Attaches public-read bucket policy
โœ… Uploads your React build folder
โœ… Outputs your live S3 website URL

Step 5: Purchase domain from aws or godaddy

I already have one domain, so I am using it

Step 6 - Create public hostedzone in route53

Copy 4 NS records from route53 as showned above image and add to name servers list

Stpe6 - Create host record(A Record) pointing to s3 website endpoint.

Step 7 โ€” Request an SSL Certificate with AWS Certificate Manager (ACM)

  1. Go to AWS Certificate Manager โ†’ Request a certificate.

  2. Choose Request a public certificate.

  3. Enter your domain name (e.g., mydomain.com and www.mydomain.com).

  4. Choose DNS validation.

  5. Add the generated CNAME records to Route 53 Hosted Zone (if AWS manages your DNS).

  6. Wait until the certificate status changes to Issued.


Step 7 โ€” Set Up CloudFront for Better Performance and HTTPS

  1. Go to AWS CloudFront โ†’ Create Distribution.

  2. Under Origin Domain Name, select your S3 bucket.

  3. Origin Access Control: Enable and attach to S3 for private access.

  4. Viewer Protocol Policy: Redirect HTTP to HTTPS.

  5. Under Alternate domain names (CNAMEs), enter your domain (mydomain.com, www.mydomain.com).

  6. Select your SSL certificate from ACM.

  7. Click Create Distribution.

Once created, CloudFront will provide a Distribution Domain Name (e.g., d1234.cloudfront.net).


Step 7 โ€” Connect Your Domain via Route 53

  1. Go to Route 53 Hosted Zone for your domain.

  2. Create two A records:

    • Root domain (mydomain.com) โ†’ Alias to CloudFront distribution

    • www subdomain (www.mydomain.com) โ†’ Alias to CloudFront distribution

  3. Save the records.


Step 8 โ€” Test Your Deployment

  1. Open your domain in a browser.

  2. You should see your React app served securely over HTTPS.

  3. Test performance โ€” CloudFront should cache content for faster delivery.


Step 9 โ€” Automating Deployments (Optional)

You can automate S3 uploads using AWS CLI:

aws s3 sync build/ s3://mydomain.com --delete

Run this command after each build to deploy updates instantly.


๐ŸŽฏ Conclusion

Youโ€™ve successfully deployed your React application to AWS S3, secured it with ACM, optimized delivery using CloudFront, and connected it to a custom domain via Route 53.

This setup ensures:
โœ… Global performance via CloudFront CDN
โœ… Free SSL via ACM
โœ… Scalable, cost-effective hosting via S3


๐Ÿ”— Resources:

  • AWS S3 Documentation

  • CloudFront Documentation

  • Route 53 Documentation

0
Subscribe to my newsletter

Read articles from SRINIVAS TIRUNAHARI directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SRINIVAS TIRUNAHARI
SRINIVAS TIRUNAHARI