This page looks best with JavaScript enabled

How to Add Slug as Default Route Key in Laravel

 ·  ☕ 2 min read  ·  ✍️ shibu

Earlier one of my laravel project used id as route key name. I have found, slug is more readable/memorable.
So instead of using id I started to use slug as route key name.

laravel-sluggable

While create a post, we can generate a slug by our own. To do this we can use Str::slug method and append some unique value to make it unique.
But using laravel-sluggable, we can generate slug automatically

First we will install laravel-sluggable using composer

1
composer require spatie/laravel-sluggable

Let, Our model name is Post and Posts table has title and slug column. In this case, we need to
HasSlug trait and define getSlugOptions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;

class Post extends Model
{
    protected $guarded = [];
    use HasSlug;
    public function getSlugOptions() : SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('title')
            ->saveSlugsTo('slug');
    }
}

Inside getSlugOptions method definition, we are generating slug. It will generate slug from title column.
we must import HasSlug and SlugOptions at top of the file.

getRouteKey & getRouteKeyName

To make slug as route key name we need add getRouteKey and getRouteKeyName definitions in our Post model

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
class Post extends Model
{
	public function getRouteKey()
	{
	    return $this->slug;
	}
	public function getRouteKeyName()
	{
	    return 'slug';
	}
}

Calling route

We are passing a $post object directly as name route parameter, when using route method for url generation. Its automatically add slug as route key name

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

route('post.show', $post) output will be like following http://domain.test/post/demo-post-slug. Here getRouteKeyName play the role to change to slug instead id

Full Model code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Spatie\Sluggable\HasSlug;

class Post extends Model
{
    protected $guarded = [];
    use HasSlug;
    public function getSlugOptions() : SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('title')
            ->saveSlugsTo('slug');
    }
    public function getRouteKey()
	{
	    return $this->slug;
	}
	public function getRouteKeyName()
	{
	    return 'slug';
	}
}
Share on

Shibu Deb Polo
WRITTEN BY
shibu
Web Developer