9
votes

I have uploaded a react app to AWS S3 and am using static website hosting. I then linked a cloudfront distribution to the s3 bucket.

I am able to navigate to the site and it functions properly except when I navigate to a new page my-domain/new-page. At first it succeeds but if I try and load the page directly or refresh I get a 403 forbidden error.

2

2 Answers

25
votes

Using react with S3 and CloudFront, I had this or a similar issue where loading the initial index page and then linking to other pages worked just fine (push state changes), but if I refreshed the page or linked directly to the page, it came up as "Access Denied," status 403.

The solution I found was to add custom error pages for 403 and 404 errors to the CloudFront configuration.

S3 responds 403 when an object doesn't exist as would be the case with pages in client side routing.

Screenshot of Cloud Front custom errors

3
votes

I have noticed this happens when you change the object and look for the object immediately. To resolve this issue, we used to cache the object for 5 mins, so CloudFront will serve cached version when available.

This also relates if you are changing the object and applying the ACL along with the object. Ensure you have public read as policy for the bucket, so you can reduce outage time.

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/*"]
    }
  ]
}

Enabling cache in CloudFront also solves the issue.

Hope it helps.