DEV Community

Roshan Raj
Roshan Raj

Posted on

Deploy React SPA to CloudFront and S3

An SPA (Single-page application) is a web app implementation that loads only a single web document, and then updates the body content of that single document via JavaScript APIs such as XMLHttpRequest and Fetch when different content is to be shown. Read more about it here.

For the purpose of this post, I will be using a simple react app.

Setting up S3 bucket to hold our react build.

Create a bucket

  • Keep the bucket name same as the domain (Helps).
  • Let the Object Ownership be 'ACLs Disabled'
  • Block All Public Access.

Deploy the React Application Build Folder to the S3 bucket

  • Make sure the index.html file is in the root of the directory.

Setting up CloudFront

Create a new CloudFront Distribution

  • Select the Origin as the S3 bucket we just created.Origin Domain
  • S3 Bucket Access: If you do not already have an Object Access Identity, create a new one.
  • We can let CloudFront update the policy for us. (Select Yes, update the bucket policy)
  • Price Class: You can select the regions as per your needs.
  • Since we will be using this CloudFront in our Domain Name, Provide the CNAME Domain Name. My Domain name is roshan-raj.com. Alternate CNAME
  • You can choose to add a custom SSL certificate. You can choose to request one from AWS. This will be free of cost if used in CloudFront. If you are creating a new SSL Certificate, it needs to be in the N.Virginia Region.
  • Specify the Default Root Object as index.html. Default Root Object
  • You can turn on Standard Logging. (Recommended)

Going Back to S3.

  • CloudFront should have added a policy for our bucket.
  • We need to add another statement in the Policy, which is s3:ListBucket.
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CLOUDFRONT>"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::roshan-raj/*"
        },
        {
            "Sid": "2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CLOUDFRONT>"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::roshan-raj"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

We are done. The React App will be available at the CloudFront URL.

Now, If you have any further routes in the React SPA, going to that routes will throw an Error "NoSuchKey".

NoSuchKey Error

We can fix this using a CloudFront Function, to re-write the url and attaching an index.html to the URL.

The "NoSuchKey" error is now fixed.
To connect it to a domain on Route53, simple point your domain to the CloudFront Domain Name.

Top comments (2)

Collapse
 
andrewbaisden profile image
Andrew Baisden

Good easy to follow setup guide 👍

Collapse
 
chrisphan profile image
Chris Phan

Thank for the instructions. There is one thing I would like to add here for case how to setup redirect from non-www to www Static website on Amazon S3 and Cloudfront. This can help us further configuration for website use only one domain. Hope that can help!