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


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 Console → Functions → Create 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!
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.