Mercure Integration

Use Mercure when table data can change outside the current browser session and you want automatic refresh.

MercureConfig can now be configured manually through DataTable::mercure(...) or auto-resolved from #[AsDataTable(..., mercure: true)].

What The Integration Does

When mercure is configured on a table:

  1. Backend options include a mercure object (hubUrl, topics, optional withCredentials, optional debounceMs).
  2. The Stimulus controller opens an EventSource to the hub with ?topic=....
  3. On each message, the controller emits a datatables:mercure:message event and triggers table.ajax.reload(null, false).
  4. The SSE connection is closed automatically on controller disconnect().

Minimal Setup

#[AsDataTable(Book::class, mercure: true)]
final class BookDataTable extends AbstractDataTable
{
}

When auto-resolution is enabled:

  • the bundle reads the default Symfony Mercure hub URL
  • explicit API Platform mercure.topics are reused when available
  • otherwise the bundle falls back to an item IRI template (for example /api/books/{id})
  • if no API Platform item metadata is available, it falls back to /datatables/books/{id}

Advanced Setup

$dataTable->mercure(
    hubUrl: '/.well-known/mercure',
    topics: ['admin/books', 'admin/authors'],
    withCredentials: true,
    debounceMs: 300,
);

Notes:

  • withCredentials enables cookie/auth forwarding in the SSE request.
  • debounceMs is applied client-side before reload (500ms by default).
  • topics accepts one or many topics.

Publishing Updates

If symfony/mercure is available, the bundle registers MercureUpdatePublisher and injects it into the Ajax edit controller.

When boolean inline edit is called with topics, the controller publishes:

{
  "type": "edit",
  "id": "...",
  "field": "..."
}

You can also publish manually with MercureUpdatePublisher::publish() or publishForDataTable().

Operational Notes

  • Mercure refresh uses ajax.reload(...): tables configured only with static data will not auto-refresh from SSE.
  • No Mercure config means no SSE subscription (dynamic import is skipped).
  • If the table receives many events, tune debounceMs to protect backend load.
  • private: true from API Platform metadata is not mapped automatically to withCredentials.