Product Decisions This Supports
- Treating the admin sidebar as a product surface. The cheapest visible UX win for internal users is a launchpad — links to billing, status pages, support ticketing, observability, docs. This package exists only to make that configuration-driven instead of hardcoded, so the decision it informs is "should admin navigation carry non-resource links at all?"
- Build vs. buy vs. fork for permission-aware navigation. Release 0.1.1 adds per-link authorization, which was the main reason to hand-roll a menu block. The PM question narrows to: does a 12-star, pre-1.0, 2019-era package cover enough of the requirement to beat ~an hour of native
NovaServiceProvider::mainMenu() work we would own anyway?
- Roadmap input for internal tooling consolidation. If the roadmap puts multiple internal systems behind one admin entry point, per-link visibility is a prerequisite, not a nicety. If it doesn't, adopting this buys cosmetic convenience at the cost of an unmaintained dependency.
- Dependency governance as a repeatable test case. Twelve stars, zero dependents, no release since September 2019, no visible test suite. However this is decided, it sets precedent for how the team treats dormant packages generally.
- Risk acceptance with a security flavor. The package makes an authorization decision inside an authenticated admin panel. A menu that never checked permissions was obviously unsafe; one that checks them incorrectly is unsafe while looking safe. That raises the adoption bar rather than lowering it.
- Feature scoping / fork trigger. Static links plus per-link
can callbacks are the entire feature set. Dynamic or per-tenant link sets, localization, submenus, or click analytics are out of scope by definition and convert this into a fork candidate.
- Documentation-trust calibration. The README describes Eloquent-tied slugs, link resolution, and configurable redirects; the release history and source tell a much narrower story — a thin Nova sidebar extension. A PM should treat the marketing copy as unverified until engineering reads
src/. Any decision made from the README alone is made on the wrong product.
When to Consider This Package
Consider it only when all of the following hold:
- You run Laravel Nova, and the compiled asset's Vue major matches your Nova version. Realistically this means Nova 1.x/2.x era; the 2019 Webpack/Vue 2 build is very unlikely to mount under Nova 4/5, which moved to Vite and Vue 3.
- The requirement is genuinely small: a handful of static or semi-static sidebar links, no counters, no submenus, no conditional generation.
- Engineering has confirmed in source that the 0.1.1 authorization check is server-side and resolves against real gates/policies — not a client-side hide in Vue, where the URL is already in the page payload and readable in devtools.
- You have verified the fail-closed default: a link with no callback behaves as policy intends, rather than being silently visible to everyone.
- You will pin the exact version (
"wehaa/custom-links": "0.1.1") and commit the lock file — pre-1.0 semver means 0.1.2 can change the authorization API without notice.
- You will avoid closures in the config file if you use
config:cache, using invokable class strings or service-provider registration instead.
- Someone will run the two-link smoke test — one visible link, one auth-gated link — and confirm the hidden link's URL is absent from the page source and Nova bootstrap JSON, not merely hidden with CSS.
- You accept the maintenance risk and are prepared to fork before extending rather than file issues upstream.
Look elsewhere — specifically at native NovaServiceProvider::mainMenu() with MenuItem::make(...)->canSee(...) — when any of the above fails, when you need anything beyond static links, or when the native path can reproduce your two links in under an hour. It usually can.
How to Pitch It (Stakeholders)
To executives: This is a small, low-risk navigation improvement for internal admin users — surfacing the tools people already use from the sidebar they already open. It is not a platform investment, and it should not be funded or planned like one. The honest framing is "an afternoon of configuration plus a documented exit path," with a clear trigger to switch to the platform-native menu if we ever need anything more than static, permission-gated links.
To engineering: Adopt it as a thin, pinned, single-purpose dependency for static, authorization-gated sidebar links — or skip it and implement the same thing natively in mainMenu(). Two things are non-negotiable either way: verify the 0.1.1 authorization runs server-side and that guarded URLs are absent from the JSON payload, and confirm the compiled Vue asset actually mounts on our Nova version before we build anything on top of it. If a use case appears that this package can't express, we fork into packages/ and own it rather than waiting on a 2019 release cadence.
The line that should survive the meeting: a dormant, pre-1.0 package that makes a security-shaped decision needs its failure mode proven before adoption, not assumed. If the native menu does the job in under an hour, that is the answer.