qbits / laravel-inertia-vue-datatable
A powerful DataTable package for Laravel + Inertia.js + Vue 3 with server-side pagination, sorting, filtering, row selection, bulk actions, and export.
Package info
github.com/RafiqueKhattak/laravel-inertia-vue-datatable
Language:Vue
pkg:composer/qbits/laravel-inertia-vue-datatable
v1.0.1
2026-03-13 12:03 UTC
Requires
- php: ^8.1
- illuminate/http: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- maatwebsite/excel: ^3.1.55
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
README
A full-featured DataTable package for Laravel + Inertia.js + Vue 3.
Features
| Feature | ✓ |
|---|---|
| Server-side pagination | ✅ |
| Column sorting (asc/desc) | ✅ |
| Search / filtering | ✅ |
| Row selection + select all | ✅ |
| Bulk actions | ✅ |
| Column visibility toggle | ✅ |
| Export CSV / XLSX | ✅ |
| Custom action buttons (slot) | ✅ |
| Custom cell renderers (slot) | ✅ |
| Debounced search | ✅ |
Installation
composer require qbits/laravel-inertia-vue-datatable
Publish config + Vue component:
php artisan vendor:publish --tag=datatable-config php artisan vendor:publish --tag=datatable-components
The Vue component will land at:
resources/js/vendor/datatable/Components/DataTable.vue
Backend: Controller
Add the HasDataTable trait to any controller and call $this->dataTable():
use YourVendor\InertiaDataTable\Traits\HasDataTable; class UserController extends Controller { use HasDataTable; private function columns(): array { return [ ['key' => 'id', 'label' => 'ID', 'sortable' => true, 'searchable' => false, 'exportable' => true], ['key' => 'name', 'label' => 'Name', 'sortable' => true, 'searchable' => true, 'exportable' => true], ['key' => 'email', 'label' => 'Email', 'sortable' => true, 'searchable' => true, 'exportable' => true], ]; } public function index() { $query = User::query(); $tableData = $this->dataTable($query, $this->columns()); return Inertia::render('Users/Index', [ 'table' => $tableData, ]); } public function export(Request $request) { $ids = array_filter(explode(',', $request->input('ids', ''))); $format = $request->input('format', 'xlsx'); $query = User::query(); return Excel::download( new DataTableExport($query, $this->columns(), $ids), 'users.' . $format ); } public function bulkDestroy(Request $request) { User::whereIn('id', $request->ids)->delete(); return back(); } }
Routes
Route::get('/users', [UserController::class, 'index']); Route::get('/users/export', [UserController::class, 'export']); Route::delete('/users/bulk-destroy', [UserController::class, 'bulkDestroy']);
Column Definition
| Key | Type | Default | Description |
|---|---|---|---|
key |
string | required | Model attribute / DB column |
label |
string | required | Column header text |
sortable |
bool | false |
Allow sorting by this column |
searchable |
bool | false |
Include in LIKE search |
exportable |
bool | false |
Include in CSV/XLSX export |
visible |
bool | true |
Initial visibility |
Frontend: Vue Component
<DataTable :columns="table.columns" :rows="table.data" :meta="table.meta" :filters="table.filters" :bulk-actions="[{ key: 'delete', label: 'Delete Selected' }]" :exportable="true" export-url="/users/export" row-key="id" @bulk-action="handleBulkAction" @selection-change="onSelectionChange" />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
columns |
Array | required | Column definitions (from server) |
rows |
Array | [] |
Current page rows |
meta |
Object | required | Pagination meta |
filters |
Object | {} |
Active filter state |
rowKey |
String | 'id' |
Unique row identifier |
selectable |
Boolean | true |
Show row checkboxes |
showColumnToggle |
Boolean | true |
Show columns menu |
exportable |
Boolean | true |
Show export buttons |
exportUrl |
String | '' |
URL to hit for export |
bulkActions |
Array | [] |
[{ key, label }] |
searchDebounce |
Number | 350 |
Debounce ms for search input |
Events
| Event | Payload | Description |
|---|---|---|
bulkAction |
{ action: string, ids: number[] } |
Fired on bulk action click |
selectionChange |
number[] |
Selected row IDs |
Slots
| Slot | Props | Description |
|---|---|---|
cell-{key} |
{ row, value } |
Custom cell renderer per column |
rowActions |
{ row } |
Action buttons at end of each row |
actions |
— | Extra buttons in the toolbar |
Configuration
config/datatable.php
return [ 'per_page' => 15, 'per_page_options' => [10, 15, 25, 50, 100], 'export_filename' => 'export', ];
Requirements
- PHP 8.1+
- Laravel 10 or 11
- Inertia.js + Vue 3
maatwebsite/excel^3.1
License
MIT