Usage with Lustre SSR
To use sketch with lustre SSR, little modifications are necessary. Sketch
bundles helpers to work with lustre SSR right out-of-the-box. Just use them, and
you’ll be good to go. Like every lustre application, it has to be setuped with
setup
, but after that,
you’ll have to use prepare
in
your HTTP handler, and at the end of the HTML generation, when you still have an
Element
from lustre,
run ssr
and let the magic
happen!
Example
An example with lustre, and with SSR. The idea here is to instanciate a cache, and to reuses it for every request. To scale it properly, the idea would be to create a cache for every process started.
import gleam/bytes_builder
import gleam/erlang/process
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import lustre/element
import lustre/element/html.{html}
import mist.{type Connection, type ResponseData}
import sketch
import sketch/lustre as sketch_lustre
import sketch/options as sketch_options
pub fn main() {
// Creates the cache here. A global cache will be used here, because the SSR
// only uses one process.
let assert Ok(cache) =
sketch_options.node()
|> sketch_lustre.setup()
// Helpers for mist server.
let empty_body = mist.Bytes(bytes_builder.new())
let not_found = response.set_body(response.new(404), empty_body)
let assert Ok(_) =
fn(req: Request(Connection)) -> Response(ResponseData) {
// Before every request, prepare the cache, to wipe it from old data, and
// mark it as "default" cache for the following render.
sketch.prepare(cache)
case request.path_segments(req) {
// Send the cache to your render function. It will be used before
// returing the HTML.
["greet", name] -> greet(name, cache)
_ -> not_found
}
}
|> mist.new()
|> mist.port(3000)
|> mist.start_http()
process.sleep_forever()
}
// Defines a class, here with lustre SSR.
fn main_class() {
[sketch.color("red")]
|> sketch.class()
|> sketch.to_lustre()
}
fn greet(name: String, cache: sketch.Cache) -> Response(ResponseData) {
let res = response.new(200)
let greetings = "Hey there, " <> name <> "!"
let html =
html([], [
html.head([], [html.title([], "Greetings!")]),
// Use the class as usual.
html.body([], [html.h1([main_class()], [html.text(greetings)])]),
])
html
// Ask for sketch to inject the cache content in the resulting HTML from lustre.
|> sketch_lustre.ssr(cache)
|> element.to_document_string()
|> bytes_builder.from_string()
|> mist.Bytes()
|> response.set_body(res, _)
}
Feedbacks
Because we lack people really using SSR, we take all feedbacks to help us improve the API for SSR with sketch! Feel free to open an issue to discuss about the API!