Skip to content
Interact for CakePHP

Meet CakePHP Interact

Reactive interfaces. The CakePHP way.

Build interactive CakePHP interfaces with PHP and Alpine. Add live search, responsive forms, and smooth page visits without leaving the stack you know.

For CakePHP 6.x · PHP 8.5+CakePHP 6 is currently unreleased.

PHP state & actions Alpine, included

A little PHP. A live interface. Live PHP
<?php
class ExoplanetsIsland extends Island
{
    #[State(writable: true)]
    public string $search = '';

    #[Pagination(url: true, history: ['page'])]
    public PaginationState $paging;

    public function viewData(): array
    {
        $planets = $this->fetchTable(ExoplanetsTable::class);
        $query = $planets->find('search', search: $this->search);

        return ['planets' => $this->paginate($query, ['limit' => 2])];
    }
}
Simplified example · imports omitted

Explore distant worlds.

Try it here

300 planets in the collection

PHP → HTML
  • 55 Cnc c

    Radial Velocity

    Discovered in 2004

  • 55 Cnc e

    Radial Velocity

    Discovered in 2004

Planet data from the NASA Exoplanet Archive.

Try Interact

A little mission control.

Try each interaction, then take a peek at the code that makes it work.

Live binding

Name your spacecraft and see its call sign update.

Call sign: awaiting a name.

<label for="demo-name">Spacecraft name</label>
<input id="demo-name" name="name"
    x-interact:model.live>

PHP actions

Pack supplies with an action that runs in PHP.

0supplies packed
<?php
#[Action]
public function increment(): void
{
    $this->count++;
}

Loading feedback

Run a simulated system check and see when it is working.

Simulated check · 450ms

<button :disabled="$server.busy">
    <span x-show="$server.busy">Working…</span>
</button>

URL state

Choose your display spacing. The URL remembers it.

ScanMapReport
<?php
#[State(writable: true, url: true, history: true)]
public string $density = 'comfortable';

Polling

Keep the mission clock fresh while this island is visible.

Mission clock · UTC · Updates every 5 seconds

<section x-interact:poll.5s.visible>
    <!-- Fresh PHP output, just here. -->
</section>

Alpine state

Open mission details instantly with local browser state.

Destination: the stars. This detail opens locally.

<div x-data="{ expanded: false }">
    <button @click="expanded = !expanded">
        View mission details
    </button>
</div>

Events

Send a signal from one island and watch another respond.

Spacecraft
Mission control 0 signals received
<?php
// In the sending island:
#[Action]
public function send(): void
{
    $this->dispatch('mission-signal');
}

// In the receiving island:
#[Action(on: 'mission-signal')]
public function receive(): void
{
    $this->received++;
}

Streaming

Watch a simulated mission report arrive in stages from one PHP action.

Ready when you are.

    

Simulated report · One request, three updates.

<?php
#[Action(stream: true)]
public function generate(): void
{
    $line = 'Scanning the horizon.';
    $this->stream('report', $line . "\n");
}

More with Interact

Keep going. Keep your stack.

There is more to explore when your application needs it.

Realtime across tabs

Refresh subscribed islands or receive events from other requests and jobs. Bring a provider adapter, including the optional Mercure integration.

Realtime subscriptions

Keep the page visits flowing

Use real links with enhanced navigation. Titles, history, scroll, and focus follow the visit without a full browser reload.

Explore navigation

Pagination, already connected

Pass your ORM query to paginate(). The Paginator helper produces real links that update the island and keep its filters in the URL.

Paginate an island

Compose smaller islands

Nest independent islands, pass reactive props, bind child values, and coordinate through events. Load them lazily when useful.

Compose islands Explore lazy loading

Uploads that stay in the flow

Send files with your island action and show upload progress. Keep validation, storage, and permissions in your CakePHP application.

Handle uploads

See how it works

One island. A universe to explore.

The search above uses a local snapshot from the NASA Exoplanet Archive. Filters stay in the URL, and PHP runs a CakePHP finder to return fresh HTML.

<?php
class ExoplanetsIsland extends Island
{
    #[State(writable: true)]
    public string $search = '';

    #[Pagination(url: true, history: ['page'])]
    public PaginationState $paging;

    public function viewData(): array
    {
        $planets = $this->fetchTable(ExoplanetsTable::class);
        $query = $planets->find('search', search: $this->search);

        return ['planets' => $this->paginate($query, ['limit' => 2])];
    }
}
Simplified example · imports omitted

Start with one interaction.

A search box, a live preview, or an inline editor. Add Interact where your application needs it.

Get started

Requires PHP 8.5+ and CakePHP 6.x, currently unreleased.