Closed knarkzel closed 1 year ago
There are two approaches you can take here: 1) Use SSR + Hydration to hydrate a loading spinner (see this example for hydration)
[package]
name = "dioxus-hmr"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = "0.3"
dioxus-web = { version = "0.3", features = ["hydrate"] }
# server side rendering
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
dioxus-ssr = "0.3"
// run with:
// cargo run # to create index.html
// dioxus serve # to run in browser
use std::io::Write;
use dioxus::prelude::*;
fn main() {
#[cfg(target_arch = "wasm32")]
dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true));
#[cfg(not(target_arch = "wasm32"))]
{
let template_pre = r#"<!DOCTYPE html>
<html class="dark:bg-slate-900 dark:text-slate-400">
<head>
<title>My App</title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<link rel="stylesheet" href="/output.css" />
</head>
<body>
<div id="main">"#;
let template_post = r#"</div>
<script type="module">
import init from "/{base_path}/assets/dioxus/{app_name}.js";
init("/{base_path}/assets/dioxus/{app_name}_bg.wasm").then(wasm => {
if (wasm.__wbindgen_start == undefined) {
wasm.main();
}
});
</script>
</body>
</html>"#;
let mut file = std::fs::File::create("index.html").unwrap();
let mut vdom = VirtualDom::new(app);
let _ = vdom.rebuild();
let renderered = dioxus_ssr::pre_render(&vdom);
file.write_fmt(format_args!("{template_pre}{renderered}{template_post}"))
.unwrap();
}
}
fn app(cx: Scope) -> Element {
let loading = use_state(cx, || true);
if **loading {
// this will force a re-render on the client
loading.set(false);
render! {
"loading..."
}
} else {
render! {
Counter {}
}
}
}
fn Counter(cx: Scope) -> Element {
let count = use_state(cx, || 0);
render! {
div {
button {
onclick: move |_| {
count.set(**count + 1);
},
"Increment",
}
"Count: {count.get()}"
}
}
}
You wouldn't actually need a server here, you could just use ssr to generate the html with the spinner that then is swapped out immediately for the real page 2) Use use_eval with getElementById to remove a specific element after the wasm has loaded
Option 1 can also be used to create a shim of your page and have loading spinners in specific areas that need WASM to operate which is much more difficult with option 2.
Specific Demand
Show spinner while waiting for wasm to load.
Implement Suggestion
I think it's possible with Trunk, but I'm not sure. Any pointers would be helpful.