Skip to the demo
Demos

Forms & validation

Every field validates on the server as you type — the rule chain lives on the component (@validate). Type an invalid email or a short password and the message appears; fix it and it clears. Submit runs the whole form.

@expose @validate((r) => r.required().min(2).max(50)) name = "";
@expose @validate((r) => r.required().email()) email = "";
@expose @validate((r) => r.required().min(8)) password = "";

@expose async submit() {
  await this.validate();   // runs all @validate rules on the server
  this.flash("Account created.", "success");
}

// `live` validates the field on the server on every keystroke
<input value={this.email} live type="email" />
<span error={this.errors.email} />   // appears / clears reactively
<button type="submit" loadingAttr="disabled">Create account</button>