Skip to content

Your first Table

This tutorial starts from the User model already present in a Laravel application. InertiaX will infer the first set of columns and filters, so you can reach a useful result before learning every configuration option.

Create a controller action that returns a named Table as an Inertia prop:

app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Inertia\Inertia;
use Inertia\Response;
use InertiaX\Facades\InertiaX;
class UserController
{
public function index(): Response
{
return Inertia::render('Users/Index', [
InertiaX::table('users')
->data(User::class)
->autoColumns()
->filterableColumns()
->autoFilters(),
]);
}
}

The four calls each have one job:

  • data(User::class) uses User::query() as the lazy Eloquent source.
  • autoColumns() infers columns from the model and database metadata.
  • filterableColumns() marks the inferred columns as filterable.
  • autoFilters() creates a matching built-in Filter for each filterable column. It is enabled by default, but is written explicitly here so the example documents its intent.

Automatic columns use the model’s $visible list when present, otherwise its $fillable list, and then remove every $hidden attribute. The model’s primary key is added as the hidden row identity when necessary.

The standard Laravel User model therefore does not expose its hidden password. Treat the model allowlist as a security boundary anyway: review $visible, $fillable, and $hidden before using automatic columns on a model with sensitive attributes.

The installation guide mounts InertiaXProvider once in resources/js/app.tsx and imports the stylesheet there. Create the matching Inertia page with only the Table prop:

resources/js/pages/Users/Index.tsx
import { InertiaX } from '@inertiax/react-inertia';
export default function UsersIndex() {
return (
<main>
<h1>Users</h1>
<InertiaX prop="users" />
</main>
);
}

Keeping the provider above Inertia’s App preserves one application runtime while pages change.

routes/web.php
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
Route::get('/users', [UserController::class, 'index'])->name('users.index');

Open /users. You should see the model’s allowed fields, a filter for each displayed field, the default refresh control, and pagination with 10 rows per page. Interactions reload only the users Inertia prop and keep the Table state in its own URL namespace.

Inference is a starting point, not a requirement. Add an explicit field when its domain presentation or capabilities matter; automatic inference skips a key that is already declared:

use InertiaX\Components\Table\Columns\TextColumn;
InertiaX::table('users')
->data(User::class)
->autoColumns()
->filterableColumns()
->autoFilters()
->addColumn(
TextColumn::make('name', 'Full name')
->searchable()
->sortable()
->filterable(),
);

The remaining fields stay inferred. The name column now has an intentional label plus search and sorting behavior.