Row Links & Modals
Make table rows clickable so users can navigate to a detail page or open a modal.
Row Links
Make each row a link to a URL:
$table->rowLink(fn($user) => route('users.show', $user));
The callback receives the row item (model instance) and must return a URL string or null.
Clicking anywhere on the row (except cells with clickable: false) navigates to the URL using an Inertia visit.
External Row Links (non-Inertia pages)
When the target page is not an Inertia page, use href: true to navigate with a plain browser redirect instead of an Inertia visit:
$table->rowLink(fn($ticket) => route('tickets.show', $ticket), href: true);
This sets rowLinkType to 'href' and uses window.location.href on click.
Opening a Row Link in a New Tab
Rows navigate in the current tab by default. For links that belong somewhere else - a report,
an external dashboard - pass newTab: true:
$table->rowLink(fn($environment) => route('accesslogs.show', $environment), href: true, newTab: true);
The new tab wins over the row link type, so it works alongside href as well as on its own.
A row is a <tr>, not an <a>. Even with '_blank' there is no middle click, no ctrl-click, no
"copy link address" and no URL in the status bar, and a screen reader does not announce a link.
When those matter, render an anchor in the column itself with an as callback instead.
Row Modals
Open a modal instead of navigating:
$table->rowModal(fn($user) => route('users.edit', $user));
This sets rowLinkType to 'modal'. On click, the package fetches the URL with Accept: application/json and passes the response to your application's openModal function.
Host app requirement
The package dispatches a table-builder:open-modal DOM event on window. Listen for it wherever your modal system lives:
window.addEventListener('table-builder:open-modal', (e) => {
openModal((e as CustomEvent).detail);
});
The URL must return JSON in this shape:
{
"component": "MyModal",
"title": "Optional title",
"data": {}
}
component is the modal Vue component name. How you render it is up to your app - a common pattern is a ModalRenderer component that resolves components/${name}.vue dynamically and renders it inside a <dialog> or overlay.
Signature (rowLink)
rowLink(callable $callback, bool $modal = false, bool $href = false, bool $newTab = false): self
Signature (rowModal)
rowModal(callable $callback): self
Conditional Links
Return null from the callback to make a specific row non-clickable:
$table->rowLink(function ($user) {
if (! auth()->user()->can('view', $user)) {
return null;
}
return route('users.show', $user);
});
Non-Clickable Cells
Individual columns can opt out of following the row link. This is useful for action columns (edit/delete buttons):
->column('actions', 'Actions', clickable: false, canBeHidden: false)
Row Clicks Without a Link
Rows without a row link emit a row-click event from the Vue component instead. See
Vue Component.
Primary Key
The row link system needs to identify each row. For Eloquent models this is automatic. For plain arrays or models with a non-standard primary key, configure it explicitly:
$table->rowKey('uuid');
rowKey() and the older primaryKey() set the same thing: the field the component uses for selection, bulk actions,
reordering and the key of row-click. See Bulk Actions.
How It Works
- After loading the resource, the table maps
rowLinkCallableover every row to produce arowLinksarray. - This array is passed to the frontend alongside
rowLinkType('link','modal', or'href') androwLinkTarget('_self'or'_blank'). - The Vue component matches each row by index to its link URL and applies the appropriate click handler.
