- Overview
- Setup
- How it works
- Layout JSON shape
- Drag-reorder
- Column span options
- Reset to default
- Live showcase
Overview
The dashboard customizer gives end-users full control over their dashboard layout. From a floating panel (FAB bottom-left), they can:
- Drag-reorder widgets via SortableJS
- Toggle visibility — hide widgets they don't need
- Pick a column span — 1 col, 2 cols, or full width per widget
- Save — layout persists per-user in a JSON column
- Reset — one click to restore the developer's defaults
When a user hasn't customized, the dashboard renders exactly as the developer configured it (panel-registered order, each widget's own $sort and $columnSpan). When a layout IS saved, the user's choices win.
Setup
1. Publish and run the migration
php artisan vendor:publish --tag=aura-filament-migrations
php artisan migrate
This adds a nullable aura_dashboard_layout JSON column to your users table.
2. Add the trait to your User model
use BlueStarSystem\AuraFilament\Concerns\HasAuraDashboardLayout;
class User extends Authenticatable
{
use HasAuraDashboardLayout;
}
3. Extend AuraDashboard instead of Filament's Dashboard
// app/Filament/Pages/Dashboard.php
namespace App\Filament\Pages;
use BlueStarSystem\AuraFilament\Pages\AuraDashboard;
class Dashboard extends AuraDashboard
{
//
}
Register it in your panel provider:
use App\Filament\Pages\Dashboard;
->pages([
Dashboard::class,
])
4. Enable the customizer on the plugin
AuraFilamentPlugin::make()
->dashboardCustomizer()
Done. A grid-icon FAB appears at the bottom-left of every panel page.
How it works
AuraDashboard overrides two methods from Filament's stock Dashboard:
getWidgets()— reads the user's saved layout from the JSON column and filters/reorders the panel's registered widgets accordingly. New widgets added to the panel after the layout was saved appear at the end as visible.getWidgetsContentComponent()— builds the grid schema with per-user column span overrides applied via->columnSpan().
The DashboardCustomizer Livewire component reads the available widgets from the AuraDashboard page, merges them with the user's saved layout, and renders the editing UI. On save, it writes back to the JSON column and reloads the page.
Layout JSON shape
[
{"class": "App\\Filament\\Widgets\\StatsOverview", "visible": true, "span": "full", "order": 0},
{"class": "App\\Filament\\Widgets\\RevenueTrendChart", "visible": true, "span": 2, "order": 1},
{"class": "App\\Filament\\Widgets\\ActivityFeed", "visible": false, "span": 1, "order": 2}
]
Only class, visible, span, and order are persisted. The label shown in the customizer panel is derived from the class name at render time.
Drag-reorder
SortableJS is loaded from CDN (jsdelivr, ~10 KB gzipped) only when the customizer panel opens. No npm dependency is required on your side.
The drag handle (six-dot grip icon) is on the left of each widget row. The ghost element gets a primary-tinted border while dragging.
Column span options
| Value | Grid behavior |
|---|---|
1 |
Single column (default for most widgets) |
2 |
Two columns (side-by-side with another 2-col or 1-col widget) |
full |
Full width of the dashboard grid |
Span is saved per-widget and applied by the Grid schema wrapper — not by the widget's own $columnSpan. This means the user's choice overrides the developer's default without the widget needing to know about the customizer.
Reset to default
The "Reset to default" button clears the JSON column entirely. On reload, the dashboard falls back to the panel's registered widget order + each widget's own $sort and $columnSpan.
Live showcase
The dashboard on demo.aura-ui.com/admin has the customizer enabled. Click the grid FAB (bottom-left) to try it.