If you're using form model binding then change the key name in your model ..
public function getRouteKeyName()
{
return 'slug';
}
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Right now I have a routes with an ID as a wildcard.
Route::get('detailPage/{id}', 'DetailPageController@index');
How can I create URLs with slugs (i.e. like on stackoverflow)? I have a table of campaigns with ID and product name. How can I use this product name? So, instead of
myapp.com/detailPage/12345
I have this -
myapp.com/detailPage/Microsoft-Xbox-360
Of course, 12345 is an ID of Microsoft Xbox 360...
If you're using form model binding then change the key name in your model ..
public function getRouteKeyName()
{
return 'slug';
}
But how can I create slugs? Should I create another column in my table? I know there is a helper function str_slug($title, $separator);, but I don't know how to use it in this case...
Yes, I would add a column with the stored slug name. Something like this (not tested):
Route::get('detailPage/{slug}', function($slug){
$result = DB::table('campains')->where('slug', $slug)->get();
// .... call controller etc...
});
Yeah, you'd need a (preferably indexed) slug column. You can use the str_slug function when saving your model.
So, I should loop through my table and create slug for each item? How can I set this action to be done automatically. So when I insert new record, its slug is created as well...
@HB_BHF Generate the slug when saving your model:
class Item extends Model
{
public static function boot()
{
parent::boot();
static::saving(function ($model) {
$model->slug = str_slug($model->name);
});
}
}
If you want to use route–model binding, then you’ll need to tell Eloquent the column to use should be your slug column instead:
public function getRouteKeyName()
{
return 'slug';
}
Now, when you request a URL like items/xbox-360, it’ll instead look for a model with a slug of xbox-360 instead of a primary key.
Important note: the str_slug function will not check if the slug is already taken. To make your slug unique you could add the id at the end of the slug-string
This work for me and you can try it out:
// Store Method
public function store(Request $request) {
$game->title = $request->title;
$str = strtolower($request->title);
$game->slug = preg_replace('/\s+/', '-', $str);
$game->save();
}
// Show Method
public function show($slug){
$game = Game::where('slug', $slug)->first();
return view('game.show')->with('game', $game);
}
// Route
Route::get('/detailPage/{slug}', 'GameController@show')->name('show_game');
Actually, I'm having a problem because in Campaigns table I have a product_id as a foreign key from Products table.
Campaigns: |id| |product_id| |slug| -> I need to create here this column?
Products: |id| |product_name|
How can I create this |slug| column out of Products?
Check my solution above. The slug is generated from my title field coming from the request. Why not have the slug column on the products table.
@nanpaul68 because I search items through campaigns table. Also it is one-to-many relationship..
@HB_BHF can you show us the the code which saves the Campaigns? Because you have the product_id you should have access to the Product itself. Than you can take the product_name and create a slug.
Please be aware that a product has many Campaigns, and so many campaigns will get the same slug. Maybe you should think about the structure of you project.
@guc43 I don't have the code which saves the Campaigns. I got two tables as final product.
@HB_BHF I don't get it. How do you save your Campaigns in your table? I think you have to show us some more, if you want some help.
if campaign has many products then you will need a slug column in the campaign as well as on the product? Think FIRST how you want users to access campaigns and products. you will then know what slugs you need
Laravel has some excellent sluggable packages. One of them is https://github.com/cviebrock/eloquent-sluggable After going through this you will be able to use slug in your project.
str_slug($string)
I solved this fairly easily.
Update your route to include an optional parameter (so it works regardless):
Route::get('{member}-{slug?}', 'MemberController@show')->name('member');
On your model, add a method that handles the composition of the url parameters:
...
public function getUrlParams()
{
return [
$this->clan_id, // member
$this->rank->abbreviation . '-' . $this->name // slug
];
}
...
Now when you reference your route, use the model method to provide the parameters:
route('member', $member->getUrlParams());
Note that I opted for the "id-slug" format to avoid route collisions with other routes.
I am not sure if this is relevant but the way I handled slugs was first to have a slug in my DB table. Then in the route:
Route::get('{slug}', 'PageController@getSlug')->where('slug', '[A-Za-z0-9_\-]+');
and in the controller:
public function getSlug($slug)
{
$page = Page::where('slug', $slug)->firstOrFail();
return $page;
}
Hope this helps.
str_slug($title) is deprecated, use:
Str::slug($title)
$slug = Str::slug('Laravel 5 Framework', '-');
Please or to participate in this conversation.