There is a guide for creating static sites with rack on the heroku dev center, it works ok, but it has a few problems. After creating a few static sites and deploying them to heroku and taking different approaches each time, some simple, some complex, I decided to investigate the issue.
Here is the code that you might find in a lot of places around the web, including the aforementioned article:
urls can get pretty long and you mostly want to serve all files in
public anyway, but the main issue is that all requests that don’t correspond to a file will take you to
index.html, the home page. Also, you don’t really want
.html displaying in your urls and using
File.open in the body doesn’t take advantage of all the headers that
Rack::Static and threfore
Rack::File will set for you.
Here’s my approach. I use
Rack::Static like so:
We get all the files in
root, set an
index, which will serve e.g.
about/index.html when you get
about/ (so it also takes care of serving
/index.html when we get
'/', the root) and set the
'Cache-Control' header to an hour for all files.
After this we need to run a
rack app. We should probably return a
404 page now, as none of the files will have been matched.
I refactored this code into a tiny gem, so I can use it directly in all my projects. I called it vienna. Now you can create a static site on heroku by putting these two lines into your
(And I won’t have to write any more
Rack::Static code again.)
vienna will also serve a
404.html if it exists, instead of just returning
'Not Found' when a file isn’t found. Check out the source.
pinbrowser.co runs on
vienna now and I’ve also tested this site that is powered by
vienna, even though I’m hosting it on GitHub Pages instead of heroku. it works great.