Leptos Hydrated
A lightweight library for flicker-free interactive state hydration in Leptos 0.8 that works with or without JavaScript.
Features
- Flicker-Free: Initializes signals with server-provided state immediately during hydration.
- Browser-First: Leverage state already in the browser (cookies, URL params) to render the first frame without waiting for API calls.
- Isomorphic: Works naturally in both SSR and CSR contexts.
- Trait-Based: Use the
Hydratabletrait to define state and refresh logic in one place. - Global & Scoped: Support for both global application state and scoped feature state.
- Zero Mismatch: Designed to avoid hydration warnings by matching server and client initial renders exactly.
Installation
Add this to your Cargo.toml:
[]
= "0.6"
Two Modes
| Mode | fetch() |
Use when |
|---|---|---|
| Injection-only | None (default) |
Server value is the source of truth (HTTP-only cookies, session tokens) |
| Injection + refresh | Some(v) |
Client can also re-read the same state (JS-readable cookies, URL params) |
Quick Start
1. Define your State with Hydratable
The most robust way to use leptos_hydrated is by implementing the Hydratable trait. This encapsulates your synchronous "seed" logic (e.g., cookies) and your asynchronous "refresh" logic (e.g., API calls).
use *;
use *;
use ;
2. Choose your hydration strategy
HydrateState (Global State)
Provides global state via context. Place it anywhere in your view tree.
HydrateContext (Scoped State)
Provides scoped state to a specific branch of the component tree.
3. Manual Hydration (Advanced)
If you don't want to use the trait, you can use the base components directly:
view!
Isomorphic Helpers
leptos_hydrated provides several helpers to read and write state consistently on both server and client, which is particularly useful inside Hydratable::initial().
get_cookie(name): Reads a cookie by name.- SSR: Reads from
http::request::Parts. - Client: Reads from
document.cookie.
- SSR: Reads from
set_cookie(name, value, options): Sets a cookie.- SSR: Uses
leptos_axum::ResponseOptionsto insert aSET-COOKIEheader. - Client: Updates
document.cookie.
- SSR: Uses
get_query_param(name): Reads a URL query parameter.- SSR: Reads from the request URI.
- Client: Reads from
window.location.search.
get_referer_query_param(name): Reads a query parameter from theRefererheader.- Note: Essential for server functions where the current request URI is the endpoint, but you need the original page's context.
get_header(name): Reads an arbitrary HTTP header by name.- SSR: Reads from
http::request::Parts. - Client: Returns
None.
- SSR: Reads from
set_header(name, value): Sets an arbitrary HTTP header.- SSR: Inserts into
leptos_axum::ResponseOptions. - Client: No-op.
- SSR: Inserts into
Server-Side Setup
In order for the isomorphic helpers to access request data on the server, you must use .leptos_routes_with_context in your Axum server setup. This provides the http::request::Parts and leptos_axum::ResponseOptions to the Leptos context.
// src/main.rs (Server)
let app: Router = new
.leptos_routes_with_context
.with_state;
Why use this instead of a standard Resource?
Standard Leptos Resources are fantastic for data that lives on the server and needs to be serialized to the client. However, they can cause "flickers" or require Suspense masks for data you already have on both sides (like a cookie).
leptos_hydrated allows you to:
- Render immediately on the server using a synchronous value.
- Hydrate immediately on the client with that same value (no flicker!).
- Refresh in the background once the WASM is ready to get the latest data.
Secure Hydration (HTTP-only Cookies)
When using sensitive data like authentication tokens in HTTP-only cookies, the client JavaScript cannot read the cookie to initialize state. leptos_hydrated solves this by allowing the server to read the cookie, fetch the corresponding user data, and inject only the result into the HTML.
The client hydrates the user data synchronously, while the secret token remains hidden from JavaScript.
Documentation
Full API documentation is available at docs.rs/leptos_hydrated.