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

Custom Links Laravel Package

wehaa/custom-links

wehaa/custom-links is a Laravel package for managing customizable links in your application, with configurable labels, URLs, and ordering to simplify navigation and resource link setup.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package occupies a deliberately narrow slot: it extends the Laravel Nova sidebar with operator-defined links and, as of the only feature release (v0.1.1, September 2019), per-link authorization. It is not infrastructure — it is an admin-panel presentation layer. That makes architectural risk low in blast radius and equally low in strategic value. Two things must be reconciled before any decision: the marketplace description markets this as a model-slug / URL-resolution package ("attach custom slugs to any model, resolve incoming links to their target models"), while the hands-on evaluation describes a thin Nova sidebar component with a config-driven link registry and a compiled Vue asset. Those are different products with different risk profiles. A TPM should treat the description as unreliable until the source under src/ and the published config confirm which one is actually shipped. If it is genuinely a slug/resolver package, the integration surface expands to routing, middleware, and 301/404 semantics — a materially larger commitment.

Integration feasibility. Feasible only under a tight set of conditions, all verifiable in an afternoon: Composer constraints resolve against your PHP and laravel/nova versions; the compiled asset mounts on your Nova major; the authorization check runs server-side and fails closed. The realistic fit is Nova 1.x/2.x era. Nova 4/5 uses Vite and Vue 3 while this asset is a 2019-era Webpack/Vue 2 build, so the expected outcome on a modern Nova install is a non-mounting component or a silent no-op. Installation is a composer require plus a provider publish — under an hour if constraints cooperate, and a hard stop if they do not.

Technical risk. Ranked by likelihood × impact:

Risk Likelihood Impact Mitigation
Client-side-only authorization; URL present in Nova bootstrap JSON Medium High (security theater in an admin panel) Read compiled Vue + grep page payload before sign-off
Fail-open default for links with no can callback Medium High Explicit test with low-privilege user; document default in config
Nova 4/5 asset incompatibility High Medium (feature simply absent) Verify on a staging Nova instance first
Closures in config break config:cache High if attempted Medium (deploy failure) Invokable class strings or register at boot
Dormant upstream, 0 dependents, pre-1.0 semver, no visible CI Certain Medium Pin 0.1.1, commit lock file, budget for fork
Description/implementation mismatch Medium Medium (scope surprise) Source review as a gate, not a formality

The governing risk is not technical failure — it is false confidence. A package that never checked permissions was obviously unsafe; one that checks them cosmetically is unsafe in a way that reads as safe in a review. That asymmetry is what raises the bar rather than lowering it.

Key questions.

  1. Where does authorization actually execute — PHP or the Vue component?
  2. What is the behavior for a link with no can callback: visible or hidden?
  3. Does the shipped package do sidebar links, model-slug resolution, or both? Which parts of the description are aspirational?
  4. What are the exact php, illuminate/support, and laravel/nova constraints, and which Nova major are we on?
  5. Is there any test suite, CI, or second maintainer, or is this one person's 2019 side project?
  6. What is the equivalent native implementation cost in NovaServiceProvider::mainMenu() with MenuItem::make(...)->canSee(...)?

That last question is the decision. The native path is typically under an hour and carries zero dependency. If native covers the requirement — and for a handful of static or semi-static links it does — the package has to justify itself on something other than effort.

Integration Approach

Stack fit. Laravel + Nova, admin surface only, authenticated internal users. This is a convenience dependency, not a platform one. It should never appear in a customer-facing path, a billing decision, or anything where a wrong visibility call has financial or compliance consequence. If the roadmap includes consolidating internal systems behind one admin entry point, per-link visibility becomes a prerequisite and this becomes roadmap-relevant; if it does not, this is cosmetic tooling and should be governed as such.

Migration path. Greenfield or additive only. There is no meaningful migration from an existing custom sidebar — the code volume is small enough that a fork is cheaper than an adapter. Recommended shape: run the package concurrently with NovaServiceProvider::mainMenu() during a short trial window, keep genuinely static links in the package, and route anything needing conditional logic, counters, submenus, or localization to native MenuSection/MenuItem. That contains exposure to the simplest case and makes removal trivial.

Compatibility. Treat Nova major as the hard gate and gate it first. Confirm against composer.json before reading config docs. Pin exactly — "wehaa/custom-links": "0.1.1", not ^0.1 — because pre-1.0 semver means a patch release can change the authorization API without notice and the release history suggests the config contract is not treated as stable. Commit the lock file. If the constraint set forces a Composer resolution hack on Nova 4/5, stop; the correct answer is native menu, not a constraint override.

Sequencing.

  1. Gate 0 — source review (half day). Read composer.json, src/, the published config, the compiled JS, and git diff v0.1.0 v0.1.1. Answer the six key questions. Kill the initiative here if authorization is client-side.
  2. Gate 1 — native baseline (half day). Implement the same two links natively with canSee. This is the control group; it establishes the real cost of not adopting.
  3. Gate 2 — two-link smoke test (half day). One visible link, one gated on a named gate. Verify the hidden link's label and URL are absent from the rendered sidebar and the Nova bootstrap JSON. Ctrl+F the URL. Not display:none — absent.
  4. Gate 3 — deploy dry run. config:cache in a production-like environment with the real config file. This is where closure-in-config failures surface.
  5. Pilot on one internal role for two weeks, then decide extend / fork / remove.

Budget: roughly 1.5–2 engineer-days to a go/no-go, plus a two-week observation window. Nothing about this warrants a longer runway.

Operational Impact

Maintenance. Effectively unmaintained upstream: last release 2019, twelve stars, zero dependents, no visible CI or test suite. Assume you own the code from day one regardless of what the license says. The MIT license and small surface make a fork cheap — copy into packages/ as a path repository and treat it as first-party. Adopt-with-fork is the honest framing; adopt-as-dependency is a fiction. Budget a nominal half-day per Nova upgrade cycle for compatibility triage, and expect at least one forced fork at the next Nova major.

Support. No upstream support channel worth relying on. Internal ownership means internal documentation: which links exist, who owns each, what gate governs visibility, and what the fail-open/fail-closed default is. Document the default in a comment in the config file itself — that is the artifact a future engineer will actually read. Build the regression net now: one feature test per authorization branch asserting both the label and the target URL are absent for unauthorized users. That test suite is the support contract.

Scaling. Scales fine along the axis it was designed for — a handful of static or semi-static links. Degrades sharply outside it: dynamic link generation, per-tenant link sets, submenus, localization, or click analytics are all out of scope and turn this into a fork-and-own project. If the requirement grows along any of those axes, the correct move is to migrate to native MenuSection/MenuItem rather than extend the package. Treat "we need a loop or a DB query to build the link list" as the explicit trigger to re-evaluate.

Failure modes. Ranked by how they present:

  • Silent absence. Asset does not mount, or a missing callback hides a link. Symptom is a ticket saying "the sidebar link is gone," not an error. Debug order: config:clear → composer show → browser console → inspect page payload → dump() in the callback → provider boot().
  • Cosmetic security. Link hidden via CSS but URL present in JSON. Detected only by payload inspection. Highest severity because it reads as working.
  • Deploy-time hard failure. Closure in a cached config throws on config:cache. Loud, therefore manageable — but it fails at deploy, not in review.
  • Ordering instability. Duplicate order values sort inconsistently between PHP and JS. Cosmetic, but use unique integers with gaps of ten and it never happens.
  • Stale config. Edits masked by cached config. Make config:clear step one of every debugging checklist.

Ramp-up. Low for a Laravel developer: config file plus one trait or callback convention, readable in an afternoon. The ramp-up cost is not the package — it is the institutional knowledge that this is a dormant dependency with a cosmetic-security failure mode. Onboarding should include the two-link smoke test as a standing verification, not a one-time setup step, because the regression is silent. For the PM, the ramp-up is governance: this is the test case that sets precedent for how the team treats low-adoption, dormant dependencies with security-adjacent behavior. Decide it deliberately, write the decision down, and apply the same standard next time — that precedent is worth more than the sidebar links.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console