hakyll- A static website compiler library

Safe HaskellNone



Once a target is compiled, the user usually wants to save it to the disk. This is where the Routes type comes in; it determines where a certain target should be written.

Suppose we have an item foo/bar.markdown. We can render this to foo/bar.html using:

route "foo/bar.markdown" (setExtension ".html")

If we do not want to change the extension, we can use idRoute, the simplest route available:

route "foo/bar.markdown" idRoute

That will route foo/bar.markdown to foo/bar.markdown.

Note that the extension says nothing about the content! If you set the extension to .html, it is your own responsibility to ensure that the content is indeed HTML.

Finally, some special cases:

  • If there is no route for an item, this item will not be routed, so it will not appear in your site directory.
  • If an item matches multiple routes, the first rule will be chosen.



type UsedMetadata = Bool Source

When you ran a route, it's useful to know whether or not this used metadata. This allows us to do more granular dependency analysis.

data Routes Source

Type used for a route


runRoutes :: Routes -> Provider -> Identifier -> IO (Maybe FilePath, UsedMetadata) Source

Apply a route to an identifier

idRoute :: Routes Source

A route that uses the identifier as filepath. For example, the target with ID foo/bar will be written to the file foo/bar.

setExtension :: String -> Routes Source

Set (or replace) the extension of a route.


runRoutes (setExtension "html") "foo/bar"


Just "foo/bar.html"


runRoutes (setExtension "html") "posts/the-art-of-trolling.markdown"


Just "posts/the-art-of-trolling.html"

matchRoute :: Pattern -> Routes -> Routes Source

Apply the route if the identifier matches the given pattern, fail otherwise

customRoute :: (Identifier -> FilePath) -> Routes Source

Create a custom route. This should almost always be used with matchRoute

constRoute :: FilePath -> Routes Source

A route that always gives the same result. Obviously, you should only use this for a single compilation rule.

gsubRoute Source


:: String


-> (String -> String)


-> Routes

Resulting route

Create a gsub route


runRoutes (gsubRoute "rss/" (const "")) "tags/rss/bar.xml"


Just "tags/bar.xml"

metadataRoute :: (Metadata -> Routes) -> Routes Source

Get access to the metadata in order to determine the route

composeRoutes Source


:: Routes

First route to apply

-> Routes

Second route to apply

-> Routes

Resulting route

Compose routes so that f `composeRoutes` g is more or less equivalent with g . f.


let routes = gsubRoute "rss/" (const "") `composeRoutes` setExtension "xml"
in runRoutes routes "tags/rss/bar"


Just "tags/bar.xml"

If the first route given fails, Hakyll will not apply the second route.