Skip to content

Custom columns

For a different cell appearance, give the column a namespaced type and register a matching renderer. Use built-in formatting when only the value needs to change.

Laravel

use InertiaX\Table\Columns\TextColumn;
TextColumn::make('role')->type('acme/role');

The key role still selects the source field. The type acme/role selects the React renderer.

React

import {
register,
type TableCellRendererProps,
type TableCustomizationOptions,
} from '@inertiax/react-table';
import { AppTable } from '@/components/app-table';
function RoleCell({ cell }: TableCellRendererProps) {
return <strong>{String(cell.value ?? '')}</strong>;
}
const customization = {
cellRenderers: [register('acme/role', RoleCell)],
} satisfies TableCustomizationOptions;
export function UsersIndex() {
return <AppTable prop="users" customization={customization} />;
}

Pass the same customization object to TableProvider to register it across the application. See Registration & diagnostics for scope and missing-renderer behavior.

For Eloquent and collections, a searchable column with a custom type needs a searchUsing() callback, even when created with TextColumn. With a custom source, searchable columns must keep type('text'); see Custom-source search.

A cell renderer also receives the row’s ID, so a cell can link to the record’s page:

Laravel

TextColumn::make('name')->type('acme/user-link');

React

import { Link } from '@inertiajs/react';
import {
register,
type TableCellRendererProps,
type TableCustomizationOptions,
} from '@inertiax/react-table';
import { AppTable } from '@/components/app-table';
function UserLinkCell({ cell, rowId }: TableCellRendererProps) {
return <Link href={`/users/${rowId}`}>{String(cell.value ?? '')}</Link>;
}
const customization = {
cellRenderers: [register('acme/user-link', UserLinkCell)],
} satisfies TableCustomizationOptions;
export function UsersIndex() {
return <AppTable prop="users" customization={customization} />;
}

rowId is the row’s key: the model’s primary key, or the field the table names with rowKey(). Use your own route helper for the URL. An edit or delete button works the same way; see Authorization & security for its endpoint.

Column meta() supplies configuration shared by all rows. A cell decorator can supply metadata for one row:

Laravel

use InertiaX\Table\Columns\CellPayload;
TextColumn::make('role')
->type('acme/role')
->meta('compact', true)
->decorateUsing(function (CellPayload $cell): CellPayload {
return $cell->putProperty('emphasized', $cell->value === 'admin');
});

The renderer reads column.meta and cell.meta respectively. Cell renderer props also include rowId. All metadata reaches the browser; follow the field exposure rules.

See Column API for reusable decorator classes and stage ordering.

View Markdown