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

dtommy79's avatar

Adding category slug to url

Hi,

I have a blog. Currently I am displaying posts like this:

Route::get('post/{slug}', [BlogController::class, 'post'])->name('frontend.post');

In my controller I'm getting the slug like this

public function post($slug)
    {

        $post = BlogPost::with('author', 'category')->where('slug', $slug)->first();

    }

I want to change this to display the category slug instead of "post". So I added a new query to my post method:

$category = DB::table('blog_post_categories')->where('slug', $catSlug)->first();

and changed my route like this:

Route::get('{catSlug}/{slug}', [BlogController::class, 'post'])->name('frontend.post');

Theoretically this works and I can access my posts directly, but in my post view I'm displaying other stuff like related posts, popular posts and latest posts and I'm getting the error

Missing required parameter for [Route: frontend.post] [URI: {catSlug}/{slug}] [Missing parameter: slug].

because of how they are linked, for example:

<a href="{{route('frontend.post', $relatedPost->slug)}}">{{ $relatedPost->title }}</a>

<a href="{{route('frontend.post', $latestPost->slug)}}">{{ $latestPost->title }}</a>

<a href="{{route('frontend.post', $popularPost->slug)}}">{{ $popularPost->title }}</a> 

I'm getting these in my controller like this:

$relatedPosts = DB::table('blog_posts')->where('blog_post_category_id', '=', $post->blog_post_category_id)->where('id', '!=', $post->id)->inRandomOrder()->limit(3)->get();

$popularPosts = DB::table('blog_posts')->orderBy('viewed', 'DESC')->limit(4)->get();

$latestPosts = DB::table('blog_posts')->orderBy('id', 'DESC')->limit(4)->get();

This is my blog_post_categories table

$table->string('name', 191)->unique();
$table->string('slug', 191)->unique();

and this is my blog_posts table

$table->string('title', 191)->unique();
$table->string('slug', 191);
$table->unsignedBigInteger('user_id');
$table->mediumText('content');
$table->string('meta_title', 191);
$table->string('meta_description', 191);
$table->boolean('is_featured');
$table->unsignedBigInteger('blog_post_category_id');
$table->string('featured_img')->nullable();

So i'm guessing I need to change the way I'm accessing the related, popular and latest posts and I also need to adjust routes in the "a href"s as well. But i can't figure it out how. Any help is appreciated.

0 likes
7 replies
Sinnbeck's avatar

You have told the route that it always will get {catSlug} and {slug} but you only provide one item. You need to give it 2 now

<a href="{{route('frontend.post', ['catSlug' => 'foobar', 'slug' => $relatedPost->slug])}}">{{ $relatedPost->title }}</a>

replace foobar with the actual code for the category

1 like
dtommy79's avatar

@Sinnbeck Thanks, i managed to do that, but i noticed a weird issue.

So currently this is my route for my posts

Route::get('{catSlug}/{slug}', [BlogController::class, 'post'])->name('frontend.post');

So my url looks like this: mysite.com/category_slug/post_title

In the browser if I change the "category_slug" to anything, the post is still available, instead of getting a 404 page.

What am I missing here?

mlewis's avatar

@dtommy79 If you want a 404 then you instead of using first() here, you should use firstOrFail()

$category = DB::table('blog_post_categories')->where('slug', $catSlug)->firstOrFail();
1 like
dtommy79's avatar

@mlewis thanks for the reply. I also needed to change to eloquent. With DB I get the Call to undefined method Illuminate\Database\Query\Builder::firstOrFail()

error

1 like
Sinnbeck's avatar

@dtommy79 you need to resolve them in the method

public function post(Category $category, BlogPost $post)

Please or to participate in this conversation.