slash2nl/nova-back-button
Adds a configurable back button to Laravel Nova pages, letting users return to the previous screen or a custom fallback URL. Lightweight and easy to install, with per-resource configuration for smoother navigation in Nova admin panels and detail views.
Install via Composer, pinning to the version that matches your Nova major. The 2.1.0 release (2024-12-19) is the Nova 5 compatibility signal, so anchor on it:
# Nova 5
composer require slash2nl/nova-back-button:^2.1
# Nova 4 — verify the prior constraint first, don't assume ^2.1 still admits it
composer show slash2nl/nova-back-button --all
composer require slash2nl/nova-back-button:^2.0
No migrations, nothing to publish in the common case — Nova cards ship precompiled JS in dist/, so npm install inside the package is only needed if you fork the Vue component.
Where to look first (in order) — this is a five-minute read, do it before you register anything:
composer.json — the laravel/nova constraint is the authoritative source of truth for Nova 4 vs. Nova 5 support. After a compatibility release, it matters more than the README.README.md — the small usage snippet is the real API. Note the exact constructor and any chainable options (label, target, visibility).src/NovaBackButton.php — confirms the $component name, any withMeta() defaults, and the chainable methods you can actually call.resources/js/ — the Vue component. This tells you how it navigates: Nova's router (this.$router.back()) versus raw window.history.back(). Read it once before you trust it on direct links, modals, and after refresh.Register the card the standard Nova way, either globally via NovaServiceProvider::cards():
use Slash2NL\NovaBackButton\NovaBackButton;
public function cards(): array
{
return [
(new NovaBackButton()),
];
}
…or scoped to a dashboard, or to a resource's cards() method.
First use case: drop it on a resource-heavy dashboard or a resource's cards() so operators who drill into a detail screen from a filtered index can pop back without touching browser chrome. That's the entire product — validate it in staging on Nova 5 first, since that's the newest path.
Scope it to where it earns its keep. This is a client-side affordance — register it where users actually drill in from filters or search. A dashboard-level registration plus per-resource registration where drill-in depth is highest covers the common case. Blanket global registration is harmless but adds visual noise.
Nova's registration points are the composition surface. Cards live on dashboards, on resources via Resource::cards(), and inside custom tools. Pick the registration point that matches where the button should appear — don't assume a single global registration covers resource detail/edit screens without checking.
Keep the label context-aware. Where the package exposes a chainable label/visibility option, use it to reflect the destination ("Back to users", "Back to this list") rather than a bare "Back". It's a cheap UX win and it's exactly what the config-label feature exists for. If the only knob is withMeta(), set it that way rather than editing the Vue component.
Test the SPA flow, not just the click. Nova is an SPA (Vue 2 on Nova 4, Vue 3 on Nova 5). The workflow that matters:
Repeat on a nested resource (e.g. a BelongsTo relation page) and after a full browser refresh — history state differs across all three.
Reimplementation is a legitimate pattern here. The card is a single-purpose Vue component; a ~20-line internal Nova card calling $router.back() reproduces it. Decision rule: adopt as-is if the Nova 5 pin works on your stack without forking; reimplement the moment you need different navigation semantics (e.g. return to a specific resource rather than history.back).
Gate staging per Nova/Laravel upgrade. Pin slash2nl/nova-back-button and laravel/nova together in composer.json, and note in your upgrade checklist that 2.1.0 was the last compatibility signal — treat it as reactive on the next Nova major.
The Nova 4 vs. Nova 5 skew is the sharpest edge. The release note says Nova 5 support was added; it does not say Nova 4 support was retained. A minor bump is allowed to drop a major — check composer.json require/conflict entries yourself rather than trusting the note. If you run Nova 4 anywhere, don't assume ^2.1 is a drop-in; verify and pin the prior version on those environments.
Prove the constraint admits Nova 5 before relaxing:
composer why-not slash2nl/nova-back-button 2.1.0 laravel/nova 5.*
If something else in your tree blocks it, you see it here rather than in a broken admin panel.
Nova 4 and Nova 5 run different frontend stacks (Vue 2 vs. Vue 3). If the package ships one dist/ bundle, test asset loading on both majors; if it ships split bundles, confirm the correct one publishes and loads. A card that renders on 4 but silently fails to mount on 5 is the most likely failure mode after a compatibility release.
SPA navigation ≠ browser "back". Nova intercepts history. If the card calls window.history.back() rather than Nova's router, it can behave differently on direct links, modal flows, and after refresh — sometimes bouncing out of Nova entirely. Read resources/js/ once so you know which mechanism ships, and test leaving Nova then pressing the card if it's raw history.
No state preservation across redirects. The card restores browser history, not filter/search state. Users landing on detail screens from external links or shared URLs may find "back" goes nowhere useful. This is a navigation shortcut — not breadcrumbs, not history state, not deep-link awareness. Set expectations in the pilot.
Don't publish assets unless you're forking. Cards ship precompiled; npm install/npm run build inside the package directory is only for modifying the Vue component. If you do fork, commit the rebuilt bundle and record the build step, or upgrades will silently overwrite (or fail to pick up) your changes.
Pin and own it. 18 stars, 0 dependents, single maintainer. Fine for a UI convenience, disqualifying for infrastructure. Pin 2.1.0, name an internal owner in the upgrade checklist, and keep the removal path documented (delete the cards() entry, composer remove). If ownership friction exceeds a couple of hours of internal implementation, reimplement instead — the code surface is tiny.
Take the review minutes. No permissions, network calls, or database changes are expected from a card like this, but confirm that in code review before deploying to an admin panel that touches anything sensitive. The upside of a ~100-line package is that the review is minutes, not days.
Watch composer update on Nova upgrades. The constraint is what enforces compatibility, so a composer update resolving a newer Nova major can either upgrade the card silently or fail mid-update. Run it in a branch, load every Nova screen that hosts the card, then merge.
How can I help you explore Laravel packages today?