Skip to content

How it works ​

Interact mounts interactive regions inside a CakePHP view. Each island has a PHP class, its own declared state, and a native template or element. Alpine connects that region to PHP; Interact returns HTML when its state changes.

One view, several islands ​

On an initial page request, the controller renders its normal view. Calls to $this->Interact->render() mount islands wherever their HTML belongs. This example mounts Counter and ResourceSearch side by side.

Initial page request Server → browser
CakePHP routeController actionPrepares the surrounding page.
Hosting view · AppViewLayout + page templateNormal page content, with a mount call for each island.
Mount Counterrender('Counter')
PHP islandCounterIslandCount state + increment action
Island renderer · TemplateViewcounter.phpNative island template
Browser regionCounter HTML + AlpineOwn state and request queue
Follow each mount from PHP to its browser region. Both independent islands belong to the same HTML document.

The mount names resolve to App\Island\CounterIsland and App\Island\ResourceSearchIsland. Their templates live under templates/island/. Each mount constructs its island, calls initialize(), assigns declared props, authorizes, calls mount(), and renders. See the full lifecycle.

Each island renders through a separate TemplateView. It receives declared props, state, errors, and viewData() on both initial and subsequent renders. Controller view variables and the hosting AppView's helper configuration do not automatically cross into island content. Pass initial values through props.

From interaction to HTML update ​

Clicking a counter button calls $server.call('increment'). A model binding can also synchronize writable state. Both use the owning island's update endpoint.

An island update Repeat per interaction
1 · BrowserInteract captures the interactionSend the signed snapshot, writable edits, and any action through fetch.
2 · CakePHP update endpointVerify, restore, and authorizeVerify the snapshot. Construct a fresh PHP island, initialize it, restore declared values, and apply accepted inputs before authorization.
3 · Authorized PHP behaviorRun hooks and the requested action, then renderCall updated() for changes and any declared action. TemplateView renders the island with its current data.
4 · BrowserAccept state and morph this island's HTMLAlpine Morph preserves newer drafts, focus, and retained local Alpine state. Other islands keep their own state.
The browser keeps the new signed snapshot for the next interaction. The original controller action, layout, and mount() do not run again.

CakePHP's CSRF and application middleware still apply. A signed snapshot protects integrity; each request still needs current authorization. Validation and saving remain application code, and synchronizing state does not save it.

This chart shows the normal rendered response. Renderless actions return accepted state and events without rendering HTML. Redirects and downloads use the same authorized action lifecycle.

Nested and page islands ​

An island template can mount child islands with the same helper. Each child has its own PHP class, template, state, and requests. Stable keys let a parent update preserve matching children and their drafts. Use explicit reactive props or model bindings to connect parent and child values, and events to coordinate siblings.

For a page island, the controller selects IslandView instead of the normal hosting view. IslandView mounts the page island and wraps its content in the normal layout on the initial GET. TemplateView still renders the island content, which can reuse an action template. Later interactions follow the same update flow above.

See Rendering and helpers for view customization, or follow the Quickstart to build the counter.