Data sources and rows
InertiaX executes both database-backed and in-memory Tables. Source kind matters: built-in operations preserve equivalent meaning, while custom operations must declare the kinds they actually support.
Supported sources
Section titled “Supported sources”Eloquent builder
Section titled “Eloquent builder”UsersTable::make('users')->data( User::query()->where('account_id', $account->id),)The builder remains lazy. Filters, search, sorting, and pagination are applied before rows are retrieved.
Model class
Section titled “Model class”UsersTable::make('users')->data(User::class)The model class is normalized to User::query().
Collection
Section titled “Collection”AuditEventsTable::make('audit_events')->data( collect([ ['id' => 1, 'event' => 'Account created', 'actor' => 'Ada Lovelace'], ['id' => 2, 'event' => 'Role changed', 'actor' => 'Grace Hopper'], ]),)Laravel and Eloquent Collections are accepted. Eloquent Collections are treated as an in-memory snapshot, not converted back into a query.
UsersTable::make('users')->data([ ['id' => 1, 'name' => 'Ada'], ['id' => 2, 'name' => 'Grace'],])Arrays normalize to a Laravel Collection.
Deferred source
Section titled “Deferred source”Use a closure when resolving the source requires request or container context:
UsersTable::make('users')->data( fn () => User::query()->whereBelongsTo(auth()->user()->account),)The callback is evaluated during Table materialization and must return one of the supported source types. Authorization and tenant scoping should already be enforced by this source; the frontend is not an authorization boundary.
Define data in the class
Section titled “Define data in the class”Reusable Tables can own their source:
class ActiveUsersTable extends Table{ protected function data(): mixed { return User::query()->where('active', true); }}A fluent ->data(...) call at the use site overrides it. This is useful when a shared definition
needs a page-specific query.
Row identity
Section titled “Row identity”Each result row must have a stable, unique key.
- Eloquent builders use the model’s configured primary key.
- Collections of models use the model primary key.
- Arrays and ordinary Collections default to
id. - Call
rowKey('uuid')when the source uses another field.
SessionsTable::make('sessions') ->data($sessions) ->rowKey('uuid')Row keys drive selection, rendering identity, and state reconciliation. Missing or duplicate identity is invalid; do not use a changing display value as the key. Numeric identities must be JavaScript-safe integers. Return database IDs above that range as exact strings rather than numbers.
Execution order
Section titled “Execution order”For every source, Table operations run in this order:
- filters;
- global search;
- sorting;
- pagination;
- row and cell serialization.
This is why a page count reflects the filtered result and why sorting happens before the page is sliced. Definitions are replay-safe: materializing the same reusable Table for another request starts from a fresh source and fresh feature definitions.
Choosing between Eloquent and Collection
Section titled “Choosing between Eloquent and Collection”Prefer an Eloquent builder for database-backed, potentially large data. It keeps filtering, sorting, and pagination in SQL. Use Collections for already-materialized domain data or bounded datasets. A custom operation that only has a valid SQL meaning should support Eloquent only and fail clearly on a Collection rather than silently changing semantics.