'Getting 403 Access Denied Errors When Hosting a React Router App in AWS S3 and CloudFront
When I deployed a React Router app to AWS S3 and CloudFront and when I try to access React routes directly it gives the following error with 403 error code. I can access both the base URL(www.sample-app.com) and route URLs(www.sample-app.com/cart) when it flows through the app.
But If I try going directly to a React route(www.sample-app.com/cart) it produces a 403 Access Denied error as follows. The major pain point is it produces this error when I try to refresh a React route URL.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>REQUEST_ID</RequestId>
<HostId>HOST_ID</HostId>
</Error>
Note: I'm using AWS load balancer and Lambda functions as backend. I have setup AWS ALB and Cloudfront to authenticate users with AWS Cognito.
Appreciate your help on this.
Solution 1:[1]
Because cloudfront can only access files that do exist in the bucket, and if a nonexisting object is request it will return 403, you need to add a custom error page, that returns the index.html file with a 200 status code. Then, because the index.html was returned, the React Router can do its job.
More info here:
Solution 2:[2]
Like I mentioned in the comment, you can't use <BrowserHistory>
when you host in a static site. You need a mechanism to redirect all URLs to your index.html so react-router will take over.
To Achieve this you will need some server-side code and hosting for the same. S3 won't work as it can handle only static files. If S3 is the only option, use or there is a hack mentioned [here][1]. I won't recommend it but there is one.
If you are planning to use server-side code here is an example of how NodeJs Express can be used to get the routing work,
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', function(req, res) {
res.sendfile('./dist/index.html');
});
assuming your build is in the dist folder. [1]: react router doesn't work in aws s3 bucket
Solution 3:[3]
When using CloudFormation to create Cloudfront Distribution, use the following in the DistributionConfig Section
"DistributionConfig": {
//Other configs
"CustomErrorResponses":[
{
"ErrorCachingMinTTL" : 1,
"ErrorCode" : 403,
"ResponseCode" : 200,
"ResponsePagePath" : "/index.html"
}
]
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | aleochoam |
Solution 2 | Sanish Joseph |
Solution 3 | zeddarn |