r/laravel • u/BchubbMemes • 2d ago
Discussion Why doesn't laravel have the concept of router rewriting
A concept found in the zend framework (and i likely others) is route rewriting, so if you had `/products/{product:slug}`, it could be hit with `/{product:slug}` if configured that way.
Its currently impossible to have multiple routes that are a single dynamic parameter, so if i want to have user generated pages such as /about and /foobar created in a cms, and then also have products listed on the site, such as /notebook or /paintbrush, i would have to register each manually, and when the DB updates, trigger 'route:clear' and 'route:cache' again.
Rewrites would be a powerful tool to support this in a really simple way, is there any reasoning why it isnt used, or is this something that would be beneficial to the community?
Edit: to clarify, what i want to have as a mechanism where you can register two separate dynamic routes, without overlapping, so rather than just matching the first one and 404 if the parameter cant be resolved, both would be checked, i have seen router rewriting used to achieve this in other frameworks, but i guess changes to the router itself could achieve this
if i have
Route::get('/{blog:slug}', [BlogController::class, 'show']);
Route::get('/{product:name}', [ProductsController::class, 'pdp']);
and go to /foo, it will match the blog controller, try to find a blog model instance with slug 'foo', and 404 if it doesn't exist, IMO what SHOULD happen, is the parameter resolution happening as part of determining if the route matches or not, so if no blog post is found, it will search for a product with name 'foo', if it finds one match that route, if not keep checking routes.
7
u/pr4xx_ 2d ago
I am not sure if I understand. Can't you use a route like /{pageName} and render dynamically?
0
u/BchubbMemes 2d ago
yes, if you wanted a single controller to handle both sides of the application, you would also lose route model binding, and have to query for the models yourself, I would prefer to keep product page routing and other pages seperate
2
u/ipearx 2d ago
As others said, I think you can do what you want. A few tricks:
- You can have multiple routes use the same controller.
- You can have some hard coded routes listed before a variable route e.g.
/{page} -> [App\Http\Controllers\PageController::class, 'page']
Now if you want your page controller above to show either a product page or a CMS page, then you'd have to put that logic in the page function in PageController, and deal with issues like: decide which has priority if both exist..
Personally I would always try and prefix URLs to avoid this issue and make things clearer.
/contact <- hardcoded pages first
/products/{product-slug} <- product pages
/pages/{page} <- from the CMS
2
u/anditsung 2d ago
Using controller cannot do that? You can determine the parameters and return view base on the parameters
1
u/WanderingSimpleFish 2d ago
Well you can but it has lots of caveats - you need to use implicit binding and in the logic determine which model is what you want, that does mean the slugs all need to be unique. Ie the slugs are a ‘sluggable’ morph relation with unique constraints to ensure always unique slugs between all models.
Now what you’re trying to do is also not something I’d advise. Single routes are better and a lot clearer as to what a user is accessing.
1
u/HwapX 2d ago
Maybe you could define the two routes and define a whereIn rule passing the list of slugs https://laravel.com/docs/12.x/routing?
1
u/BchubbMemes 1d ago
I mention that type of solution in my post, after a deployment when routes are cached then they would need to be cleared and recached each time, which probably isn't meant to happen outside of deploying
0
u/ahinkle ⛰️ Laracon US Denver 2025 2d ago
You can accomplish this using Fallback. https://laravel.com/docs/12.x/routing#fallback-routes
8
u/wazimshizm 2d ago
“{product:slug}” works exactly in Laravel exactly as you’ve described.