Defining Tables
Every Table has an ID, a data source, columns, and optional filters or capability overrides. Define it inline when it is local to one response; use a class when the definition is reused, inherited, or large enough to deserve its own file.
Inline builders
Section titled “Inline builders”The facade creates a lazy Table builder that can be returned directly as an Inertia prop:
use InertiaX\Components\Table\Columns\TextColumn;use InertiaX\Facades\InertiaX;
return Inertia::render('Users/Index', [ InertiaX::table('users') ->data(User::query()) ->addColumn(TextColumn::make('name', 'Name')->sortable()),]);Use this style for a small, page-specific Table. The prop name is users, and its protocol
component ID is also users. Choose a stable name of 1–64 characters that starts with an ASCII
letter and then uses only letters, numbers, _, or -. Laravel rejects invalid names immediately.
Reusable Table classes
Section titled “Reusable Table classes”<?php
namespace App\Tables;
use App\Models\User;use InertiaX\Components\Table\Columns\BadgeColumn;use InertiaX\Components\Table\Columns\NumberColumn;use InertiaX\Components\Table\Columns\TextColumn;use InertiaX\Components\Table\Filters\SelectFilter;use InertiaX\Components\Table\Table;
class ActiveUsersTable extends Table{ protected static int $defaultPageSize = 25;
protected function data(): mixed { return User::query()->where('active', true); }
protected function columns(): array { return [ NumberColumn::make('id', 'ID')->sortable(), TextColumn::make('name', 'Name')->sortable()->searchable(), BadgeColumn::make('role', 'Role'), ]; }
protected function filters(): array { return [ SelectFilter::make('role', 'Role')->options([ 'Admin' => 'Administrator', 'Engineer' => 'Engineer', ]), ]; }}Return it by choosing the prop/instance name:
return Inertia::render('Users/Index', [ ActiveUsersTable::make('active_users'),]);The class may provide its own protected data() method, or the caller may provide the source:
ActiveUsersTable::make('active_users')->data($query)A fluent data() call wins over the class declaration. The same per-use precedence applies to
columns, filters, and behavior.
Mutating inherited definitions
Section titled “Mutating inherited definitions”Column and filter collections use explicit operations:
ActiveUsersTable::make('users') ->addColumn(TextColumn::make('email', 'Email')) ->replaceColumn(BadgeColumn::make('role', 'Access level')) ->removeColumn('id') ->addFilter(TextFilter::make('email', 'Email'));addColumn()/addFilter()extend the existing declaration.replaceColumn()/replaceFilter()require and replace the matching key.removeColumn()/removeFilter()remove the matching key.clearColumns()/clearFilters()empty the collection.setColumns()/setFilters()are convenience macros for clear then add.
Plural variants accept arrays. They do not weaken duplicate or missing-target validation.
Class defaults
Section titled “Class defaults”Protected static defaults are inherited and may be overridden by a child class or a fluent call:
use InertiaX\Components\Table\Enums\FilterMode;use InertiaX\Components\Table\Enums\SelectionMode;
protected static int $defaultPageSize = 25;protected static array $defaultPageSizeOptions = [10, 25, 50];protected static bool $defaultPagination = true;protected static bool $defaultSorting = true;protected static bool $defaultMultiSort = true;protected static bool $defaultSelection = false;protected static SelectionMode $defaultSelectionMode = SelectionMode::Multiple;protected static bool $defaultAutoColumns = false;protected static bool $defaultAutoFilters = true;protected static FilterMode $defaultFilterMode = FilterMode::Basic;protected static bool $defaultRefreshButton = true;Column-wide defaults are also available: $defaultSortableColumns, $defaultCopyableColumns,
$defaultSearchableColumns, $defaultToggleableColumns, $defaultVisibleColumns,
$defaultWrapColumns, $defaultTruncateColumns, and $defaultFilterableColumns.
Prefer per-column capability calls when only a few fields need the behavior. Use class defaults when the policy genuinely applies to the entire Table family.
Multiple Tables on one page
Section titled “Multiple Tables on one page”Every Table needs a distinct ID and matching prop:
return Inertia::render('Dashboard', [ ActiveUsersTable::make('active_users'), AuditEventsTable::make('audit_events'),]);<InertiaX prop="active_users" /><InertiaX prop="audit_events" />State is namespaced by Table ID, preventing pagination, filters, or requests from colliding.