IMPORTANT This configuration doesn’t work for Safari. If you know of a solution please post it in the comments.
The wikireverse.org site is an AngularJS website that is hosted on AWS in a S3 bucket and served via CloudFront. Getting this setup to work with deep links was a bit tricky so hopefully this will save someone some time.
The Angular app uses HTML5 mode, which means history.pushState is used for changing URLs. If the browser doesn’t support HTML5 it falls back to using the hashbang prefix (#!) for URLs. This prefix is also needed for deep links otherwise Angular won’t know where to route the user. This is configured by the line below in app.js.
For the S3 bucket you need to enable website hosting, set the index document to index.html and set up a URL rewrite rule. Any 404 requests will have their URL rewritten to add the hashbang prefix and send it to index.html. The Angular app can then route the request or return a 404 if it is actually a broken link.
<RoutingRules> <RoutingRule> <Condition> <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName>wikireverse.org</HostName> <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith> </Redirect> </RoutingRule> </RoutingRules>
The CloudFront distribution needs to be pointed at the S3 bucket. The important step here is the origin needs to be the S3 website endpoint not the standard S3 endpoint. So for WikiReverse the origin is wikireverse.org.s3-website-us-east-1.amazonaws.com not wikireverse.org.s3.amazonaws.com. The S3 routing rule will only work if you use the website endpoint.