oliwol/laravel-slugify
A Laravel package for generating URL-friendly slugs from strings. Provides a simple helper to turn titles and text into clean, readable slugs for routes, posts, and other model fields, with optional customization for separator and uniqueness.
Architecture fit. oliwol/laravel-slugify is a narrow, single-responsibility package that hooks into Eloquent model events and route-model binding — it sits cleanly in the persistence/HTTP seam of a standard Laravel app and requires no service provider choreography beyond auto-discovery. v2.0.0 keeps that footprint and adds two additive surfaces: a fluent SlugConfig builder (invoked via a slugConfig() method on the model) and ID-anchored slugs ({slug}-{id} route keys). Neither changes the package's architectural posture; both are opt-in per model, which keeps blast radius small.
Integration feasibility. Low-to-moderate. composer require oliwol/laravel-slugify:^2.0 plus composer update is the stated path, and the release explicitly claims no breaking changes. The real work is not installation but configuration choice: teams must decide, per model, whether to stay on attribute-driven slugs (#[Slugify]) or move to the fluent API, and — more consequentially — whether to adopt appendId. Adoption of appendId changes the public URL contract of a resource (from /posts/my-title to /posts/my-title-42), which is a product/SEO decision, not a library decision. The bundled Spatie v4 migration guide matters here: it tells us the vendor expects a meaningful share of inbound users to be replacing spatie/laravel-sluggable, so "we already have slugs" is likely our starting state rather than greenfield.
Technical risk.
appendId resolves by ID, not slug, with a 308 emitted when the slug is stale. That is a behavioral change to resolution and redirect handling that will interact with signed URLs, API clients that treat 308 as terminal, and any custom resolveRouteBinding overrides.Key questions. (1) What is our actual PHP/Laravel version distribution, and does 8.4+ clear it? (2) Does appendId's 308 redirect set Cache-Control, and can we configure or disable it? (3) How does the package enforce slug uniqueness under concurrent writes? (4) Are renamed slugs in non-appendId mode redirected, or do they 404? (5) Is slugConfig() evaluated per-request or at boot, and does it cache safely under Octane? (6) Is the Spatie v4 migration path one-way, i.e. can we roll back to spatie/laravel-sluggable if needed? (7) What does the slugify-development Boost skill actually give us — is it a real productivity gain or a docs wrapper?
Stack fit. Strong on a modern Laravel codebase: PHP 8.4+, Laravel 11/12/13, auto-discovery, no queue or external service dependency. It is a pure application-layer concern with no infrastructure footprint, so it slots into existing deploy pipelines without new runbooks. The friction point is version alignment, not architecture — the package's floor is at or above the floor of the frameworks it targets, so it effectively becomes our version driver.
Migration path. Phased, and deliberately boring:
spatie/laravel-sluggable or hand-rolled Str::slug observers, and record PHP/Laravel versions per service. This determines eligibility before any code changes.^2.0, keep the existing attribute-based config, change nothing else. This validates the upgrade claim and surfaces any Octane or route-binding surprises.#[Slugify] attribute for simple cases and slugConfig() only where conditionals are genuinely needed — and document the rule before more models migrate.appendId selectively, if at all. Only for resources where slugs are unstable (frequently renamed, editorially churned) and where a permanent URL is desirable. Treat this as a product decision with an SEO owner, not a refactor.composer.json until the last model is cut over.Compatibility. Backward compatible with v1.x, and everything new is opt-in — so the upgrade itself is low-risk and the feature adoption is where risk lives. Because appendId changes public URLs, any adoption must be sequenced behind a redirect plan for pre-existing links. Cross-check that our route caching (route:cache) regenerates cleanly and that any API resource serializing route keys is updated in lockstep with the binding change.
Sequencing. Upgrade first (cheap, reversible), standardize configuration second, pilot appendId third, Spatie retirement last. Do not bundle the version bump and the appendId rollout into one release — they have very different failure modes and rollback costs.
Maintenance. Very low steady-state. Single maintainer, small surface, no runtime services. The ongoing cost is governance: keeping two configuration mechanisms from proliferating, and owning the URL-stability policy that appendId implies. The bundled Boost skill is a nice-to-have for onboarding but should be treated as documentation, not as a substitute for a written internal convention.
Support. Support burden is concentrated in the first weeks of each model migration — questions will be "why did this URL change" and "why is this 308 cached" rather than library bugs. Frontline support (content editors, SEO) needs to know that slug renames are permanent redirects. Budget a short internal note and a rollback procedure per migrated model.
Scaling. Negligible compute impact — slug generation is per-write, and route resolution by ID in appendId mode is arguably better than slug-string lookups because it hits the primary key. The scaling concern is indirect: permanent 308s accumulate in CDN and browser caches, so a rename event at scale is effectively irreversible. For high-traffic, high-SEO properties, plan rename operations as carefully as schema migrations.
Failure modes.
appendId; rehearse renames in staging.route:cache in CI.slugConfig() closures close over request state, config could leak across requests; verify per-request evaluation.Ramp-up. Roughly half a day for a Laravel-fluent engineer to install, read the reworked docs, and migrate a first model. The ID-anchored feature deserves a separate, longer review because it touches routing, SEO, and caching simultaneously — estimate a day of design plus a staging rehearsal before production. The Spatie v4 guide and new UPGRADE.md materially reduce the migration learning curve, and the "Why Laravel Slugify?" and "ID-Anchored Slugs" doc pages are the right entry points for a TPM skimming for decision inputs.
Recommendation. Upgrade to ^2.0 — the change is backward compatible and the cost of staying on v1.x grows as Laravel 13 approaches. Standardize on one configuration mechanism. Defer appendId to a separate, product-owned decision with an explicit redirect and cache policy, and do not treat it as part of the library upgrade.
How can I help you explore Laravel packages today?