Refreshing Relation Manager tab badges after updating records in Filament

Filament makes it easy to organize Relation Managers into tabs, complete with badges showing the record count. But there's a catch: if you update records inside a Relation Manager, those badges won't refresh automatically.
This article shows you how to fix that using Livewire events.
The Problem
By default, you can set a badge count on a tab using the getBadge() method in your Relation Manager:
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
return $ownerRecord
->categories()
->count() ?: 0;
}
This works well for initial loads, but if you create, update, or delete records, the badge won't update until you manually refresh the page.
The trick
Filament's Livewire component includes a handy method called refresh-page.
We can dispatch this event whenever an action modifies the records, forcing the Relation Manager and its badges to refresh.
Here's how it looks:
#[On('refresh-page')]
public function refresh(): void {}
Putting it into Actions
You can use the after() method on any action such as creating, updating, or deleting a record to trigger the refresh:
<?php
namespace App\Filament\Resources\Posts\RelationManagers;
use App\Filament\Resources\Categories\Schemas\CategoryForm;
use App\Filament\Resources\Categories\Tables\CategoriesTable;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
class CategoriesRelationManager extends RelationManager
{
protected static string $relationship = 'categories';
public function form(Schema $schema): Schema
{
return CategoryForm::configure($schema);
}
public function table(Table $table): Table
{
return CategoriesTable::configure($table)
->headerActions([
CreateAction::make()
->after(fn () => $this->dispatch('refresh-page')),
])
->recordActions([
EditAction::make(),
DeleteAction::make()
->after(fn () => $this->dispatch('refresh-page')),
]);
}
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
return $ownerRecord
->categories()
->count() ?: 0;
}
}
Now, whenever you run the action, the badges update instantly:
Conclusion
Livewire events are a powerful way to keep your UI in sync.
In this case, dispatching refresh-page ensures Relation Manager tab badges always reflect the latest record counts.
Download source code
Run project on Firebase Studio
- Open studio.firebase.google.com and import the repository
https://github.com/wiremodel/simple-blog - Run the project. Once it's up, switch to the correct branch:
git checkout v4/refresh-badges
Update dependencies and migrate the database:
composer update -W
php artisan migrate:fresh --seed
.env file has APP_URL set to the URL provided by Firebase Studio.