Dynamic Tabs with Table Widgets in Filament v4 using Sushi Model — Data Loads Only After Second Clic
Description:
I’m migrating a working FilamentPHP v3 setup to v4, and I’m running into a problem when dynamically rendering tabs with table widgets using data loaded from external WooCommerce APIs (via the Sushi model).
Here’s the scenario:
- I have multiple WooCommerce stores, each exposing an API with the same structure.
- My Laravel backend connects to these stores to retrieve live customer orders.
- The goal is to build a Filament v4 List page that displays:
- - Tabs, one per store (dynamically generated from the stores table).
- - A table inside each tab showing all customer orders (fetched via API).
- - The tab label should also show a count badge of active orders.
In Filament v3, this worked well using a TableWidget with actions and filters, and I dynamically created columnSpanFull widgets inside getHeaderWidgets().
However, after upgrading to Filament v4:
- Actions are deprecated for table widgets.
- I’m now using the new tab layout approach (getTabs() in ListRecords).
- The table uses a Sushi model to load API data for the selected tab.
Problem Behavior:
- When I click a tab for the first time → nothing loads.
- When I click another tab → the previous tab’s data loads instead.
- It sometimes requires two clicks to show the correct data.
- The API call seems to be made N+2 times, where N = number of records returned.
So it looks like the tab selection and table reactivity are slightly out of sync in Filament v4 — perhaps because of the Livewire lifecycle or how Sushi data is initialized per tab.
Question:
How can I correctly bind a Filament v4 tab layout to a dynamic Sushi model table so that:
- The correct tab data loads on the first click,
- The API is called only once per tab change, and
- The table re-renders smoothly without double queries or delays?
Any examples or best practices for handling tab-based dynamic data sources in Filament v4 would be greatly appreciated.
Code Structure (relevant files attached):




0 Replies