UI frameworks
Shared validation for Leptos server functions and WASM clients, without a leptos dependency.

vld-leptos lets the same vld schemas check server-function arguments on the server and form fields in the browser. It has no leptos dependency (it works with any Leptos version) and builds for native and WASM targets. The API is the same as vld-dioxus: both re-export the form helpers from vld-integration-common.

Install

Cargo.toml
[dependencies]
vld = "0.5"
vld-leptos = "0.5"

No features. MSRV: 1.85 (see MSRV).

Example

use leptos::prelude::*;

fn name_schema() -> vld::primitives::ZString { vld::string().min(2).max(50) }
fn email_schema() -> vld::primitives::ZString { vld::string().email() }

#[server]
async fn create_user(name: String, email: String) -> Result<(), ServerFnError> {
    vld_leptos::validate_args! {
        name  => name_schema(),
        email => email_schema(),
    }
    .map_err(|e| ServerFnError::new(e.to_string()))?;
    Ok(())
}

#[component]
fn CreateUserForm() -> impl IntoView {
    let (name, set_name) = signal(String::new());
    let name_error = Memo::new(move |_| vld_leptos::check_field(&name.get(), &name_schema()));
    // ... render the input and `name_error`
}

Whole-struct validation with a schema! type:

vld::schema! {
    struct CreateUserSchema {
        name: String => vld::string().min(2).max(50),
        email: String => vld::string().email(),
    }
}

#[derive(serde::Serialize)]
struct CreateUserArgs { name: String, email: String }

let args = CreateUserArgs { name: "X".into(), email: "bad".into() };
let errors = vld_leptos::check_all_fields::<CreateUserSchema, _>(&args);
assert_eq!(errors.len(), 2);

API

  • validate_args! { arg => schema, ... } — validate local values; Result<(), VldServerError>.
  • validate::<S, T>(&value) / validate_value::<S>(&json) — validate against a schema type.
  • check_field(&value, &schema) / check_field_all(&value, &schema) — single-field checks for reactive UI.
  • check_all_fields::<S, T>(&value) — Vec<FieldError> for a whole form.
  • VldServerError { message, fields } — field_error, field_errors, has_field_error, error_fields, from_json, from_server_message.
  • FieldError { field, message }; prelude.

Gotchas

  • Field paths have no leading dot: name, user.email, items[0].
  • Parse errors coming back from a server function with VldServerError::from_server_message(&e.to_string()), not from_json (the Display of ServerFnError adds a prefix).