joerithegreat/nova-table-card
joerithegreat/nova-table-card adds a configurable table card to Laravel Nova dashboards, letting you display query results or metrics in clean columns with custom formatting. Surface key records and stats at a glance without building a custom card.
This is a Laravel Nova card package: it renders a table (columns + rows you supply) inside a standard Nova card, so you can surface arbitrary tabular data on a dashboard or resource detail page without building a custom Vue component. Release 1.1.0 adds Nova 5 support, so the package now spans Nova 4.x and 5.x.
Minimal steps:
composer require whitespacecode/nova-table-card — confirm the resolved version supports your Nova major (1.1.0+ for Nova 5, 1.0.x if you are still on Nova 4).dist/. Run php artisan nova:publish only if you are overriding the card's frontend.cards() method (e.g. app/Nova/Dashboards/Main.php) or in a Resource's cards() method.columns(), rows()/data(), title()) — that surface, not the Nova wiring, is where the package's own conventions live.Dashboard card with a query-backed table. The natural pattern is to resolve the card's rows from a query inside the card definition (or a small dedicated class/method), keeping the card itself thin:
public function cards(): array
{
return [
(new TableCard)
->title('Latest Orders')
->width('1/2')
->columns([...])
->rows(Order::latest()->take(5)->get()->map(fn ($o) => [...])->all()),
];
}
Resource detail cards. Use the same card inside a Resource's cards() when the table is scoped to the record being viewed ($this->resource is available via NovaRequest). This is the cleanest way to show related rows — e.g. recent invoices for a customer — without defining a whole index-style relationship.
Extract data into a dedicated provider. Rather than inlining a query in cards(), put it in an invokable class (App\Nova\Cards\LatestOrders) that returns the configured card. This keeps dashboards declarative, makes the table reusable across dashboards, and gives you an obvious place to add caching.
Pair with Nova's authorization helpers. Cards render for anyone who can see the dashboard, so gate sensitive tables with ->canSee(fn (Request $request) => $request->user()->isAdmin()) and/or the card's canSeeWhen equivalent.
Cache the heavy bits. Dashboards render on every page load of /nova. Wrap aggregate queries in Cache::remember(..., 60, ...) and, if the package supports it, use the card's refresh/auto-refresh option rather than recomputing per request.
Layout composition. Treat these as half- or third-width cards alongside Nova metrics and trend metrics; they read well as a drill-down companion to a metric above them.
"whitespacecode/nova-table-card": "^1.0" vs "^1.1") rather than floating, and verify composer why laravel/nova after upgrading.get() on a large table will slow every dashboard load. Always take()/limit() and eager-load relationships.Carbon instances, enums, and models placed directly in rows may render oddly or leak attributes — map to plain strings/arrays (and explicitly pick columns) before returning.php artisan nova:publish --force if you had published this card's assets, and clear compiled views/nova-components caches if the card renders blank.canSee closure returning false, an empty collection from a query scoped by a NovaRequest filter, or rows being an array of objects rather than arrays.How can I help you explore Laravel packages today?