Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anibabbar's avatar

Start Multiple routes via slug, like product, page without any prefix in route

Hi Everyone

You guys are awesome.

I have a small query, I have different tables for Product, Post and Pages with slug col.

I need to eliminate product, page, postm product-category from urls like below

product/supa-gulper-floor-tool-wrubber-wheels-35mm

page/about-us

post/hello-world

product-category/accessories

I am using laravel 11. Its tough to change database structure now. almost 200 products have been added.

Please help.

Regards Anirudh

0 likes
3 replies
Shivamyadav's avatar

I am little bit confused, after reading it . What I understand ! You are trying to find the post or product or page by it's slug or may be trying to remove all prefixes from url and directly find the data based on the slug url

Route::get('/{slug}', function ($slug) { 
	dd($slug); //based on this slug directly find your products/pages/post
});
anibabbar's avatar

@Shivamyadav 3 different tables have slug col. Now how can i redirect it to the right controller.

martinbean's avatar

@anibabbar Unfortunately there’s no real way to do this. If a request comes in and the slug could belong to one of many models, then there’s no way for Laravel to “magically” know which model you want to query.

Basically, you’re going to have to create your own fallback controller that does it’s own routing to look up the correct model, and then pass the request off to a dedicated controller for handling:

Route::fallback(FallbackController::class);
class FallbackController extends Controller
{
    public function __invoke(Request $request)
    {
        $path = $request->path();

        // Look up product with slug
        if ($product = Product::query()->where('slug', '=', $path)->first()) {
            return resolve(ProductController::class)->show($product);
        }

        // Look up page with slug
        if ($page = Page::query()->where('slug', '=', $path)->first()) {
            return resolve(PageController::class)->show($page);
        }

        // Look up post with slug
        if ($post = Post::query()->where('slug', '=', $path)->first()) {
            return resolve(PostController::class)->show($post);
        }

        // If here, no models have record with the slug; throw 404
        abort(404);
    }
}

Obviously this will get unwieldily the more models you wish to query by slug, so you may consider extrapolating slugs out to its own model and table, and then have some form of polymorphic relation pointing back to the record associated with that slug:

public function __invoke(Request $request)
{
    $slug = Slug::query()->where('path', '=', $request->path())->firstOrFail();

    return match ($slug->model_type) {
        'page' => resolve(PageController::class)->show($slug->model),
        'post' => resolve(PostController::class)->show($slug->model),
        'product' => resolve(ProductController::class)->show($slug->model),
        default => abort(404),
    };
}

If you extrapolate slugs to its own model, you’d also be able to put a unique constraint on the path column, so that slugs are unique across all models, i.e. you can’t have both a page and a post with the same slug value.

Please or to participate in this conversation.