15

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.

4 Answers 4

39

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

Sign up to request clarification or add additional context in comments.

6 Comments

Interesting find.
Pretty helpful!
This is a very important piece missing in the docs
Why isn't this the accepted answer? Thanks mate
Because this still refreshes to the incorrect page (At least if you're building in nextjs), and doesn't fix the client side refresh for all pages
|
3

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.

Comments

0

This may also help:

When you are configuring your cloud front distribution and you look at what your origin is set to (click your distribution and then click "Origins" tab) it will give you a dropdown of resources pointing to a s3 bucket(s).

When you select a bucket, if that bucket has static site hosting enabled it will recommend you use the bucket site url instead. Don't do this. warn from aws

What I have found works better is if you stick with the original bucket arn, select the option that says "Origin access control settings (recommended) Bucket can restrict access to only CloudFront.", and then click "Create a Control Setting" and stick with the default configuration it provides. cloud front origin configuration

When you goto save this new origin, AWS will prompt you to copy a policy that you can just copy into your bucket ACL and everything will work.

Note: This is just an addition to Kokaubeam answer which is still a necessary evil. The above just helps with keeping from opening up the static site url to public. Additionally, this is for the case where you want to keep your static site url available as well instead of just accessing through cloud front. Ideally, you should disable static site hosting and then follow these same steps.

Comments

0

TL;DR; Go in the S3 bucket hosting the website > Proprieties > Static website hosting > Edit > Error document - optional > set this to your index.html.

Image description (click to open)

Explanation

Incorporating custom error pages like 403 and 404 directly into your CloudFront configuration can be a viable workaround. However, this approach limits your ability to redirect users to specific, customized error pages (for example, error-403.html) if you're also using AWS WAF Web ACL.

A more flexible alternative is to make the adjustments in the S3 bucket that hosts your website. To do this, go to your S3 bucket, navigate to 'Properties', then 'Static website hosting', and click 'Edit'. Here, you'll find an 'Error document - optional' field. Set this to your index.html file.

By doing this, any URL that doesn't match the home directory will be redirected to your index.html page. This allows you the freedom to configure your CloudFront to work with an AWS WAF Web ACL.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.