HTML / SSR
ascent-html renders the same UI AST to a string. There is no separate server walker: it mounts
into a disposable in-memory DOM with the same Mount engine the browser uses, then serializes
the tree. Server and client cannot drift.
Html.render / Html.renderPage emit compact markup (what morph consumes): a fragment, no doctype.
Document(title)(head*)(body*) is a whole document. renderDocument mounts that html root as the
document element and emits the doctype. renderDocumentPretty is the indented twin. Pretty output
is for humans; the newlines would become text nodes if fed back through morph.
Docs below use the pretty entry points so the result panel is readable.
render and renderPage
{
val ui = E.div(A.className("card"), E.h1("Hello"), E.p("rendered on the server"))
Html.renderPretty(ui)
}<div data-ascent="3xmrk9mlrljk" class="card">
<h1 data-ascent="10rbnu6k8nayd">Hello</h1>
<p data-ascent="1nye82ifts9sr">rendered on the server</p>
</div>{
object Box extends CssClass(S.padding.px(8))
Html.renderPagePretty(E.div(Box, "styled"))
}<div data-ascent="1rgt1ud03uic9" class="ascent-docs-HtmlPage-Box-2">styled</div>
.ascent-docs-HtmlPage-Box-2 {
padding: 8.0px;
}
Reactive snapshots
Reactive boundaries are .get-ted for their current value and rendered inline; one static
snapshot, no observers. Event handlers and lifecycle hooks are omitted. Scoped runs once in a
fresh Scope, renders, and closes. data-ascent ids match the client Mount stamps when using
the same IdMode.
for
n <- sq(3)
html <- Html.renderPretty(E.span(n.map(_.toString)))
yield html<span data-ascent="1bnfv1c0sne5f">3</span>Document
Document(title)(head*)(body*) builds the shell: charset, viewport, title, then the head list, then
the body list. A script in the body list stays in body. StylePlacement.Aside returns CSS beside
the markup. StylePlacement.InlineInHead also appends one style in head when the tree touched
CSS. The effect fails with Html.Error when the mounted tree is not a single html element.
Html.renderDocument(
Document("Todos host")()(E.script(A.src("/host.js"))),
StylePlacement.Aside,
)<!DOCTYPE html><html data-ascent="e9ye28zd0mnn" lang="en"><head data-ascent="7icj2gd0vkyv"><meta data-ascent="vy777jlxxf3p" charset="utf-8"><meta data-ascent="pmprh6ir0ph" name="viewport" content="width=device-width, initial-scale=1"><title data-ascent="9v2yyr6bdatc">Todos host</title></head><body data-ascent="1jv3zv936qgjp"><script data-ascent="1qmrjmgmogk85" src="/host.js"></script></body></html>Html.renderDocumentPretty(
Document("Todos host")()(E.p("Hello")),
StylePlacement.Aside,
)<!DOCTYPE html>
<html data-ascent="cd1m9kilxi4w" lang="en">
<head data-ascent="7icj2gd0vkyv">
<meta data-ascent="vy777jlxxf3p" charset="utf-8">
<meta data-ascent="pmprh6ir0ph" name="viewport" content="width=device-width, initial-scale=1">
<title data-ascent="9v2yyr6bdatc">Todos host</title>
</head>
<body data-ascent="m6j0x39ztdqv">
<p data-ascent="1x5pvdacje1gx">Hello</p>
</body>
</html>