Amazon cloudfront

Cloudfront enables you to host your static website via s3. You should set your root object to index.html to rewrite https://yourdomainname.com to https://yourdomainname.com/index.html for cleaner urls.

However you might run into an issue of having subdirectories in your s3 bucket that you want to do the same for (for example on hosting a hugo blog). Unfortunately Cloudfront doesn’t support this by default.

Amazon Lambda

Help comes in the way of creating a lambda function to rewrite your subdirectories to /index.html.

Create a new function

Select Lambda from your services and click Create function.

Choose author from scratch and name your function something like yourdomainname-com-index-html-redirection. Choose Node.js 14.x as the Runtime. Leave architecture as x86_64 (you might be tempted to change this to arm64, but Lambda@edge doesn’t support it yet).

Author from scratch

Give permission to Lambda@Edge to create a trigger

Click Configuration and open your role under Role name in a new tab. Click Trust relationships and add "edgelambda.amazonaws.com" as a Principal Service, such as:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "lambda.amazonaws.com",
                    "edgelambda.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Trust relationships

Create a trigger

Click Add trigger. Select Cloudfront and click Deploy to Lambda@Edge. Select your Cloudfront Distribution, leave the other fields as is. Click Confirm deploy to Lambda@Edge and Deploy.

Edit code

Go back to the code editor and paste the following simple program:

'use strict';
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;

    // 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(/\/$/, '\/index.html');
    
    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);
    
    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;
    
    return callback(null, request);
};

Click Deploy.