Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra DataGrid Server-driven data grid for Laravel
Elyra
Inertia integration (Svelte / Vue)

Inertia integration (Svelte / Vue)

The Svelte and Vue clients are client-driven: a headless engine calls a fetch function that POSTs the protocol request to a Laravel endpoint. This guide covers the endpoints, CSRF, and server-seeded first paint.

Endpoints

Define the grid once and reuse it across the page, grid, mutate and export routes:

use Elyra\DataGrid\Protocol\GridRequest;
use Elyra\DataGrid\Protocol\GridMutation;
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('status', editable: true, editor: 'select', rules: 'required|in:pending,paid,shipped')
        ->column('qty', type: 'number', editable: true, rules: 'required|integer|min:0')
        ->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', 'qty', 'revenue'],
        'view' => ['skip' => 0, 'take' => 20],
        'meta' => ['total'],
    ])),
]));

Route::post('/api/sales/grid',   fn (Request $r) => salesGrid()->respond(GridRequest::fromArray($r->all())));
Route::post('/api/sales/mutate', fn (Request $r) => salesGrid()->mutate(GridMutation::fromArray($r->all())));
Route::post('/api/sales/export', fn (Request $r) => salesGrid()->export(
    GridRequest::fromArray(json_decode($r->input('request'), true) ?: []), 'csv', 'sales'));

CSRF

The laravelFetch helper posts JSON. The simplest approach for API-style grid endpoints is to exempt them from CSRF in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware): void {
    $middleware->validateCsrfTokens(except: ['api/*']);
})

Alternatively keep CSRF and add a <meta name="csrf-token"> tag — laravelFetch sends it as X-CSRF-TOKEN.

Server-seeded first paint (initialData)

A client-fetched grid is empty on first paint until its XHR resolves. Pass the first page as an Inertia prop and hand it to the grid as initialData — the grid renders immediately and only fetches on interaction:

<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: [ /* ... */ ],
  fetch: laravelFetch('/api/sales/grid'),
  initialData: props.initial,   // ← instant first paint
};
</script>

This also improves perceived performance and works well with Inertia SSR.

The laravelFetch helper

import { laravelFetch } from '@elyra/datagrid-vue'; // or -svelte
const fetch = laravelFetch('/api/sales/grid');

It POSTs the GridRequest as JSON with Accept: application/json, X-CSRF-TOKEN (from the meta tag, if present) and X-Requested-With. You can provide any (request) => Promise<GridResponse> if you need custom behavior.

Custom mutate

editing.mutate is any (GridMutation) => Promise<GridMutationResult>:

editing: {
  mode: 'slideover',
  mutate: async (m) => (await fetch('/api/sales/mutate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
    body: JSON.stringify(m),
  })).json(),
},