libero/ssr
Helpers for server-side rendering with Libero.
Server-side: call a dispatch handler directly, encode flags for the HTML document, and render the full page shell.
Client-side: read and decode flags embedded by the server.
Types
Values
pub fn boot_script(
client_module client_module: String,
flags flags: a,
) -> element.Element(msg)
Render a fragment of two <script> elements that boot the client app:
one assigns the base64-encoded ETF flags to window.__LIBERO_FLAGS__,
the other imports client_module as an ES module and calls main().
Drop this in your document tree (typically at the end of <body>)
when building a server-rendered page.
html.body([], [
html.div([attribute.id("app")], [views.view(model)]),
ssr.boot_script(client_module: "/web/app.mjs", flags: model),
])
client_module is a JS import path controlled by the developer, not user
input. It is concatenated into the generated <script type="module">
without escaping. If you derive this value from external input, you must
validate it yourself.
pub fn call(
handle handle: fn(state, BitArray) -> #(
BitArray,
option.Option(error.PanicInfo),
state,
),
handler_ctx handler_ctx: state,
module module: String,
msg msg: msg,
expect expect: fn(response) -> payload,
) -> Result(payload, SsrError)
Call a dispatch handler directly on the server, returning a
decoded payload. Encodes the call envelope, invokes the handler,
strips the wire framing, and passes the response through the
expect function to extract the desired value.
The response is the handler’s return type (e.g. Result(Int, Nil)).
ssr.call(
handle: dispatch.handle,
handler_ctx:,
module: "rpc",
msg: GetCounter,
expect: fn(resp) {
let assert Ok(n) = resp
n
},
)
// Returns Result(Int, SsrError)
pub fn decode_flags(
flags: dynamic.Dynamic,
) -> Result(a, SsrError)
Decode flags from a Dynamic value (base64 ETF string). Use this in a Lustre init function to decode server-embedded flags.
pub fn encode_flags(data: a) -> String
Encode a value as a base64 ETF string, ready to embed in HTML as client flags.
pub fn handle_request(
req req: request.Request(body),
parse parse: fn(uri.Uri) -> Result(route, Nil),
load load: fn(request.Request(body), route, state) -> Result(
model,
response.Response(mist.ResponseData),
),
render render: fn(route, model) -> element.Element(msg),
handler_ctx handler_ctx: state,
) -> response.Response(mist.ResponseData)
Render a server-side page for an HTTP request.
Pipeline: parse(uri) -> load(req, route, handler_ctx) -> render(route, model) ->
HTML response.
- Non-GET requests get a
405 Method Not Allowed. parsereturningError(Nil)gets a bare404 Not Found. Custom 404 pages: handle the catch-all in your mist router and only callhandle_requestfor paths you recognize.loadreturningError(response)returns that exact response: the loader owns auth redirects, soft 404s with custom bodies, etc.loadreturningOk(model)renders the document tree fromrenderinto a200 OKHTML response.
ssr.handle_request(
req:,
parse: router.parse_route,
load: load_page,
render: render_page,
handler_ctx:,
)