Creating Static Sites in Ruby with Rack
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:
Firstly, 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 config.ru
.
(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 Jekyll
with vienna
, even though I’m hosting it on GitHub Pages instead of heroku. it works great.