Polymorphic routing
Serve every content type through one route. Register the type map:
// config/polyslug.php
'types' => [
'page' => \App\Models\Page::class,
'article' => \App\Models\Article::class,
],
Then bind a {type}/{polyslug} route — the {polyslug} parameter resolves to the right
model based on {type}, and self-healing still applies:
Route::get('/{type}/{polyslug}', [ContentController::class, 'show'])
->middleware('polyslug.canonical');
The polyslug route binding is registered by the package itself, so no Route::bind()
call of your own is needed and the route stays safe to cache.
An unknown type or an unresolvable slug yields a 404. Every registered class must be an
Eloquent model implementing Sluggable.
Resolving manually
$model = app(\Polyslug\PolyslugResolver::class)->resolve('page', 'my-title_aB3xK');
resolve() returns null for an unknown type or an unresolvable value — the caller turns
that into a 404. Use it wherever you need the same lookup outside a route, for example
in a preview endpoint or a console command.
The gate still applies
The polymorphic resolver honors
polyslugResolveQuery()
exactly like a bound route does, so a draft or a foreign tenant's record is a 404 here
too. Registering a type in polyslug.types does not widen what is reachable.
See the headless CMS recipe for the full wiring.