All packages
Sluggable for Laravel
Events & exceptions
Listen for SlugChanged to refresh sitemaps, caches or search indexes whenever a slug changes:
use RoundlyConsulting\Sluggable\Events\SlugChanged;
Event::listen(SlugChanged::class, function (SlugChanged $event): void {
// $event->model, ->column, ->locale, ->previous, ->current, ->reason (ChangeReason)
Cache::forget('sitemap');
});| Event | Payload | When |
|---|---|---|
SlugChanged (after commit) | model, column, locale, previous, current, reason (ChangeReason) | Once per persisted change. |
SlugCollisionRetried | modelClass, column, attempt | Every race retry. |
SlugsRegenerated | modelClass, report | End of a regeneration run / queued chunk. |
- SlugChanged implements ShouldDispatchAfterCommit — never fired for a rolled-back save. It fires once per persisted change, manual ones included, and once per changed locale for maps.
- It is not dispatched inside withoutGeneration() or with sluggable:regenerate --without-events.
- ChangeReason is one of Generated, Regenerated, Manual, CollisionRetry or Restored.
Exceptions
Every exception extends the abstract SluggableException (a RuntimeException). Messages name the model class, column and locale — never another row’s value.
| Exception | Thrown when |
|---|---|
InvalidSlugDefinitionException | An invalid definition or config value — duplicate columns, several route keys, a bad separator, maxLength out of range, a missing contract, a missing scope value and similar. |
InvalidLocaleException | A malformed locale code. |
SlugGenerationException | Probing exhausted, an empty source under Fail, retries used up, an index/definition mismatch, invalid custom-slugger output or an unsafe manual value. |
SlugAlreadyTakenException | A Strict manual value is already taken. |
SlugLockedException | A manual change to a locked slug. |
SlugMovedException | A retired slug was requested — renders the history redirect; implements ShouldntReport. |
UnsupportedDriverException | Index DDL on an unsupported driver (e.g. SQL Server). |
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.