Rendering and slots
Use the default renderer for table structure and slots for targeted application content. The server resource remains authoritative even when a cell or control is replaced.
Custom cells
<DataTable :resource="topics">
<template #cell(name)="{ item }">
<strong>{{ item.name }}</strong>
</template>
<template #emptyState>
<p class="py-10 text-center text-muted-foreground">
No topics found.
</p>
</template>
</DataTable>Slot inventory
Layout slots:
topbarbeforeSearchandafterSearchbeforeActionsandafterActionsfilterstable,thead, andtbodysummaryFooterfooterloadingemptyStateconfirmationqueuedAction
Attribute slots:
cell(<attribute>)header(<attribute>)summary(<attribute>)filter(<attribute>)image(<attribute>)image-fallback(<attribute>)action(<key>)
Use attribute slots when only one definition needs custom rendering. Replacing the structural table slots makes the application responsible for accessibility and layout behavior inside that region.
Application-owned filter control
Use filter(<attribute>) for a non-Eloquent source, option creation, or a custom picker. First declare the stored value on the server:
NumericFilter::make('source_id', 'Source')->withoutClause();Then render the control:
<DataTable :resource="quotes">
<template
#filter(source_id)="{
value,
update,
setDisplayValue,
close,
}"
>
<AsyncSourceSelect
:model-value="value"
@select="({ value: nextValue, label }) => {
update(nextValue);
setDisplayValue(label);
close();
}"
/>
</template>
</DataTable>The package owns the value and URL state. The application owns loading, search, pagination, option creation, and the external endpoint.
Icon resolver
Icon names are library-agnostic. Register a resolver once:
import { Pencil, Trash2 } from "@lucide/vue";
import { setIconResolver } from "@musing/inertia-table-vue";
setIconResolver((name) => ({ Pencil, Trash2 })[name]);The resolver receives both the icon name and its context. A table may instead provide its own iconResolver prop.
Row identity
Laravel-generated resources include stable Eloquent key metadata. For an application-owned resource, provide the identity explicitly:
<DataTable
:resource="topics"
:row-key="(topic) => topic.uuid"
/>The headless equivalent is useActions(table, { rowKey: (topic) => topic.uuid }).
For a fully application-owned renderer, see the headless API.