Route model binding
Route::get('/topics/{topic}', ShowTopic::class); // routeKey() column
Route::get('/posts/{post:seo_slug}', ShowPost::class); // any slug column
Route::get('/clinics/{clinic}/products/{product:slug}', ShowProduct::class)->scopeBindings();
Route::get('/archive/{topic}', ShowArchived::class)->withTrashed();
route('topics.show', $topic); // current-locale slug- routeKey() makes the column getRouteKeyName(); for a locale map getRouteKey() is the current-locale slug, so URL generation depends on the locale — queued URL generation should run under the intended locale.
- Binding follows the definition’s chain (LocaleFallback::Any by default, so a URL in any resolvable locale still resolves) and prefers the current locale.
- Scoped child bindings (->scopeBindings(), HasMany and BelongsToMany) and ->withTrashed() routes are covered.
- Non-string, over-long or control-character values never reach the database.
Primary-key fallback
SlugDefinition::for('slug')->from('name')->routeKey()->bindByKeyFallback();
// /products/red-chair and /products/42 both resolvebindByKeyFallback() (or binding.key_fallback globally) tries the primary key after a slug miss — and only for values shaped like the key: ctype_digit for integer keys, the model’s own uuid/ulid validation for unique ids. A numeric slug like 2024 is never shadowed by id 2024.
Composing with HasUuids / HasUlids
HasUuids and HasUlids also define resolveRouteBindingQuery, so resolve the conflict with insteadof — HasSlug keeps their malformed-id guard for key bindings:
use HasSlug, HasUuids {
HasSlug::resolveRouteBindingQuery insteadof HasUuids;
}A method declared on the model class itself silently wins over the trait — delete your own getRouteKeyName() / resolveRouteBinding() when adopting routeKey().
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.