x-laravel/sluggable
x-laravel/sluggable is a Laravel package that simplifies generating URL-friendly slugs for Eloquent models. It automatically creates clean, unique slugs from chosen source fields, helping you build readable routes and SEO-friendly URLs with minimal configuration.
slug-2). This supports decisions on whether URLs are title-derived, stable identifiers, or localized per market.whereSlug(), findBySlug() and route model binding, so you can approve free renaming of published content without a bespoke redirect subsystem — a product decision teams usually defer or block outright.model:prune, scheduled by the package) is a storage-vs-link-durability trade-off you can state explicitly rather than discover.SlugChanged (after commit) plus slugChanging/slugChanged model events let marketing, search indexing and analytics react to URL changes without polling.Consider adoption when most of these hold:
Rules\Slug, Rules\UniqueSlug including reserved slugs), model:prune, events — rather than another service to operate.Look elsewhere or stay manual when:
Str::slug call is sufficient and this adds surface area for no gain.Due diligence before committing: license and support terms, test coverage and maintenance cadence. This is a v1.0.0 initial release, so treat the public API as stabilising — pin the version and review subsequent releases for breaking changes, particularly around the HasSlug contract, history schema and config keys.
For executives: Content teams currently can't safely change a page title without breaking links and search rankings, or they pay engineering for one-off redirect work each time. This package makes URL changes safe by default — old links keep resolving for a configurable period — and folds slug generation, uniqueness and validation into the framework we already run. The business outcome is retained search traffic and fewer ad-hoc engineering requests, with no new infrastructure to operate and a retention setting that caps storage growth. Cost is integration time on a handful of models, not a platform migration.
For engineering: One trait and one interface per model, tunable per model for source attributes, regeneration behaviour and scoping. Uniqueness is enforced against global scopes with savepoint-based retry on the unique index, so races degrade to a retry rather than a 500 or a duplicate. History is a separate table/model/connection if we want it off the primary, pruned through model:prune on the package's scheduler with configurable age, frequency and chunk size. It uses standard Laravel seams — model events, a queued-safe post-commit SlugChanged event, and form-request validation rules including one that sees reserved slugs. No new services, no queue dependency, no vendor lock beyond the package itself.
Shared risk statement: The main judgement call is the reservation window — how long old URLs stay live versus how much history we retain. That is a product policy decision we should set deliberately at launch rather than leave at a default, and revisit if link durability turns out to matter more than we assumed.
How can I help you explore Laravel packages today?