Hakyll for Website Hosting

Posted on 2022-04-14

I recently tried to make a docker image to bundle a Hakyll server. Eventually I realized it doesn’t make any sense: Hakyll is a static site generator. This means that any webserver, e.g. apache or nginx, can serve the outputs from Hakyll. Its just a bunch of HTML files, optionally with css and/or Javascript.

The main reason I wanted Hakyll was honestly because it was written in Haskell. In addition, Hakyll gets a few points for being FOSS, simple to configure and supporting pandoc, meaning I can render HTML from e.g. a markdown file.

A regular path and matching looks like this (in your main method):

match (fromString $ "css/default.css") $ do 
  route idRoute
  compile compressCssCompiler

This says, create a URL matching of “css/default.css” to be served locally from idRoute, i.e. the same path, i.e. “css/default.css”.

For custom URLs, replace idRoute with our own custom path. This website is e.g. hosted under a “blog” URL prefix. I achieve that by replacing idRoute above with:

urlPrefix :: String
urlPrefix = "blog/"

prefixedRoute :: Routes
prefixedRoute = customRoute $ (urlPrefix ++) . toFilePath

Now, when Hakyll compiles the website content, it automatically creates a directory blog in its output directory, in effect creating a URL prefix. Similarly, if I had written a custom URL translator that replaced all symbols with underscores, the result is that the output directory from Hakyll would contain files with underscores. Or that files would end with .html, as below:

-- Prefix route with URL prefix and convert to html file
  route $ prefixedRoute `composeRoutes` setExtension "html"

For a full example, check out this site’s source code in my gitlab repository

Got suggestions, corrections, or thoughts? Post a comment!

Markdown is allowed
Email is used just to show an avatar image and is not displayed or stored
Comments are moderated. They will appear below after they are approved.

0 comments