amazon-s3react-routeramazon-cloudfrontstatic-site

How to solve "x-cache: Error from cloudfront" on SPA


We are having issues trying to make working a SPA with a client router (react router). We are using the concept of have a DOMAIN -> CDN (CloudFront) -> S3 for serving our static files.

We have configured the S3 for serving static files. The CDN are configured to have the origin from the S3 and we have configured custom error pages to catch errors:

enter image description here

with this configuration we can catch errors like this:

https://www.example.com/custom-url

The CDN will redirect all the 404/403 errors to the main index.html and react router will get the correct routing.

We have working our site, and the client router is working fine, but we have a problem with the response of our CDN with x-cache: Error from cloudfront:

enter image description here

If we access to the main url https://www.example.com without any query param (not query string) all works fine.

How can I solved this problem and make that all my dynamic URLs work?

Thanks.


Solution

  • When you visit http://mywebsite.com the request will hit the index.html file in S3. Then you might click a button and go to http://mywebsite.com/stats which is an internal route of your SPA app. Thus, it will not trigger any backend request.

    But if you reload the page, http://mywebsite.com/stats will be sent to S3 as your browser does not know that you are running an SPA frontend.

    S3 will return 403 error with index.html and Cloudfront will send you the error.

    Solution is using an edge lambda function in Cloudfront. Here an example:

    const path = require('path')
    
    exports.handler = (evt, ctx, cb) => {
        const {request} = evt.Records[0].cf
    
        if (!path.extname(request.uri)) {
            request.uri = '/index.html'
        }
    
        cb(null, request)
    }
    

    Source: https://hackernoon.com/how-to-host-a-single-page-application-with-aws-cloudfront-and-lambda-edge-39ce7b036da2