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

Laravel Unique Urls Laravel Package

vlados/laravel-unique-urls

Laravel package for generating and managing unique URLs, helping you create collision-free slugs and SEO-friendly permalinks for models and content with automatic uniqueness checks and customizable URL patterns.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Scope note: this is a baseline assessment — there is no prior assessment or repository/telemetry data on file. Everything below is derived from the v2.2.0 release notes and describes the package as a Laravel artisan tooling layer that generates and audits model URLs via urls:generate and urls:doctor.

Architecture fit

The package operates as a console-level tooling layer over Laravel's container and console APIs, with URL generation delegated to a per-model urlHandler() and slug behaviour to urlStrategy(). v2.2.0 introduces Services\ModelDiscoveryService, which is the architecturally significant change: model discovery was previously implicit (Spatie ModelFinder defaulting to app_path()) and is now an explicit, configurable, shared service consumed by both commands. That consolidation is the right shape — one source of truth for "which models does this application own" — and it turns a hardcoded assumption into an extension point via the new model_paths config key. Optional coupling to nwidart/laravel-modules is detected at runtime with a base_path('Modules') fallback, which keeps the package viable for both module-based and conventional apps. The urls:doctor redesign (resolving controllers through ControllerResolver and mirroring LaravelUniqueUrlsController's __invoke/show/index fallback logic) is a correctness improvement that aligns static analysis with runtime behaviour — a genuine architectural alignment rather than a cosmetic change.

Integration feasibility

High for conventional Laravel apps: no configuration change is required, and leaving model_paths unset preserves the previous app/-only behaviour as a strict subset. For modular apps the feasibility hinges on whether the project's PSR-4 map and directory layout match what the discovery service expects; the release supports both Modules/{Module}/app and legacy Modules/{Module}/Models / Entities layouts, which covers the common nwidart conventions and most hand-rolled variants. model_paths accepts three shapes (bare directory, Namespace => /dir pair, full descriptor), so teams can bypass namespace guessing entirely when their autoload map is unusual. Standard composer require / version bump; no migrations, no schema, no service provider re-registration implied.

Technical risk

  • Controller instantiation in urls:doctor. Resolution now builds the controller through the container rather than calling class_exists(). Constructors with side effects (auth checks, repository calls, HTTP clients, queue dispatches) will execute during a "read-only" audit. Failures are captured as errors rather than aborting the run, which is the right failure mode, but the side-effect surface is new and undocumented in terms of guarantees.
  • Deliberately silent strategy failures. urlStrategy() exceptions remain unreported because doctor runs against empty instances. This is defensible, but it means a green doctor run does not imply slug generation works. Doctor's signal should be read as "wiring is valid," not "URLs will generate."
  • Silent namespace mismatch. A directory whose namespace prefix doesn't match the composer PSR-4 map contributes zero models. v2.2.0 mitigates this by naming any path that yields no models, and --strict escalates it to a non-zero exit — but only if teams opt in. Default exit codes on empty/partial scans remain a governance gap.
  • Ambiguity and short-name fallback. --model=Post now falls back to discovered models when not in App\Models. Convenient interactively; in CI scripts it converts a previously hard failure into a potential collision error or, worse, a resolution to a different model than intended if only one match exists across modules.
  • Behaviour deltas land as a findings wave. class_uses_recursive() widens coverage to models inheriting the trait from a parent, and modular models were previously invisible entirely. Modular projects should expect doctor to report strictly more after upgrade. Two changes move the other way (pinned Livewire component names and show()/index() fallbacks no longer flagged as broken), so some previously red findings will go green — teams should confirm that's genuine and not masking.
  • Output string change. Everything is ok now becomes Everything is ok — checked 12 models in 2 paths; anything doing exact-match parsing of doctor's stdout breaks.

Key questions

  1. Which Laravel and PHP versions are supported, and is there a documented semver/deprecation policy for the model_paths schema?
  2. Does a non-strict doctor run exit non-zero when individual models/controllers are recorded as errors, or only on --strict empty scans? This determines whether doctor is usable as a CI gate at all.
  3. Is there a machine-readable (--json) output for dashboards and trend tracking, or is stdout parsing the only option?
  4. What is the measured scan time and memory footprint on a large modular monorepo (e.g. 30+ modules, 500+ models), given controllers and models are now instantiated?
  5. Are controller constructors executed in a context that could touch the database, queue, or session? Is there a documented "safe to run in CI" contract?
  6. Is spatie/laravel-model-finder a hard dependency, and is it still required given the new discovery service?
  7. What is the maintenance posture — release cadence, maintainer count, test coverage for the module layouts and namespace-guessing paths?

Integration Approach

Stack fit

Fits any Laravel application already using artisan in local dev and CI, and is complementary to route:list, IDE helper generation, and static analysis rather than overlapping them. It slots naturally into a GitHub Actions / GitLab CI job that runs after composer install and before deploy. For module-based codebases (nwidart/laravel-modules, or in-house Modules/ or src/Domain/ PSR-4 layouts) this release is effectively the first version that is usable — prior versions quietly ignored those models.

Migration path

  1. Establish a baseline: on the current version, capture urls:doctor output (and exit code) on the branch you intend to upgrade.
  2. Bump the constraint, run the full test suite, then re-run urls:doctor and diff against the baseline. Expect net-new findings for modular projects.
  3. Triage findings into three buckets: (a) genuinely broken handlers/URLs, (b) healthy models newly brought into scope, (c) false positives from namespace/PSR-4 mismatch.
  4. For bucket (c), either correct the PSR-4 mapping or pin model_paths explicitly with 'Namespace' => '/dir' pairs to remove the guessing step. Prefer explicit pairs for any non-standard layout.
  5. Convert --model invocations in scripts to fully qualified class names; treat the short-name fallback as an interactive convenience only.
  6. Update any CI step that exact-matches doctor's success line.
  7. Only after a clean, explicit-path scan, consider --strict.

Compatibility

No breaking API change is declared. Published config files predating model_paths fall back to automatic discovery, which is a superset of the old behaviour — so an unmodified config cannot lose coverage. The compatibility risks are behavioural and textual (wider reporting scope, changed doctor messaging, changed --model resolution semantics), not structural. Nothing here requires a coordinated change with application code.

Sequencing

Upgrade and observe first, gate later. Run the package upgrade in an isolated PR; land the doctor-output diff as the review artefact; fix namespace and path configuration; then, in a follow-on PR, adopt --strict as non-blocking (warning only) for one sprint before making it blocking. Keep urls:generate out of automated write paths until --model FQCN normalisation is complete.

Operational Impact

Maintenance

The surface area grows modestly but meaningfully: model_paths has three accepted shapes and a "skip non-existent directories" rule, which will generate support questions. Documentation should show the exact three forms with one canonical example per project layout (plain Laravel, nwidart modules, custom PSR-4). Namespace guessing is coupled to composer.json's PSR-4 map, so it drifts whenever autoload configuration changes — explicit Namespace => path pairs are the lower-maintenance choice for anything non-standard.

Support

Expect a predictable wave of "doctor reports 60 new issues after upgrading" tickets from modular teams. Pre-empt with a release note and internal runbook stating that doctor was previously blind to module models, not clean. The corresponding positive change — pinned Livewire components and show()/index() fallbacks no longer reported broken — should be called out so teams don't assume the package regressed in the other direction.

Scaling

Cost scales with module count × model count, and now includes model and controller instantiation rather than cheap class_exists() checks. This should be negligible for apps in the low hundreds of models and worth measuring for modular monorepos. Recommend a one-off timing exercise on the largest application before wiring doctor into a per-PR job; if it's slow, schedule it nightly instead.

Failure modes

  • Directory with a mismatched namespace prefix contributes zero models; surfaced only via the per-path warning or --strict.
  • urlStrategy() failures are silent by design — a green doctor run can still ship broken slugs.
  • Ambiguous short names fail loudly with candidates listed; single-match fallback can silently resolve to an unintended model if names move between modules.
  • Controller constructors with real dependencies now execute during audits; unresolvable dependencies are recorded as errors rather than crashing the run, and one broken model no longer aborts coverage for everything after it.
  • Non-existent model_paths entries are skipped without loud failure — a typo in config degrades coverage quietly.
  • Exit-code semantics for recorded errors (versus empty scans) are the main unknown; confirm before relying on doctor in CI.

Ramp-up

Low for engineers: two artisan commands and one optional config key. Realistic estimate is roughly half a day to upgrade and triage a small modular app, and one to three days for a large modular monorepo where PSR-4 mismatches need cleanup and findings need bucketing. The single highest-value control is the pre/post doctor diff — it is cheap, it converts an opaque behaviour change into a reviewable list, and it gives the TPM a defensible answer when asked whether the upgrade "broke anything."

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core