How can I render a specific purescript-halogen component into the <head> tag?
The following example written for Halogen 1.0.0 renders the stylesheet and the paragraph into the HTML body:
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(Nothing))
import CSS as C
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.HTML.CSS as HS
import Halogen.Query.HalogenM as HQ
import Halogen.VDom.Driver as HV
styles :: forall p i. HH.HTML p i
styles = HS.stylesheet $
C.select C.body $ C.margin C.nil C.nil C.nil C.nil
content :: forall p i. HH.HTML p i
content = HH.p_ [ HH.text "Test" ]
main :: Eff (HA.HalogenEffects ()) Unit
main = HA.runHalogenAff $ HA.awaitBody >>= HV.runUI ui unit
where
ui = H.component { initialState : const unit
, render : const render
, eval : const $ HQ.halt "no query"
, receiver : const Nothing
}
render = HH.div_ [ styles, content ]
The DOM is generated as follows:
<html>
<head>
<title>Test</title>
<script async="" type="text/javascript" src="main.js"></script>
</head>
<body>
<div>
<style type="text/css">
body { margin: 0 0 0 0 }
</style>
<p>
Test
</p>
</div>
</body>
</html>
This example works but according to the specification the style element is only allowed "where metadata content is expected", i.e. the <head> element. So I want to render the stylesheet there. How do I accomplish this?
Notice the
awaitBodyfunction - as well as waiting for it to load, this selects thebodyelement, which is not really what you want in this case. If you want to write to theheadthen you're going to need to select that and pass it torunUIfor a component that renders a stylesheet.You'll also need to run two separate components, one for the
head, one for thebody:If they need to communicate then you could use the
subscribeanddriverfunctions from theHalogenIOrecord thatrunUIproduces to set up channels between them.I had concerns about doing this, as you're supposed to pass through an element that is empty as the target for where a container will render... but when using the Halogen-provided
VDomdriver it appears to behave at least, in that the<head>contents won't be replaced by the style component (it is appended to the end). This is basically unspecified behaviour though, so I'm not sure it would necessarily hold true with other drivers.