Random
Common getrandom / rand patterns for WASM and SSG — deterministic seeds vs live entropy.
SSG vs client navigation
Full page load (open /demo/random in a new tab, or refresh): any rand::rng() or getrandom::fill in the component body is evaluated at build time and frozen in static HTML until you rebuild.
Client-side navigation (click Random in the nav): the page mounts in WASM only; rand::rng() in the body runs at navigation time — still not suitable for hydration on a cold load.
Hydration reuses SSG HTML for the first paint. For live bytes or floats, use use_effect (below). For stable demo output, use a SeedableRng with a fixed seed in render.
Live entropy — client after hydration
getrandom::fill and rand::rng() run only inside use_effect, so a full-page SSG load does not bake build-time random bytes into public/.
getrandom::fill([u8; 16])
→ …
rand::rng().random::<u32>()
→ …
rand::rng().random::<f64>() in [0, 1)
→ …Roll on demand (interactive)
User-driven randomness does not run during SSG or the first hydration pass.
last roll: —Seeded RNG (SSG-stable)
let mut rng = StdRng::seed_from_u64(42);
rng.random::<u32>() → 572990626
rng.random_range(10..20) → 15
five d6 from same stream → [2, 4, 6, 4, 6]Tips
- On
wasm32-unknown-unknown, enable getrandom'swasm_jsfeature in this app'sCargo.tomland setgetrandom_backend="wasm_js"in.cargo/config.toml(see repo). Without that,getrandom::fillfails at compile time or runtime in the browser. - Libraries should not enable
wasm_js— only the application crate (this template). - Prefer
StdRng::seed_from_u64for tests, snapshots, and SSG demos that must match across build and hydration. - Prefer
rand::rng()(thread-local, backed by getrandom) for gameplay and UI afteruse_effector user events. - Use
getrandom::filldirectly when you need raw bytes (tokens, UUIDs, crypto-adjacent helpers); userandfor typed sampling and shuffles.