Hi all, I've been playing around with lustre recently and am trying to prototype having a client component rendered from a server component. The basic idea is that I would like to render most things with server components but in certain cases, have a component render on the client where it makes sense for latency/ux reasons. Ideally at some point I would just have a client_component("SomeComponent", data) function that I can call from the server view that takes care of all the details.
Does anyone know if this is possible or has anyone achieved this?
I have a project with separate client and server directories, and I have a sample client lustre app that should get mounted to #app when main is called.
// client
pub fn main() -> Nil {
echo "client main function is running!"
let app = lustre.element(html.text("Hello, world!"))
let assert Ok(_) = lustre.start(app, "#app", Nil)
Nil
}
When the client.mjs is built, it is placed in the server priv/static folder and loaded via script src="..." tag from my server component's view function:
// server
fn view(model: Model) -> Element(Msg) {
div([], [
...
element.element("div", [attribute.id("app")], []),
script([src("/static/client.mjs")], ""),
])
}
But in the browser I see nothing is rendered and the following console log
src/client.gleam:13
"client main function is running!"
Uncaught TypeError: document is not a function
at is_browser (client.mjs:4502:26)
at start3 (client.mjs:4758:6)
at main (client.mjs:4771:15)
at client.mjs:4925:1
is_browser @ client.mjs:4502
start3 @ client.mjs:4758
main @ client.mjs:4771
(anonymous) @ client.mjs:4925
Interestingly, I am able to make this work when I place the #app div and script outside of the server component, but not when rendered from the server component.