Enable JavaScript to use the interactive tables. You can also read the quick start .
Orders Search for a customer, filter by status or date, and sort by total.
Pass OrdersTable::make('orders') to Inertia::render() and render it with AppTable.
use App\Models\Order;
use InertiaX\Table\Columns\BadgeColumn;
use InertiaX\Table\Columns\DateColumn;
use InertiaX\Table\Columns\DateTimeColumn;
use InertiaX\Table\Columns\NumberColumn;
use InertiaX\Table\Columns\TextColumn;
use InertiaX\Table\Filters\DateFilter;
use InertiaX\Table\Filters\SelectFilter;
use InertiaX\Table\Table;
class OrdersTable extends Table
{
protected static bool $defaultSelection = true;
protected static bool $defaultAutoFilters = false;
protected function data(): mixed
{
return Order::query();
}
protected function columns(): array
{
return [
NumberColumn::make('id')->numberCast('int')->visible(false),
TextColumn::make('reference', 'Order')->sortable()->searchable()->copyable(),
TextColumn::make('customer_name', 'Customer')
->relationship('customer', 'name')->sortable()->searchable(),
BadgeColumn::make('status')->variant([
'pending' => 'warning', 'paid' => 'success', 'packing' => 'info',
'shipped' => 'success', 'cancelled' => 'danger', 'refunded' => 'secondary',
]),
NumberColumn::make('total_cents', 'Total')->numberCast('int')
->currency('USD', divideBy: 100)->sortable(),
DateColumn::make('ordered_on', 'Ordered')->sortable(),
DateTimeColumn::make('shipped_at', 'Shipped')->sortable(),
];
}
protected function filters(): array
{
return [
SelectFilter::make('status')->options([
'pending' => 'Pending', 'paid' => 'Paid', 'packing' => 'Packing',
'shipped' => 'Shipped', 'cancelled' => 'Cancelled', 'refunded' => 'Refunded',
]),
DateFilter::make('ordered_on', 'Ordered'),
];
}
}Customers Filter by plan or status, and hide or show columns from the Columns menu.
The plan badge maps each plan to a color, and toggleable columns appear in the Columns menu.
use App\Models\Customer;
use InertiaX\Table\Columns\BadgeColumn;
use InertiaX\Table\Columns\BooleanColumn;
use InertiaX\Table\Columns\DateColumn;
use InertiaX\Table\Columns\NumberColumn;
use InertiaX\Table\Columns\TextColumn;
use InertiaX\Table\Filters\BooleanFilter;
use InertiaX\Table\Filters\SelectFilter;
use InertiaX\Table\Table;
class CustomersTable extends Table
{
protected static bool $defaultAutoFilters = false;
protected static bool $defaultToggleableColumns = true;
protected function data(): mixed
{
return Customer::query();
}
protected function columns(): array
{
return [
NumberColumn::make('id')->numberCast('int')->visible(false)->toggleable(false),
TextColumn::make('name')->sortable()->searchable(),
TextColumn::make('email')->searchable()->copyable(),
TextColumn::make('company')->sortable(),
BadgeColumn::make('plan')->variant([
'enterprise' => 'primary', 'growth' => 'success', 'starter' => 'info', 'free' => 'secondary',
]),
BooleanColumn::make('active', 'Status')->trueLabel('Active')->falseLabel('Paused'),
NumberColumn::make('lifetime_orders', 'Orders')->numberCast('int')->sortable(),
DateColumn::make('joined_on', 'Joined')->sortable(),
];
}
protected function filters(): array
{
return [
SelectFilter::make('plan')->options([
'free' => 'Free', 'starter' => 'Starter', 'growth' => 'Growth', 'enterprise' => 'Enterprise',
]),
BooleanFilter::make('active', 'Status'),
];
}
}Support queue Filter tickets by priority or status, or search subjects and customers.
Each badge maps its values to colors, and the select filters narrow the queue.
use App\Models\SupportTicket;
use InertiaX\Table\Columns\BadgeColumn;
use InertiaX\Table\Columns\DateTimeColumn;
use InertiaX\Table\Columns\NumberColumn;
use InertiaX\Table\Columns\TextColumn;
use InertiaX\Table\Filters\SelectFilter;
use InertiaX\Table\Table;
class SupportTicketsTable extends Table
{
protected static bool $defaultAutoFilters = false;
protected function data(): mixed
{
return SupportTicket::query();
}
protected function columns(): array
{
return [
NumberColumn::make('id')->numberCast('int')->visible(false),
TextColumn::make('reference', 'Ticket')->searchable()->copyable(),
TextColumn::make('subject')->searchable()->wrap(),
TextColumn::make('customer_name', 'Customer')
->relationship('customer', 'name')->sortable()->searchable(),
BadgeColumn::make('priority')->variant([
'urgent' => 'danger', 'high' => 'warning', 'medium' => 'info', 'low' => 'secondary',
]),
BadgeColumn::make('status')->variant([
'open' => 'warning', 'waiting' => 'secondary', 'resolved' => 'success', 'closed' => 'success',
]),
TextColumn::make('assignee')->sortable(),
DateTimeColumn::make('opened_at', 'Opened')->sortable(),
];
}
protected function filters(): array
{
return [
SelectFilter::make('priority')->options([
'low' => 'Low', 'medium' => 'Medium', 'high' => 'High', 'urgent' => 'Urgent',
]),
SelectFilter::make('status')->options([
'open' => 'Open', 'waiting' => 'Waiting', 'resolved' => 'Resolved', 'closed' => 'Closed',
]),
];
}
}Quick start: Users A complete table from your Laravel model, with no columns declared.
Columns and field types are inferred from your model.
$users = Table::make('users')
->data(User::class)
->autoColumns();
return Inertia::render('users/index', [
$users,
]);Search & filters: Users Search, filter by role, sort, select rows, and hide or show columns.
Declare columns, add a role filter, and enable row selection.
Table::make('users')
->data(User::class)
->addColumns([
NumberColumn::make('id')
->numberCast('int')->visible(false),
TextColumn::make('name')
->searchable()->sortable(),
TextColumn::make('email')->toggleable(),
TextColumn::make('role'),
DateColumn::make('joined_on', 'Joined')
->format('M j')->toggleable(),
])
->addFilter(SelectFilter::make('role')->options([
'admin' => 'admin',
'analyst' => 'analyst',
'engineer' => 'engineer',
]))
->selection()
->pageSize(5);Advanced filters Orders after October 5 that are pending or packing: a Match any group inside Match all. Open Filters to change a condition, add a group, or clear the filters.
Call filterMode(FilterMode::Advanced) in the controller; OrdersTable is the same class as in the Orders example.
use App\Tables\OrdersTable;
use Inertia\Inertia;
use Inertia\Response;
use InertiaX\Table\Enums\FilterMode;
class OrderController
{
public function index(): Response
{
return Inertia::render('orders/index', [
OrdersTable::make('orders')->filterMode(FilterMode::Advanced),
]);
}
}Custom cells Totals use a custom React cell; search, filter by status, or sort by date.
Laravel formats statuses and dates; React formats totals.
Table::make('orders')
->data(Order::class)
->addColumns([
NumberColumn::make('id')
->numberCast('int')->visible(false),
TextColumn::make('reference', 'Order')
->searchable(),
TextColumn::make('customer'),
NumberColumn::make('total')->type('demo/money'),
BadgeColumn::make('status')->variant([
'paid' => 'success', 'processing' => 'warning',
'refunded' => 'secondary', 'failed' => 'danger',
]),
DateColumn::make('placed_at', 'Placed')
->format('M j')->sortable(),
])
->addFilter(SelectFilter::make('status')->options([
'paid' => 'paid', 'processing' => 'processing',
'refunded' => 'refunded', 'failed' => 'failed',
]))
->pageSize(5);Custom layout: Order cards Search, sort, filter, and page through orders shown as cards.
Pass your own layout as AppTable children and place the search, sort, filter, and pagination controls around it.
use App\Models\Order;
use InertiaX\Table\Columns\BadgeColumn;
use InertiaX\Table\Columns\DateColumn;
use InertiaX\Table\Columns\DateTimeColumn;
use InertiaX\Table\Columns\NumberColumn;
use InertiaX\Table\Columns\TextColumn;
use InertiaX\Table\Filters\DateFilter;
use InertiaX\Table\Filters\SelectFilter;
use InertiaX\Table\Table;
class OrdersTable extends Table
{
protected static bool $defaultSelection = true;
protected static bool $defaultAutoFilters = false;
protected function data(): mixed
{
return Order::query();
}
protected function columns(): array
{
return [
NumberColumn::make('id')->numberCast('int')->visible(false),
TextColumn::make('reference', 'Order')->sortable()->searchable()->copyable(),
TextColumn::make('customer_name', 'Customer')
->relationship('customer', 'name')->sortable()->searchable(),
BadgeColumn::make('status')->variant([
'pending' => 'warning', 'paid' => 'success', 'packing' => 'info',
'shipped' => 'success', 'cancelled' => 'danger', 'refunded' => 'secondary',
]),
NumberColumn::make('total_cents', 'Total')->numberCast('int')
->currency('USD', divideBy: 100)->sortable(),
DateColumn::make('ordered_on', 'Ordered')->sortable(),
DateTimeColumn::make('shipped_at', 'Shipped')->sortable(),
];
}
protected function filters(): array
{
return [
SelectFilter::make('status')->options([
'pending' => 'Pending', 'paid' => 'Paid', 'packing' => 'Packing',
'shipped' => 'Shipped', 'cancelled' => 'Cancelled', 'refunded' => 'Refunded',
]),
DateFilter::make('ordered_on', 'Ordered'),
];
}
}Collections: Activity log Search by actor or sort by time, on an in-memory collection.
Pass a collection or an array and declare its columns.
Table::make('activity')
->data(collect($recentEvents))
->addColumns([
TextColumn::make('id')->visible(false),
TextColumn::make('actor')->searchable(),
TextColumn::make('action'),
TextColumn::make('target')->copyable(),
DateTimeColumn::make('occurred_at', 'Time')
->format('H:i')->sortable(),
])
->pageSize(5);