Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Resource Card Laravel Package

norman-huth/nova-resource-card

Laravel Nova Resource Card lets you display Nova resources as compact, customizable dashboard cards. Surface key records and resource data at a glance, making it easy to add quick-access resource overviews to your Nova dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require norman-huth/nova-resource-card

Nova itself lives behind nova.laravel.com, so your Composer auth for nova.laravel.com must already be configured — this package pulls against your existing Nova install, not a public satellite.

Because the package is archived (last release 2024-03-08), do not use ^ constraints blindly. Pin it:

"norman-huth/nova-resource-card": "1.0.0"

Where to look first

  1. vendor/norman-huth/nova-resource-card/src/ — the Card class. Confirm the exact namespace (it follows the author's Muetze42/NormanHuth convention) and the fluent setters exposed on the card before writing dashboard code.
  2. vendor/norman-huth/nova-resource-card/dist/ — check for a prebuilt js/card.js. If it exists, you never need Node; if not, you're in for a build.
  3. The package's own service provider and any config/ file — determine whether options are config-driven or fluent-method driven. This decides your whole integration style.

First use case

The canonical win is a dashboard that replaces a bare "Resources" sidebar with tappable cards showing each resource's name, icon, and record count — useful when non-technical admins live in Nova. Register it in your NovaServiceProvider:

// app/Providers/NovaServiceProvider.php
use NormanHuth\NovaResourceCard\ResourceCard; // verify namespace in src/

public function cards()
{
    return [
        ResourceCard::make()->resource(\App\Nova\User::class),
        ResourceCard::make()->resource(\App\Nova\Order::class),
    ];
}

Or, for a single multi-resource card, pass an array of resource classes. Confirm the accepted signature in the card's constructor/fluent methods — this package predates any Nova 5 card conventions and its API is not guaranteed to match Laravel Nova's own Metric/Value ergonomics.

Implementation Patterns

One card per resource, ordered deliberately. Register cards in the order you want them to appear; Nova renders in registration order, and card width controls grid flow. This is the most predictable pattern and keeps each card independently authorizable.

Multi-resource summary card. If the card accepts an array of resource classes, use it on a "home" dashboard for an at-a-glance admin view, and keep per-resource cards out. Mixing both produces duplicate counts and confuses users about which is authoritative.

Per-dashboard placement. Rather than globally in NovaServiceProvider::cards(), scope cards to dashboards where they earn their space:

// app/Nova/Dashboards/Main.php
public function cards()
{
    return [
        ResourceCard::make()->resource(\App\Nova\Order::class)->width('1/3'),
        ResourceCard::make()->resource(\App\Nova\Customer::class)->width('1/3'),
    ];
}

Nova's width('1/3' | '1/2' | 'full') is applied by the card wrapper, so it should work regardless of the package's internals — verify visually.

Authorization is your job, not the card's. Wrap each card in canSee() so a user who cannot viewAny a resource never sees its count:

ResourceCard::make()
    ->resource(\App\Nova\Order::class)
    ->canSee(fn ($request) => \App\Nova\Order::authorizable()
        && \App\Nova\Order::availableForNavigation($request)
        && \Gate::forUser($request->user())->allows('viewAny', \App\Models\Order::class)),

Cache the counts. Aggregate counts on large tables are expensive, and Nova cards re-request on every dashboard load. Nova cards inherit cacheFor(); if this package doesn't override it, call it in your registration:

ResourceCard::make()
    ->resource(\App\Nova\Order::class)
    ->cacheFor(now()->addMinutes(10)),

If cacheFor() is a no-op here (possible, given the card is custom-built), cache at the query level with Cache::remember() inside whatever callback the card exposes.

Compose with metrics rather than duplicating them. Use a resource card for "where do I go" navigation and a Value/Partition metric for "how am I doing" trend data. Do not use a resource card to display a growth percentage it wasn't built to compute.

Fork-and-vendor for anything non-trivial. With 6 stars and 0 dependents, upstream fixes are not coming. If you need a behavior change, publish the card's views/assets (if the provider supports publishes()) or point Composer at your fork:

"repositories": [
  { "type": "vcs", "url": "[email protected]:yourorg/nova-resource-card.git" }
]

Remember the fork must keep the same package name in its composer.json for a drop-in swap.

Gotchas and Tips

Archived status is the headline risk. There will be no fix for a Nova 5 breaking change or a Vue 3 / Vite incompatibility. Before adopting, smoke-test the card in a staging Nova install; if the dashboard card silently renders blank, you are almost certainly hitting a Nova version mismatch, not a bug in your registration code.

Blank card = asset or prop problem. Debug in this order: (1) browser console for a missing card.js 404, (2) php artisan nova:publish if the package publishes assets, (3) vue devtools — inspect the card prop Nova hands the component and confirm the resource class and count are present. If the prop is there but the UI is empty, it's a Vue/build issue, not a PHP one.

Counts can leak data. A card that renders Order::count() regardless of policy exposes record volume to users who can't see the resource. Always gate with canSee(). This is the single most likely security mistake with any resource-count card.

Check whether the count respects your global scopes and Nova lenses. Resource::indexQuery() vs. Model::count() vs. Resource::applyFilters() produce very different numbers for soft-deleted, tenanted, or team-scoped models. Verify the number against what the resource index actually shows for the same user; if it diverges, don't ship it.

Soft deletes and withTrashed. A count taken from the Eloquent model silently excludes trashed records. If admins expect "all orders," that mismatch will be reported as a bug within a week.

Nova indexQuery overrides are not applied automatically. If your Order resource overrides indexQuery() for multi-tenancy, a card counting through the model will leak cross-tenant totals. Prefer counts derived from the resource's own query path if the package exposes one.

Dark mode and CSS. Hand-built Nova cards frequently hardcode colors. If the card looks wrong in dark mode, add a small CSS override in Nova::style() or your app's nova.css rather than editing vendor files.

Config is likely global, not per-card. If the package ships a config file, options may apply to every card instance. In that case, prefer multiple dashboards over multiple configurations.

Extension points to look for: publishes() for views/assets, a config/nova-resource-card.php, fluent ->icon() / ->label() / ->uriKey() setters, and the Vue component's props. The Vue layer is where almost all customization actually lives — treat the PHP class as a thin prop builder.

Publish before you patch. Run php artisan vendor:publish --provider="NormanHuth\NovaResourceCard\ResourceCardServiceProvider" (adjust the namespace) to see exactly what's overridable. If nothing publishes, your only stable extension path is a fork.

Upgrade discipline. Because there are no future releases, document the commit hash or version you pinned in your README, and add the card to your dependency-audit list. When you eventually upgrade Nova, this package is the first suspect for a broken dashboard.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager