pdmfc/nova-action-button
Add configurable action buttons to Laravel Nova resources. Define buttons with labels, icons, colors, and links or actions, then place them on resource detail and index views to trigger custom operations, external URLs, or modal actions with minimal code.
Architecture fit. This package is a thin presentation layer: a Nova field that renders a button which dispatches an Action class you already own. It introduces no service provider surface, no config, no migrations, no persistence, and no new endpoint. That means fit is a binary function of the host application, not of the package: if our back-office work already flows through Nova Actions as the canonical execution path, the architectural seam is clean and the package adds an entry point and nothing else. If business logic currently lives in controllers or ad-hoc services outside Nova's action system, the package delivers zero until we first extract those operations into Action classes — and at that point the button is the easy part of the workstream.
Integration feasibility. Installation is a Composer line plus field registration, with php artisan nova:publish only if the app has never built assets. There is no configuration, no migration, and no publish step in the typical case. Realistic engineering cost is half a day to integrate and one day to harden. The gating fact is version: the last release is 2021-10-09, which predates Nova 4's frontend rework and Nova 5 entirely. The PHP field class will probably still load; the compiled JS bundle is where breakage will surface. Nova 4/5 compatibility must be treated as unverified until spiked, not assumed — read the laravel/nova constraint in the package's composer.json before any estimate is committed.
Technical risk. Ranked by how badly it bites:
authorizedToSee()/policy, never only in the field's canSee closure.fields() — CSV exports, indexQuery sort handlers — may surface an empty column or a nonsense sort target. Audit rather than assume.composer.json we own it; the risk is not the current code but the unbounded cost at the next Nova upgrade.fields() refactor can silently drop the button; nobody notices until an operator complains.Key questions.
ShouldQueue?Stack fit. Laravel + Nova 3.x only. For anything not on Nova, this package is irrelevant. For Nova 4/5, it is a spike-gated decision, not an adoption.
Migration path. There is none in either direction, which is the package's most underrated property for a pilot: it is additive and fully reversible. Nothing to migrate in; on abandonment, composer remove plus deleting one line from fields() restores the prior state with no data cleanup. That reversibility is what justifies a time-boxed trial rather than a build.
Compatibility. Three checks before writing custom code: (1) the laravel/nova constraint in the package's composer.json; (2) the source itself — src/ is the documentation, so read the constructor, resolve(), and meta() for the exact fluent method names rather than trusting blog posts that may describe a fork; (3) the compiled asset rendering in our Nova build. Critically, after installing, re-verify that the dropdown version of the same Action still works — that isolates whether a failure is the package or our Action. Vendor via a fork (private VCS or a Composer path repo), pin an exact commit, and document in the repo README why the fork exists.
Sequencing.
->onlyOnDetail(). Exit criterion defined in advance: button renders, click dispatches, detail view refreshes, unauthorized user sees nothing.indexQuery for any relation the visibility closure reads.ShouldQueue before the button is exposed at index scale.Confirmation prompts (->confirmText(), ->confirmButtonText()) belong on the Action class, not in the field, so the button and the dropdown keep identical semantics.
Maintenance. We become the maintainer on day one. Budget a named owner, a pinned commit, a CI smoke test that asserts field presence, and a README note explaining the fork. Per-unit ownership cost is low; cost at the next Nova major is not, and should be recorded as a known liability rather than discovered during an upgrade.
Support. None exists. MIT, one release four years ago, 36 stars, zero dependents — there is no community answer surface for the failure modes above. Escalation is internal by default, which is acceptable for an internal tool with a small trusted operator group and unacceptable for anything customer-facing, financial, or destructive. The honest escape hatch is roughly two days of in-house Nova field work, or native Nova 4+ row/inline actions — both preferable to debugging a 2021 dependency in production. Set the exit criterion before the spike, not after.
Scaling. Runtime scaling is a non-issue: the shim is stateless and dispatches into whatever Action we already run. What scales badly is the surface, not the package — per-row visibility closures on a 50-row index, and synchronous long-running work behind a button, which converts a slow job into a timeout and a support ticket. Scale the Actions (queue, idempotency, audit trail), never the button. Also cap button count: three is a workflow, eight is a dropdown with extra steps.
Failure modes. In order of operational pain: silent no-op (button looks live, dispatches nothing, no refresh); stale compiled asset after a Nova update (Vue error or 404 in console); authorization leak (button visible to a user who cannot execute); lost registration after a fields() refactor; duplicate submission on double-click for non-idempotent actions; export or sort pollution from the field leaking into fields() iterators. Debugging order should be fixed: field registered on the right resource and surface → Action namespaced and authorizedToSee true → console clean → network request returns 2xx → dropdown version of the same action still works.
Ramp-up. Engineering: half a day to integrate, one day to harden, plus the one-day spike — roughly two to three days end to end including validation. Operators: near zero, since a labelled button is self-explanatory, but change management matters — anyone accustomed to the dropdown must find both entry points behaving identically, which is exactly why confirmation and permission logic stays on the Action. For stakeholders, the framing is a time-boxed pilot on Nova 3 with a named owner and a defined exit criterion; and it should be logged as a platform posture decision, because adopting a Nova-only, unmaintained package is a quiet vote to stay on Nova and deepens the lock-in accordingly.
How can I help you explore Laravel packages today?