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 Storage Info Card Laravel Package

qubeek/nova-storage-info-card

A Laravel Nova card that shows storage information for your application, including disk usage and available space, so you can monitor storage health at a glance from the Nova dashboard. Easy to install and configure for local or remote disks. Keep an eye on capacity before it becomes a problem.

View on GitHub
Deep Wiki
Context7

Getting Started

The card is a Laravel Nova dashboard widget that reports usage statistics for S3-style disks configured in config/filesystems.php. It is not a storage driver — it is a read-only observability card, so the first decision is whether Nova is already installed and whether you have at least one s3 disk wired up.

  1. Install the package alongside Nova (Nova ≥ 4 is the safe assumption; verify the composer.json constraint before committing):

    composer require qubeek/nova-storage-info-card
    
  2. Confirm a disk exists. In config/filesystems.php you should already have something like:

    'disks' => [
        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
        ],
    ],
    

    The card reads this disk through Laravel's Storage facade / Flysystem S3 adapter, so if the disk works for Storage::disk('s3')->put(...), the card has what it needs.

  3. Publish the config (the exact tag varies — check the README, but it will be a standard vendor:publish):

    php artisan vendor:publish --provider="Qubeek\NovaStorageInfoCard\CardServiceProvider"
    

    This should drop a file such as config/nova-storage-info-card.php where you list the disk names to monitor.

  4. Register the card in app/Providers/NovaServiceProvider.php:

    public function cards()
    {
        return [
            // ...
            new \Qubeek\NovaStorageInfoCard\StorageInfoCard(),
            // or, if the constructor takes a disk name:
            // (new \Qubeek\NovaStorageInfoCard\StorageInfoCard('s3'))->width('1/2'),
        ];
    }
    

    Verify the constructor signature in the package source before assuming it takes a disk argument — with zero dependents and a zero score, don't rely on examples you find in blog posts.

First use case: add one card bound to your primary media bucket and let it render object count, total size, and (if supported) the last-modified/recency summary on the Nova dashboard. This gives you an at-a-glance sanity check that backups and uploads are landing in the right bucket without opening the AWS console.

If you cannot get the card to render at all within ~15 minutes, stop and evaluate whether a small custom Nova metric card is a better use of time — the core logic here is a couple of listObjectsV2 calls and a view.

Implementation Patterns

One card per disk. The most robust pattern with S3 monitoring is to register a separate card instance per disk rather than one card with a dropdown. It keeps the dashboard scannable and lets you size/layout them independently:

public function cards()
{
    return [
        (new StorageInfoCard('media'))->width('1/2'),
        (new StorageInfoCard('backups'))->width('1/2'),
        (new StorageInfoCard('exports'))->width('1/3'),
    ];
}

Config-driven disks. If the package supports a disks array in the published config, prefer that over hardcoding disk names in NovaServiceProvider. It means a non-developer can add a bucket to the dashboard by editing config, and it keeps NovaServiceProvider from becoming a list of magic strings. Cache-clear after editing (php artisan config:clear) — see gotchas.

Pair with a policy/permission gate. Wrap the card registration so only admins see storage figures:

public function cards()
{
    return Gate::allows('viewStorageMetrics')
        ? [new StorageInfoCard('s3')]
        : [];
}

Storage costs and bucket names are mildly sensitive; there is no reason every Nova user needs them.

Use it as a smoke test in staging. Because the card exercises the same credentials and bucket config as your application, a broken card is often the fastest signal that an IAM policy change or a region misconfiguration has broken uploads in an environment. Put it on the staging dashboard deliberately.

Combine with application-level metrics. The card reports what is in the bucket. Pair it with your own Nova metric (queued jobs, failed uploads, media records in the DB) to detect divergence — e.g. object count flat while DB media records grow indicates orphaned uploads or a failed sync job.

Layout for the dashboard. Cards are Nova components; use ->width(), ->onlyOnDashboard(), and ->canSee() as you would with any card. Grouping storage cards into a dedicated "Storage" dashboard (Nova::mainMenu / custom dashboard class) scales better than piling them onto the main dashboard once you have more than two buckets.

Refresh strategy. For buckets with more than a few thousand objects, do not let the card run a fresh listing on every dashboard load. Either configure the package's cache TTL (if it exposes one) or schedule a small artisan command that warms a cache key the card reads. A dashboard that takes 8 seconds to load because it is paginating a 2M-object bucket will be disabled by your team within a week.

Gotchas and Tips

  • IAM permissions are the #1 failure mode. Listing a bucket requires s3:ListBucket on the bucket ARN, not just s3:GetObject on bucket/*. If you only granted object-level permissions for uploads, the card will error or render zeros while uploads work fine. Also check s3:GetBucketLocation if the package resolves the region.
  • Listing is a billed operation. listObjectsV2 is cheap per call but not free, and Nova dashboards get refreshed more often than you think. Budget for it, and cache aggressively on large buckets.
  • 1000-object pagination. S3 returns at most 1000 keys per page. A naive implementation either under-reports or loops until timeout. Test against a bucket with >1000 objects before trusting the number; a card showing exactly "1000 objects" is almost certainly a pagination bug.
  • Timeout on big buckets. Dashboard requests go through PHP-FPM with a request timeout. Large buckets can exhaust it. If you see 504s after adding the card, that is the card, not Nova.
  • Nova version mismatch. Nova 4 → 5 changed the card/tool registration surface. This package has no dependents, so it has not been battle-tested across versions. If the card does not appear in the dashboard's "Add card" list or throws a Vue component resolution error, check the nova constraint in the package's composer.json against your installed version.
  • config:cache will mask config edits. In production, after changing the disk list run php artisan config:clear && php artisan config:cache. This bites people constantly.
  • S3-compatible endpoints (MinIO, DigitalOcean Spaces, R2). Set endpoint, use_path_style_endpoint => true (MinIO), and a correct region on the disk itself. The card inherits whatever the disk is configured with — do not try to fix endpoint issues from the card's config.
  • Credential source matters. If your app uses an IAM instance role in production and static keys locally, the card will show real numbers in prod and errors locally. That is expected; don't "fix" it by adding static keys to .env on the server.
  • The package is effectively unmaintained. Zero dependents and a zero score mean you are the QA team. Fork it into your own packages/ directory or a private VCS repo and pin the fork; that way a future Nova upgrade does not leave you waiting on a maintainer who may not exist. The code surface is small enough to own.
  • Extension points to check in source: the card's Blade/Vue view (for adding a "manage bucket" link or a percentage-used bar), the config file (cache TTL, disk list), and whether the underlying service is bound as a singleton you can swap for a mock in tests.
  • Debugging tip: if the numbers are wrong, bypass the card and run the same operation manually — Storage::disk('s3')->allFiles() or Storage::disk('s3')->files() — then compare. This tells you instantly whether the problem is IAM/disk config (a Laravel issue) or the card's aggregation logic (a package issue).
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast