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

Nova Sluggable Laravel Package

drobee/nova-sluggable

A Laravel Nova field for generating and managing URL slugs from a title or other attribute. Adds a sluggable input to Nova resources, creating unique, SEO-friendly slugs automatically and keeping them in sync as records are edited. A simple drop-in field for Eloquent models.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

drobee/nova-sluggable is a deliberately narrow artifact: a single Nova form field that derives a slug from a source attribute and writes it into the resource form. It is a presentation-layer control surface, not a slug engine. That distinction is the whole architecture conversation — it does not touch models, migrations, API controllers, importers, seeders, or queue workers. Every non-admin write path remains the responsibility of a model-level trait (typically spatie/laravel-sluggable).

Fit is therefore conditional and cheap to assess:

  • In scope: Nova is already installed, licensed, and a committed part of the admin platform; editors need generate/regenerate/edit affordances in the resource form.
  • Out of scope by construction: any system where slugs must be consistent across admin, API, and ingestion paths — there the trait is the source of truth and this field is cosmetic polish.
  • Redundancy flag: Nova 4+ ships a first-party Slug field with source syncing. Until a written acceptance criterion demonstrates native is insufficient, the architecturally correct answer is to add no dependency at all. This evaluation should not proceed past that gate.

Integration feasibility

Low effort, low surface area, high reversibility. The integration is a composer require plus a Slug::make('Slug')->from('title') line on the target resources. The package is MIT and roughly a hundred lines of field code, so comprehension cost is an afternoon, not a sprint.

The real feasibility work is preconditions, not code:

  1. Nova licensing in CI. Nova is a privately hosted paid package. Without repository credentials in CI, composer install fails for this field and every other Nova field — a pre-existing condition this package will expose, not create.
  2. Database uniqueness. A unique index on the slug column plus a unique:table,slug,{{resourceId}} validation rule. The field cannot guarantee uniqueness; concurrent creates are a database problem.
  3. Model trait adopted first. Without it, an API write silently persists null while the editor's form works — the worst class of inconsistency, and one that surfaces as an SEO defect rather than an error.
  4. Asset render verification. Nova field packages ship prebuilt JS/CSS. Assets compiled against a different Nova toolchain render blank or throw console errors even after a clean composer require. This is the single most common silent failure and costs minutes to check on a branch.

Technical risk

Risk Likelihood Impact Mitigation
Compiled assets break on Nova upgrade Medium-high Blank slug input in admin, silent CI smoke test rendering the resource form; pin narrow constraint
Scope misread as "slugs are handled" High Null/duplicate slugs from API, imports, seeders Trait as source of truth; documented convention
Upstream goes dark (0 dependents, 45 stars) Medium Field rots until a form breaks MIT fork into app/Nova/Fields, pre-agreed owner
Hand-curated slugs overwritten Low-medium Irreversible SEO regression Back up column; gate write-back before enabling editable mode
Transliteration gaps (CJK, accented) Medium if multilingual Empty/malformed slugs Test with real content; rely on trait transliteration
Update semantics surprise High Typo fix leaves stale slug; stakeholder confusion Write the acceptance criterion down, verify field matches

Note the release date (May 2024) and zero dependents: there is no community backstop, no "someone already filed this bug" safety net, and compatibility will not move in lockstep with Nova or Laravel majors.

Key questions

  • Does Nova's first-party Slug field already satisfy the written acceptance criteria? If yes, terminate the evaluation here.
  • Which Nova major are we on, and has the field been verified to render on a branch — not inferred from the README?
  • Is a model-level slug trait already in place, or is this package about to become a false signal of coverage?
  • Who owns this field when Nova 5 lands: upstream, a fork, or a reimplementation?
  • Do any records have hand-tuned slugs that must be preserved?
  • Is our content multilingual, and has the field been tested against real non-Latin titles?
  • Does the roadmap treat Nova as a long-term platform commitment, or are we accumulating small unmaintained field dependencies that will need a migration?

Integration Approach

Stack fit

Laravel + Nova, exclusively. The package is inert outside a Nova panel, so if the admin layer is Filament or bespoke Blade, the answer is a model trait plus a plain text field and this evaluation closes. Assuming Nova: the field composes naturally with the existing resource class, sits as a sibling of the source attribute so the generate action reads in context, and imposes no migration beyond the slug column the model already needs. Its only runtime coupling is to Nova's field asset pipeline.

Migration path

No data migration. The slug column either exists or is added with string('slug')->unique()->nullable(); existing rows are backfilled by the model trait, not by the field. This makes adoption and reversal symmetric — adding the field is a ->make() line, removing it is deleting that line, and no schema or persisted state depends on the package.

The one genuine migration decision is update semantics: does the slug regenerate when the title changes, or only on create? Most implementations sync on create. That behaviour must be stated as an acceptance criterion before rollout, because stakeholders will otherwise discover it as a bug ("I fixed the typo, the URL didn't change"). If any form of slug history or 301 redirect on change is desired, this is out of scope — that is a product feature with real scope, and the correct decision is to defer rather than stretch a form field.

Compatibility

Two version axes and both need verification on a branch:

  • Nova major. Assume the May 2024 release targets Nova 4. Nova 5 compatibility is a branch question, not a README question. Nova majors break field packages regularly.
  • Laravel major. Same posture; the field surface is small but the asset build is the fragile part.

Sequencing discipline: pin a narrow Composer constraint, and add a CI job that boots Nova and renders the resource form. That job is what converts a silently broken admin form into a build failure — the entire compatibility posture rests on it.

Sequencing

  1. Gate (half-day): compare Nova's native Slug field against written acceptance criteria. Most likely outcome: native wins and no dependency is added. Do this before anything else.
  2. Preconditions: confirm slug column with unique index; adopt or verify the model trait as source of truth; confirm Nova credentials in CI.
  3. Spike on a branch (half to one day): install, register on a single Post resource, load the create form, confirm compiled assets render, test transliteration with real content, document actual fluent method names from vendor/ source (the README is thin).
  4. Pilot: one resource, read-only mode by default for non-technical editors.
  5. Decide: adopt upstream pinned / vendored fork / reimplement. Pre-agree the owner and the exit path before this decision, not after the first breakage.
  6. Roll out to further resources only after the CI render smoke test is green and merged in the same PR as the adoption.

Standardise on one field type app-wide. Mixing Nova native on some resources and this package on others doubles the upgrade blast radius — two asset pipelines to debug on every Nova bump.

Operational Impact

Maintenance

The dominant ongoing cost is not code, it is compatibility re-verification on every Nova and Laravel major. Budget one patch per major release, with a named maintainer. With zero dependents and 45 stars there is no upstream community pressure to fix issues, so the internal owner is the de facto maintainer — the fork is the plan, not the fallback. Because the surface is roughly a hundred lines and MIT-licensed, vendoring into app/Nova/Fields is a legitimate exit that costs hours, not weeks. Pre-agree that exit path and its owner before adoption.

Secondary maintenance: keeping the slug convention documented so the admin-form-only boundary is understood by the next engineer, and keeping editable vs. read-only policy consistent across resources.

Support

Support load should be near zero if the scope boundary is socialised. The failure it introduces is not a crash — it is a silent inconsistency between the admin form and every other write path. That class of issue arrives as "the URL is blank on the API-created article" with no error log to point at, which is expensive to diagnose and easy to prevent with the trait. Ticket deflection is the actual value: editors who currently file engineering tickets to fix a slug get a form field instead. That is a measurable reduction in low-value tickets, and the right success metric for the pilot.

Scaling

Scales fine within its envelope. Uniqueness enforcement is on the database index, so concurrent creates collide and retry at the database layer, not in the field. The field adds no per-request overhead worth modeling. The scaling limit is organisational, not technical: as the number of Nova resources grows, the number of ->make() sites that must be touched on a Nova major grows linearly. That is why standardising on one field type and pinning the constraint matters more at scale than any performance consideration.

Failure modes

  • Blank field after a Nova upgrade (highest frequency, silent). Mitigation: CI render smoke test.
  • Null slug from API/import/seeder (highest impact, SEO-visible). Mitigation: model trait as source of truth, documented boundary.
  • Duplicate slug on concurrent create. Mitigation: unique index + {{resourceId}} validation rule.
  • Hand-curated URL overwritten (irreversible). Mitigation: back up the column, gate write-back before enabling editable mode.
  • Malformed/empty slug from non-Latin titles. Mitigation: test with real content, fall back to trait transliteration.
  • Stale slug after title edit. Mitigation: written acceptance criterion, verified behaviour.
  • Composer resolution failure in CI on missing Nova credentials — a pipeline failure, visible and fast, which is the good failure mode.
  • Upstream abandonment. Low blast radius given MIT + small surface; fork is cheap.

Ramp-up

Engineering: one engineer, half-day spike, no prior Nova-field expertise required — the source is short enough to read end to end, and that reading is the onboarding. Total adoption cost is roughly 1–3 dev-days including tests, offset against the same 1–3 days to build in-house, which is why the buy-vs-build question is largely a wash and the native-field comparison is the only decision that really matters.

Editorial/stakeholder: minimal, but two items need explicit communication before launch — (a) slugs are only auto-generated in the admin form, and (b) whether the slug changes when the title changes. Both are one-line statements that prevent a disproportionate share of downstream confusion.

Recommendation: a one-resource pilot behind a short spike, treated as a swappable convenience layer with slug logic owned by the application, not the package. Do not treat it as a platform commitment. The correct first action is proving Nova's native field insufficient; if it is sufficient, add nothing.

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