How to Use CloudFront Functions to Redirect Paths in an S3 + CloudFront Setup

Rakesh KadamRakesh Kadam
4 min read

Introduction

When hosting a web application on AWS S3 with CloudFront as a CDN, it's common to have specific routes that require better user experience optimizations. A great example is hosting a Unity WebGL game inside a subdirectory (e.g., /game) but requiring users to access /game/index.html to start the game.

Instead of expecting users to manually navigate to /game/index.html, we can leverage AWS CloudFront Functions to automatically redirect /game requests to /game/index.html. In this blog post, we'll explore how to set this up step by step.

Prerequisites

Before proceeding, ensure you have:

  • An S3 bucket hosting your frontend and Unity WebGL game.

  • A CloudFront distribution serving the content from the S3 bucket.

  • Basic familiarity with AWS CloudFront and S3.


Step 1: Setting Up Your S3 Bucket Structure

Your S3 bucket should have the following structure:

my-bucket/
├── index.html
├── assets/
├── game/
│   ├── index.html
│   ├── game-files/

This structure ensures that the Unity game build is available at https://your-domain.com/game/index.html.

Step 2: Creating a CloudFront Function for Redirect

2.1 What is a CloudFront Function?

CloudFront Functions allow lightweight JavaScript execution at the CloudFront edge, enabling request/response transformations before reaching the origin (S3 in this case). We’ll use a function to check if the request is for /game and redirect it to /game/index.html.

2.2 Writing the CloudFront Function

Navigate to AWS CloudFront ConsoleFunctionsCreate Function.

Use the following JavaScript code for the function:

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // Redirect /game to /game/index.html
    if (uri === "/game") {
        return {
            statusCode: 301,
            statusDescription: "Moved Permanently",
            headers: { 
                "location": { "value": "/game/index.html" }
            }
        };
    }

    return request;
}

2.3 Deploying the CloudFront Function

  • Save the function and publish it.

  • Attach it to your CloudFront distribution:

    • Go to your CloudFront distribution.

    • Navigate to Behaviors.

    • Select the behavior where the function should run (typically the /* path pattern).

    • Under Function associations, attach your function to the Viewer Request event.

    • Save the changes.


Step 3: Testing the Redirect

After deployment, test your setup by visiting:

https://your-domain.com/game

If everything is set up correctly, the request should automatically redirect to:

https://your-domain.com/game/index.html

This ensures a smoother user experience, as users won’t have to manually enter /index.html.


Step 4: Handling Additional Routes (Optional)

If you need to apply similar redirects for other paths (e.g., /dashboard, /profile), you can modify the function like this:

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // Define paths that should redirect to index.html
    var paths = ["/game", "/dashboard", "/profile"];

    if (paths.includes(uri)) {
        return {
            statusCode: 301,
            statusDescription: "Moved Permanently",
            headers: { "location": { "value": uri + "/index.html" } }
        };
    }

    return request;
}

Why Use CloudFront Functions Instead of AWS Lambda?

While AWS Lambda@Edge can also perform request modifications, CloudFront Functions offer several advantages:

  • Lower Cost: CloudFront Functions are significantly cheaper than Lambda@Edge since they run within CloudFront’s infrastructure.

  • Faster Execution: They execute at the CloudFront edge locations, leading to lower latency compared to Lambda@Edge, which runs in AWS Regions.

  • Simplified Management: No need to manage execution environments or worry about cold starts.

  • Higher Scalability: CloudFront Functions are designed to handle millions of requests per second efficiently.

If all you need is a simple redirect, CloudFront Functions are the better, lightweight choice over Lambda@Edge.


Conclusion

By leveraging AWS CloudFront Functions, we successfully implemented a seamless redirection for our Unity game hosted on S3. This solution improves the user experience while keeping requests efficient at the edge.

Key Takeaways:

✅ CloudFront Functions are lightweight and cost-effective for handling redirects.
✅ The Viewer Request function executes before hitting the origin (S3), reducing unnecessary requests.
✅ You can extend this approach to multiple routes needing a default index.html.

By implementing this technique, you can ensure a smoother and more intuitive navigation experience for your users.


Further Reading:

Let me know in the comments if you found this guide helpful or have any questions!

0
Subscribe to my newsletter

Read articles from Rakesh Kadam directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rakesh Kadam
Rakesh Kadam

I wear many hats and crave a challenge. Experience both in tech and sales. My geeky interests lie mostly in Linux, security, DevOps, infrastructure, and automation.