Quick start
This guide builds a minimal, sortable, filterable, paged grid over a sales
table for each client. It assumes you completed Installation.
Every grid needs a server definition (which columns exist, security, driver). The clients then either use it directly (Livewire) or call it through a JSON endpoint (Vue/Svelte).
Livewire
Create a component that extends DataGrid:
<?php
namespace App\Livewire;
use Elyra\DataGrid\Livewire\DataGrid;
use Elyra\DataGrid\Server\Grid;
use Elyra\DataGrid\Server\GridDefinition;
class SalesGrid extends DataGrid
{
public string $heading = 'Sales';
protected function definition(): GridDefinition
{
return Grid::table('sales')
->connection('elyrasql')
->key('id')
->columns(['sku', 'region', 'category', 'status'])
->column('revenue', type: 'number')
->searchable(['sku', 'category']);
}
protected function columns(): array
{
return [
['field' => 'sku', 'header' => 'SKU', 'frozen' => true],
['field' => 'region', 'header' => 'Region'],
['field' => 'category', 'header' => 'Category'],
['field' => 'status', 'header' => 'Status'],
['field' => 'revenue', 'header' => 'Revenue', 'type' => 'number'],
];
}
}
Route it as a full-page component:
Route::get('/sales', App\Livewire\SalesGrid::class);
That is a complete, working grid. See the Livewire guide to enable selection, grouping, editing, export, and more.
Vue (Inertia)
Server — a JSON endpoint plus a page route (routes/web.php):
use Elyra\DataGrid\Protocol\GridRequest;
use Elyra\DataGrid\Server\Grid;
use Illuminate\Http\Request;
function salesGrid()
{
return Grid::table('sales')->connection('elyrasql')->key('id')
->columns(['id', 'sku', 'region', 'category', 'status'])
->column('revenue', type: 'number')
->searchable(['sku', 'category']);
}
Route::get('/sales', fn () => Inertia::render('Sales', [
'initial' => salesGrid()->respond(GridRequest::fromArray([
'columns' => ['id', 'sku', 'region', 'category', 'status', 'revenue'],
'view' => ['skip' => 0, 'take' => 20],
'meta' => ['total'],
])),
]));
Route::post('/api/sales/grid', fn (Request $r) => salesGrid()->respond(GridRequest::fromArray($r->all())));
Exempt the API route from CSRF (bootstrap/app.php):
$middleware->validateCsrfTokens(except: ['api/*']);
Page — resources/js/pages/Sales.vue:
<script setup lang="ts">
import { DataGrid, laravelFetch } from '@elyra/datagrid-vue';
import type { GridResponse } from '@elyra/datagrid-vue';
const props = defineProps<{ initial?: GridResponse }>();
const options = {
key: 'id',
columns: [
{ field: 'sku', header: 'SKU', frozen: true },
{ field: 'region', header: 'Region' },
{ field: 'category', header: 'Category' },
{ field: 'status', header: 'Status' },
{ field: 'revenue', header: 'Revenue', type: 'number' as const, align: 'right' as const },
],
fetch: laravelFetch('/api/sales/grid'),
initialData: props.initial, // instant first paint (SSR)
};
</script>
<template>
<DataGrid :options="options" heading="Sales" />
</template>
The initialData prop is the server-seeded first page — the grid renders
immediately, then fetches on interaction. See Inertia integration.
Svelte (Inertia)
Server setup is identical to Vue. The page (resources/js/pages/Sales.svelte):
<script lang="ts">
import { DataGrid, laravelFetch } from '@elyra/datagrid-svelte';
import type { GridResponse } from '@elyra/datagrid-svelte';
let { initial }: { initial?: GridResponse } = $props();
const options = {
key: 'id',
columns: [
{ field: 'sku', header: 'SKU', frozen: true },
{ field: 'region', header: 'Region' },
{ field: 'revenue', header: 'Revenue', type: 'number', align: 'right' },
],
fetch: laravelFetch('/api/sales/grid'),
initialData: initial,
};
</script>
<DataGrid {options} heading="Sales" />
Next: Defining grids.