AngularJS is a Javascript Framework that allows you to create dynamic front-end web applications easily.
I have traditionally packaged these applications through NodeJS, and Grunt (or Gulp) in particular.
Once it needs to be hosted for the whole world to see, I always used to push the static folder up to an Apache2 or Nginx Linux web server.
There’s really not a massive need for this though, as it’s easily possible to AngularJS applications completely serverless using a combination of AWS S3 and Cloudflare.
You don’t have to use Cloudflare in your own setup, and could technically keep everything within AWS by swapping Cloudflare out with Route53.
But I really like Cloudflare and have used it for many years wherever I get a chance to.
Quickstart
You will need an AWS account, and possibly a Cloudflare account too if you want to use them for your domain and DNS management.
To host an AngularJS website on S3 you will need to follow these general steps:
- Create an S3 bucket with the name of the domain you will expose
- Set the bucket to public
- Update the HTML5Mode and HashPrefix in your AngularJS code
- Package and upload your AngularJS site to the S3 bucket
- Update the bucket for ‘Static website hosting'
- Update the ‘Redirection rules'
- Update your DNS to point to the S3 bucket
The problem
So doing most of the above would probably seem obvious.
However, when you have canonical/permanent HTML5 URLs (such as <a href="https://analytics.statvoo.com/developers" target="_blank" rel="noreferrer noopener">https://analytics.statvoo.com/developers</a>
or <a href="https://analytics.statvoo.com/plans" target="_blank" rel="noreferrer noopener">https://analytics.statvoo.com/plans</a>
, then navigating to them and refreshing the browser will result in either a 404
or 403
error page served by S3.
If you were hosting this yourself, you could fix the problem by serving your app through npm
or updating your .htaccess
file to enable mod_rewrite
capabilities.
S3 has none of this.
This is where you need to revert to having a backup hashPrefix
and S3 Redirection rules
to counter it.
Luckily, it’s really easy. So let’s do it now!
Update your AngularJS Application
In your AngularJS app, find (or add…) the $locationProvider...
code as below:
angular.module(app, [])
.config(function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
});
Remember to update your app
name if required, and any other weird things you may have changed beforehand.
How to setup S3 for static AngularJS serving
We are going to create a new S3 bucket for our site, which was analytics.ataiva.com
.
Go S3 and create a new bucket called analytics.ataiva.com
, remember to change it to your own domain/subdomain.
Make sure that you deselect “Block public…” and make the bucket “public”.
Now upload all your static AngularJS site assets, HTML and everything else that your packager (Grunt?) created for you.
Once this is done, select Properties
and open the Static website hosting
box.
At this point you can select “Use this bucket to host a website”, enter index.html
into the “index document field” and then update the Redirection rules
field with the following:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<HostName>analytics.ataiva.com</HostName>
<ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<HostName>analytics.ataiva.com</HostName>
<ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
Make sure to update your own HostName
in both sections to whatever you named your bucket, which should also match your domain/subdomain hostname.
The properties box should look something like this:
Make sure to Save
this and then it’s time to update the DNS entry.
Update your DNS
Head over to your DNS for the specific domain property and add (or update…) a CNAME
record, this should be the subdomain or the first section of your bucket name. In my case, it will be analytics
.
Now set the target to <bucket-name>.s3-website-eu-west-1.amazonaws.com
, in my case it would be analytics.ataiva.com.s3-website-eu-west-1.amazonaws.com
.
Now you’re good to go!
Wait a moment and then head over to your website in a browser, click between links and then try and refresh.
Job done!