GET STARTED FEATURE
Ship an interactive component
Add a #[UiOn] handler and the framework signs the event into the page, dispatches it to one endpoint and patches the reply back. No client framework needed.
Ship an interactive component
Making a component interactive is adding a method, not a frontend. You declare the backend event on the component; the framework wires the signed round-trip and patches the DOM.
#[UiOn(part: 'input', event: 'change')]public function onInputChanged(UiInteractionEvent $event): UiInteractionResult{ return UiInteractionResult::patch(patches: [ new UiResponsePatch( op: UiResponsePatch::OP_SET_TEXT, targetInstance: $event->instanceId, targetName: 'server-ack', value: 'Server received: ' . (string) $event->value(), ), ]);}The round-trip, wired for you
The server signs the event manifest into the page; the tiny capture-only runtime posts matches to POST /__ui/dispatch; the dispatcher verifies the signature, runs your method, and returns DOM patches scoped to the firing instance. The field above is live — type and the server echoes back. See Interactive HTML and the event runtime for the full machinery.
Shipping interactivity by adding a server method keeps the whole feature inside one architecture: no per-feature endpoint, no client routing, no second framework. You grow capability by declaration — exactly as the rendering thesis promises.
How it works
Add #[UiOn(part, event)] to a component method returning a UiInteractionResult. The server signs the event manifest into the page; the tiny runtime captures matches and posts to POST /__ui/dispatch; the server runs your method and returns scoped patches. The field above is live — type and the server echoes back: a shipped interactive component, no client framework.
Why it matters
Shipping interactivity by adding a server method keeps the whole feature inside one architecture: no per-feature endpoint, no client routing, no second framework. You grow capability by declaration, exactly as the rendering thesis promises.