Recently, I was going back over an Amazon S3 static site I maintain and noticed that I couldn’t navigate directly to subpages without using a trailing /index.html
. It turns out there’s a few quirks of the Amazon CloudFront console settings that might lead to this. Let’s take a look at how to fix it.
The Setup
For context, the basic structure of the site I was working with minus a few asset folders looks like this:
.
├── index.html
└── projects
├── ben-frankly
│ ├── index.html
│ └── main.css
├── chameleon
│ ├── index.html
│ └── main.css
├── index.html
├── pigeon
│ ├── index.html
│ └── main.css
└── state-sales-tax-api
└── index.html
There is a homepage (http://serverlessfoo.com) that has links to individuals project pages under the /projects directory.
The Issue
Essentially, I wanted to host these different HTML pages on the same site as subpages without having to pay for different domains. Now with a typical webserver, you could configure the plain URLs without an index.html
to assume when you enter https://serverlessfoo.com/projects/ben-frankly
into your browser you actually want to see the file located at https://serverlessfoo.com/projects/ben-frankly/index.html
.
However, with the configuration I was using under the CloudFront distribution for this site, the plain no-index.html
pages were displaying this error when I navigated to them.
This was odd for me, because in the past I’d setup sites with what I thought was the exact same services with the same configuration and the behavior was the one I wanted (with the plain no-index.html
loading the index.html
file). Now, instead of this behavior, when I navigated to one of my subfolder projects at https://serverlessfoo.com/projects/chameleon/
I got the “No such key” error:
But when I visited https://serverlessfoo.com/projects/chameleon/index.html
it loaded just fine:
The Fix
After a little bit of digging I realized that there are two different possible CloudFront origins for S3 Static sites:
- Bucket Origins
- Static Site Origins
Bucket origins are the default origin that CloudFront autofills for you when you start typing the name of your bucket into the CloudFront Origin configuration:
The issue turned out to be that I had used the bucket origin in the CloudFront origin configuration (because it was the only autofill option I saw for this site!):
The bucket origin is the same as the name of your bucket with a .s3.amazonaws.com
at the end of it. These origins can work to host a static site and have it cached by CloudFront. However, they lead directly to the issue discussed above for any subpages.
In order to fix this issue, we need to use a static site origin with CloudFront. Static site origins reference the hosted static site instead of S3 bucket files. This enables navigating to pages without the trailing /index.html because the static site itself has that configuration taken care of.
Static site origins will differ depending on the AWS region they deployed in so be sure to review your static site URL to get the correct value. They should look like a version of your static site URL without the initial http://
. In my case in us-east-1, I added .s3-website-us-east-1.amazonaws.com
to the end of my bucket name to create the new value for my origin: www.serverlessfoo.com.s3-website-us-east-1.amazonaws.com
.
This will not currently autofill inside of CloudFront so it is less intuitive:
With this configuration applied, you should be able to either wait for CloudFront to update or run an invalidation on the cache and then try navigating to the plain no-index.html
url. After that, all your subpages should work as expected.
Still having problems? Leave a comment below!