yesod-static- Static file serving subsite for Yesod Web Framework.

Safe HaskellNone




A subsite which serves static content which is embedded at compile time.

At compile time, you supply a list of files, directories, processing functions (like javascript minification), and even custom content generators. You can also specify the specific relative locations within the static subsite where these resources should appear. The mkEmbeddedStatic function then computes the resources and embeds them directly into the executable at compile time, so that the original files do not need to be distributed along with the executable. The content is also compressed and hashed at compile time, so that during runtime the compressed content can be sent directly on the wire with the appropriate HTTP header. The precomputed hash is used for an ETag so the client does not redownload the content multiple times. There is also a development mode which does not embed the contents but recomputes it on every request. A simple example using an embedded static subsite is static-embed.hs.

To add this to a scaffolded project, replace the code in Settings/StaticFiles.hs with a call to mkEmbeddedStatic with the list of all your generators, use the type EmbeddedStatic in your site datatype for getStatic, update the route for /static to use the type EmbeddedStatic, use embedStaticContent for addStaticContent in Foundation.hs, use the routes generated by mkEmbeddedStatic and exported by Settings/StaticFiles.hs to link to your static content, and finally update Application.hs use the variable binding created by mkEmbeddedStatic which contains the created EmbeddedStatic.

It is recommended that you serve static resources from a separate domain to save time on transmitting cookies. You can use urlParamRenderOverride to do so, by redirecting routes to this subsite to a different domain (but the same path) and then pointing the alternative domain to this server. In addition, you might consider using a reverse proxy like varnish or squid to cache the static content, but the embedded content in this subsite is cached and served directly from memory so is already quite fast.



embeddedResourceR :: [Text] -> [(Text, Text)] -> Route EmbeddedStatic Source #

Construct a route to an embedded resource.

mkEmbeddedStatic Source #


:: Bool


-> String

variable name for the created EmbeddedStatic

-> [Generator]

the generators (see Yesod.EmbeddedStatic.Generators)

-> Q [Dec] 

Creates an EmbeddedStatic by running, at compile time, a list of generators. Each generator produces a list of entries to embed into the executable.

This template haskell splice creates a variable binding holding the resulting EmbeddedStatic and in addition creates variable bindings for all the routes produced by the generators. For example, if a directory called static has the following contents:

  • js/jquery.js
  • css/bootstrap.css
  • img/logo.png

then a call to

#define DEV_BOOL True
#define DEV_BOOL False
mkEmbeddedStatic DEV_BOOL "myStatic" [embedDir "static"]

will produce variables

myStatic :: EmbeddedStatic
js_jquery_js :: Route EmbeddedStatic
css_bootstrap_css :: Route EmbeddedStatic
img_logo_png :: Route EmbeddedStatic

embedStaticContent Source #


:: Yesod site 
=> (site -> EmbeddedStatic)

How to retrieve the embedded static subsite from your site

-> (Route EmbeddedStatic -> Route site)

how to convert an embedded static route

-> (ByteString -> Either a ByteString)

javascript minifier

-> AddStaticContent site 

Use this for addStaticContent to have the widget static content be served by the embedded static subsite. For example,

import Yesod
import Yesod.EmbeddedStatic
import Text.Jasmine (minifym)

data MySite = { ..., getStatic :: EmbeddedStatic, ... }

mkYesod "MySite" [parseRoutes|
/static StaticR EmbeddedStatic getStatic

instance Yesod MySite where
    addStaticContent = embedStaticContent getStatic StaticR mini
        where mini = if development then Right else minifym


Orphan instances