Getting started with web development using Haskell, Spock, and Lucid, I can't figure out how to serve my static files. In the directory of Main.hs
I have /static/css/main.css
, which contains just a background colour to see if the css is indeed applied. So my directory tree looks like
app
├── Main.hs
└── static
└── css
└── main.css
However, with the below configuration, the main.css
file is not found (it contains a 404 when inspecting it with Firefox). Other than that, the site shows fine.
I have tried to mimick the funblog example when it comes to serving these files (with Wai), altered for Lucid instead of Blaze. In particular the middleware $ staticPolicy (addBase "static")
from Web/Blog.hs
and the line where we link the css from Web/Views/Site.hs
.
module Main where
import Network.Wai.Middleware.Static
import Lucid
import Web.Spock
import Web.Spock.Config
import Web.Spock.Lucid (lucid)
type Server a = SpockM () () () a
main :: IO ()
main = do
cfg <- defaultSpockCfg () PCNoDatabase ()
runSpock 8080 (spock cfg app)
app :: Server ()
app = do
middleware $ staticPolicy (addBase "static")
get root $ do
lucid $ do
head_ $ link_ [ rel_ "stylesheet"
, type_ "text/css"
, href_ "/css/main.css"
]
body_ $ h1_ "Hello."
-- Additional imports
import Text.Blaze.XHtml5 ((!))
import qualified Text.Blaze.XHtml5 as H
import qualified Text.Blaze.XHtml5.Attributes as A
import Control.Monad.Trans (MonadIO)
import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
-- The main function did not change.
blaze :: MonadIO m => H.Html -> ActionCtxT ctx m a
blaze = lazyBytes . renderHtml
app :: Server ()
app = do
middleware $ staticPolicy (addBase "static")
get root $
blaze $ do
H.head $
H.link ! A.href "/css/main.css" ! A.rel "stylesheet"
H.body $
H.h1 "Hello Blaze."
Make sure your static
folder is in the root directory of your project, and not of your main file, i.e., the static
folder should live next to (and not in) your app
and/or src
folder.
In this case that would be
├── app
│ └── Main.hs
├── static
│ ├── css
│ │ └── main.css