Examples menu

Contact Form

Fill in the form, attach a file if you like, and send it. Wrong fields show an error next to them. The form posts as multipart/form-data: text fields arrive in $c->input(), the file in $c->file(), and the form comes back re-rendered over SSE.

No base64 overhead. Datastar's contentType: 'form' modifier submits the nearest <form enctype="multipart/form-data"> as a real multipart POST: files travel as binary, not JSON blobs.
Two validation layers. HTML5 required / type="email" / minlength attributes make Datastar call reportValidity() before the request is even sent. The server then re-validates every field independently.
$c->file('attachment') returns the parsed upload array (name, type, tmp_name, size) if the upload succeeded, or null if no file was sent or the upload failed.
State shared via PHP references. The action and view closures share mutable variables with use (&$ref). No signals needed: nothing is client-reactive. The SSE block re-render reads the updated values directly via Twig.
Success toggled server-side. On clean submission $submitted becomes true; the re-rendered block switches to the confirmation panel. No page reload, no client branching.

Actions

submit

Validates all fields server-side. Mutates shared PHP reference variables on failure or on success, then calls $c->sync() to trigger a block re-render via SSE.

Views

contact-form.html.twig

Form with inline errors and a success panel. Submitted as multipart/form-data via Datastar contentType: form, with the context id in a hidden via_ctx field.