miso

Core concepts

Text & fragments

A VText represents a DOM text node; a VFrag groups siblings without a wrapper element, like React's <></>. Both participate in keyed reconciliation.

Text nodes

The simplest way to produce a VText is via the IsString instance on View. String literals inside a child list are automatically promoted to text nodes:

H.div_ [] [ "Hello, world!" ]

For dynamic content, use the text smart constructor with a MisoString:

H.div_ [] [ text (ms userName) ]

HTML encoding

When compiling with the ssr flag, text automatically HTML-encodes its argument — <, >, &, " and ' become entities. This prevents accidental XSS when rendering user-supplied strings on the server. To embed trusted, pre-rendered content without escaping use textRaw; it is a no-op on the client and bypasses encoding on the server.

text    "<b>bold</b>"   -- SSR output: &lt;b&gt;bold&lt;/b&gt;
textRaw "<b>bold</b>"   -- server and client: <b>bold</b>

Concatenating and keying

text_ accepts a list of strings and joins them with a single space. A VText may also carry a Key (textKey, textKey_): keyed text nodes take part in the same reconciliation as keyed elements, so a stable key prevents unnecessary text-node replacement when sibling order changes.

H.div_ [] [ text_ [ "Hello", "world" ] ]          -- renders: Hello world

renderItem :: Item -> View context model Action
renderItem item = H.li_ [] [ textKey (itemId item) (itemLabel item) ]
text
single string, HTML-encoded on the server
vtext
synonym for text
textRaw
single string, never HTML-encoded
text_
list of strings joined with a space
textKey
single keyed string
textKey_
list of keyed strings joined with a space

Fragments

VFrag groups sibling nodes without a wrapper element in the DOM, analogous to the React Fragment API and the browser's DocumentFragment:

-- Renders two <li> elements as direct siblings, no enclosing element
fragment [ H.li_ [] [ "Item A" ], H.li_ [] [ "Item B" ] ]

-- Keyed fragment — survives reordering without full teardown / remount
vfrag_ "my-key" [ H.li_ [] [ "Item A" ], H.li_ [] [ "Item B" ] ]

Fragments may be nested. The differ recurses into nested fragments and processes them as if they were a flat sequence of sibling DOM nodes, so nesting carries no runtime cost beyond the constructor allocation. Empty fragments in child lists are erased before diffing and are therefore a no-op.

fragment
unkeyed fragment
vfrag
unkeyed fragment (alias)
fragment_
keyed fragment
vfrag_
keyed fragment (alias, infix-friendly: "key" `vfrag_` [...])