Ember on S3 with CloudFront - Less Hash More Cache
We like deploying our Ember app to S3 with ember-cli-deploy. While cheap and fast, there is a caveat to this approach:
When a user goes directly to a page on your Ember site, say
https://emberweekend.com/episodes, S3 doesn't have the capacity to serve your
index.html file. We initially solved this by setting redirect rules in our s3 static web hosting settings:
<RoutingRules> <RoutingRule> <Condition> <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName>emberweekend.com</HostName> <ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith> </Redirect> </RoutingRule> </RoutingRules>
So, when we visit:
S3 will not be able to find that page (404) and redirect us to:
This returns the
index.html file, which loads the Ember app.
Then, the Ember app uses
pushState() to change the url back to:
Please note: This is how it's currently working as of this article's publish date. Subject to change.
This works, but the frequently changing URLs bothered us, the status code still returned a 301 redirect, and our friends at Ember Weekend noticed Google was not indexing pages that were created after taking this approach. Attempting to reconcile these issues led us to Amazon CloudFront's custom error page configuration.
We simply create a Custom Error Response that returns our
/index.html with a status of
200 when we get a
CloudFront -> <distribution-id> -> Error Pages -> Create Custom Error Response
So now, if we were to visit:
Our S3 bucket will still return a
404, but now Cloudfront will handle that
404 and return the
/index.html file with a status of
No redirects, no Hash URLs, and all is right with the world.