I have two static web apps (create-react-apps) that are currently in two separate S3 buckets. Both buckets are configured for public read + static web hosting, and visiting their S3 hosted URLs correctly display the sites.
Bucket 1 - First App:
index.html
static/js/main.js
Bucket 2 - Second App:
/secondapp/
index.html
static/js/main.js
I have setup a single Cloudfront for this - The default cloudfront origin loads FirstApp
correctly, such that www.mywebsite.com loads the index.html by default.
For the SecondApp
, I have set up a Cache Behavior so that the path pattern secondapp/*
points to the SecondApp bucket URL.
In my browser, when I visit www.mywebsite.com/secondapp/
it correctly displays the second web app.
If I omit the trailing slash however, I instead see the First App, which is undesired.
If I visit www.mywebsite.com/secondapp/something
, I am also shown the First App, which is also undesired. (I want it to load the .html of secondapp
)
Both apps are configured to use html5 push state via react-router-dom.
My desired behavior is that visiting the following displays the correct site/bucket:
www.mywebsite.com
- Currently working
www.mywebsite.com/secondapp/
- Currently working
www.mywebsite.com/secondapp
- (Without trailing slash) Not working, shows First App
www.mywebsite.com/secondapp/something_else
- Not working, show First App
How can I achieved the desired behavior?
Thanks!
You can configure a single CloudFront web distribution to serve different types of requests from multiple origins. For example, your website might serve static content from an Amazon Simple Storage Service (Amazon S3) bucket and dynamic content from a load balancer.
Hosting several subdomains in the same S3 bucket can be a great solution if you want to save time and money. Using only one S3 bucket means saving money because Amazon charges you for the size and amount of buckets, so fewer buckets mean fewer expenses.
After researching this issue, I was able to resolve it using lambda@edge (https://aws.amazon.com/lambda/edge/)
By deploying a simple javascript function to route specific paths to the desired s3 bucket, we are able to achieve an nginx-like routing setup. The function sits on lambda@edge on our Cloudfront CDN, meaning you can specify when it is triggered. For us, it's on "Origin Request"
My setup is as follows:
arn:aws:lambda:us-east-1:12345667890:function:my-function-name
)Here is an example of the lambda function I used.
var path = require('path');
exports.handler = (event, context, callback) => {
// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;
const parsedPath = path.parse(request.uri);
// If there is no extension present, attempt to rewrite url
if (parsedPath.ext === '') {
// Extract the URI from the request
var olduri = request.uri;
// Match any '/' that occurs at the end of a URI. Replace it with a default index
var newuri = olduri.replace(/second-app.*/, 'second-app/index.html');
// Replace the received URI with the URI that includes the index page
request.uri = newuri;
}
// If an extension was not present, we are trying to load static access, so allow the request to proceed
// Return to CloudFront
return callback(null, request);
};
These are the resources I used for this solution:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With