Free·

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 we have a problem when we update records inside a Relation Manager, those badges won't refresh automatically.

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:

app/Filament/Resources/Posts/RelationManagers/CategoriesRelationManager.php
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:

BasePage.php
#[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:

app/Filament/Resources/Posts/RelationManagers/CategoriesRelationManager.php
<?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

Download on GitHub

Join the Discussion

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
Make sure your .env file has APP_URL set to the URL provided by Firebase Studio.