👋 Hi, in this post, I’ll show you how to dynamically register widgets in Filament based on user properties. This approach allows you to display personalized widgets, such as task overviews 📋, for each user. We’ll walk through a simplified example using a Task model with a name property and a many-to-one relationship with the User model.
🚀 So let’s start!
1) Create custom livewire widget, this is important that they are not auto discover from Filament/Widgets folder by default
2) Our widget has a $task property and display its name
<?php
namespace App\Livewire;
use App\Models\Task;
use Filament\Widgets\Widget;
class TaskOverview extends Widget
{
protected static string $view = 'livewire.task-overview';
public Task $task;
public function mount(Task $task): void
{
$this->task = $task;
}
}
<x-filament-widgets::widget>
<x-filament::section>
Task name: {{ $task->name }}
</x-filament::section>
</x-filament-widgets::widget>
3) Create middleware for register widget
php artisan make:middleware AddWidgetForUserMiddleware
public function handle(Request $request, Closure $next): Response
{
if (is_null($request->user())) {
return $next($request);
}
if (! filament()->getCurrentPanel()) {
return $next($request);
}
$widgets = [];
foreach (auth()->user()->tasks as $task) {
$widgets[] = TaskOverview::make(['task' => $task]);
}
filament()->getCurrentPanel()->widgets($widgets);
return $next($request);
}
4) Last step its register our middleware in AdminPanelProvider
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
AddWidgetForUserMiddleware::class,
])
That's what the user sees if he has tasks.
💡 This approach allows for highly personalized dashboards in Filament, making user experiences more dynamic. I hope you found this tutorial helpful! 🙌 If you have any questions or ideas for improvements, feel free to share them in the comments below 💬