Skip to content

Deferred tab badges re-render on every table interaction (sort, search, filter, paginate) #19583

@leek

Description

@leek

Package

filament/filament

Package Version

v5.4.2

Laravel Version

v12.56.0

Livewire Version

v4.2.2

PHP Version

PHP 8.4.19

Problem description

Tab badges configured with ->deferBadge() re-trigger their loading state (spinner) on every table interaction — sorting, searching, filtering, and pagination. This creates a visible loading loop where badges flash back to spinners after each action, even though the underlying counts haven't changed.

Screen Recording

CleanShot.2026-03-27.at.10.15.49.mp4

Example configuration on a ListRecords page:

public function getTabs(): array
{
    return [
        'all' => Tab::make('All')
            ->badge(fn () => Post::query()->count())
            ->deferBadge(),
        'published' => Tab::make('Published')
            ->badge(fn () => Post::query()->whereNotNull('published_at')->count())
            ->deferBadge()
            ->modifyQueryUsing(fn (Builder $query) => $query->whereNotNull('published_at')),
        'draft' => Tab::make('Draft')
            ->badge(fn () => Post::query()->whereNull('published_at')->count())
            ->deferBadge()
            ->modifyQueryUsing(fn (Builder $query) => $query->whereNull('published_at')),
    ];
}

On initial page load, badges load correctly via deferred request. But any subsequent table interaction (clicking a sortable column, typing in search, applying a filter, or paginating) causes all deferred badges to re-enter their loading state — showing spinners and re-fetching counts.

Previously reported in #19574 (closed for not following the issue template). Also related to #19336.

Expected behavior

Deferred badges should only fetch once on initial page load (or when switching tabs) and remain stable during table interactions like sorting, searching, filtering, and pagination. The badge counts don't change due to these interactions — they are global counts, not filtered by the table state.

Steps to reproduce

  1. Clone the reproduction repository and follow the README setup instructions
  2. Login at http://localhost:8000/admin/login with test@example.com / password
  3. Navigate to Posts — observe tab badges (All, Published, Draft) load correctly
  4. Click any sortable column header (e.g. "Title")
  5. Observe: All tab badges show loading spinners again and re-fetch
  6. Type in the search box — badges flash to spinners again
  7. Paginate — badges flash to spinners again

Reproduction repository (issue will be closed if this is not valid)

https://github.com/leek/filament-deferred-badge-bug

Relevant log output

No error output — this is a UX issue where deferred badges visually re-enter loading state on every Livewire request triggered by table interactions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions