Search code examples
haskellscotty

Serve static css file using WAI middleware and Scotty


I have the following Main.hs

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Web.Scotty
import Network.Wai.Middleware.RequestLogger
import Network.Wai.Middleware.Static
import Text.Blaze.Html.Renderer.Text (renderHtml)
import qualified Text.Blaze.Html5 as H
import Text.Blaze.Html5.Attributes
import Control.Monad.IO.Class

main :: IO ()
main = do
  scotty 3000 $ do
    middleware logStdoutDev
    middleware $ staticPolicy (noDots >-> addBase "static")
    get "/" $ do
        html $ renderHtml $
            H.docTypeHtml $
                H.html $ do
                    H.head $
                        H.link H.! rel "stylesheet" H.! href "stylesheet.css"
                    H.body $ do
                        H.h1 "Link Shortener"
                        H.form H.! method "POST" H.! action "/shorten" $ do
                            H.input H.! type_ "text" H.! name "url"
                            H.input H.! type_ "submit" H.! value "Shorten!"
    post "/shorten" $ do
        url <- param "url"
        liftIO $ putStrLn url
        redirect "/"

and the following directory structure (this is in a stack project):
directory

As far as I can tell from reading around, a GET request to /stylesheet.css should serve the stylesheet, but I get a 404. A request to /static/stylesheet.css is also a 404. Is there a problem with my middleware policy or directory structure?


Solution

  • This is probably a "current directory" issue. When run from inside the Stack project directory, an executable should normally be launched with its current directory set to the root of the project directory, not the app subdirectory. If you move your static directory up one level, that will probably fix it.

    I was able to get your code working fine in a stack new ... simple project with static a subfolder of the project root.

    scottystatic/
    |
    |   stack.yaml, scottystatic.cabal, etc.
    |
    +-- src/
    |       Main.hs
    |
    `-- static/
            stylesheet.css