Leptos Hydrated
A library for flicker-free interactive state hydration in Leptos 0.8.
leptos_hydrated is ideal for bootstrapping state that you already have or can have on both sides (isomorphic data), such as cookies or URL parameters. By initializing signals immediately with server-provided state and synchronizing them once the browser is active, you eliminate the "loading flicker" common in SSR applications.
How it Works
- Server-Side Render (SSR):
initial()is called on the server. The result is serialized into a deterministic injection stream in the HTML shell. - Hydration: The client reads the serialized state from the stream in the same order and initializes the signal immediately: zero flicker.
- Synchronization: Once the WASM is active,
initial()is re-run on the client to synchronize with the current browser state (e.g., reading a JS-accessible cookie). - Lifecycle Hooks: Use
on_hydrateto execute any client-side code immediately after hydration (e.g., event listeners).
Hydration Accessors
leptos_hydrated mirrors standard Leptos signal patterns to make state management intuitive.
1. Local (Independent)
Use hydrated_signal to create a new, independent hydrated signal. This works exactly like RwSignal::new(T), but it is hydration-aware.
2. Scoped (Shared)
Wrap a section of your component tree with <HydratedContext<T>> to share a hydrated signal. Use use_hydrated_context<T>() in descendants to access it.
3. Global (Shared)
Use <HydratedContext<T> global=true /> (typically in your app shell) to provide state globally across your entire application.
Quick Start
1. Define your State with Hydratable
Implement the Hydratable trait to define how your state is initialized and synchronized.
use *;
use *;
use ;
;
Server-Side Setup
1. Middleware
You must add the .hydrated() middleware to your Axum router.
// src/main.rs (Server)
use HydratedRouterExt;
let app = new
.leptos_routes
.fallback
.hydrated // <--- Add this before .with_state()
.with_state;
Isomorphic Helpers
get_cookie(name): Reads a cookie by name.set_cookie(name, value, options): Sets a cookie.get_query_param(name): Reads a URL query parameter.
Utilities
isomorphic! { state => ..., hydrate => ... }: Branch logic for server-seed vs client-hydration.use_hydrated_context<T>(): Accesses state from context (returnsOption<RwSignal<T>>).