skip to Main Content

Working on a project with Laravel 5.2 and just trying to implement SEO friendly urls and remove the id aspect from the url itself.

Usually you would do something like this:

Route::resource('post', 'PostsController');

where you would have in url “www.mywebsite.com/post/12” – the id of the post
now if i replace that to its title, in my controller I have to now search by their title in the database. If there are two posts with the same title i get an error since it is finding more then one record

So my question is, how do I allow the same title in posts to be used along with SEO friendly url and still search by id or something along those lines in the controller show method.

Thanks in advance for the help.

2

Answers


  1. As mentioned in the comments you can add a unique column called slug to your database table.

    One approach to this would be to make the column nullable and then generate the slug after the Post has been created.

    In your Post model add the following:

    /**
     * Boot the model
     */
    public static function boot()
    {
        static::created(function ($post) {
    
            $post->generateSlug();
    
        });
    }
    
    /**
     * Generate the slug for the newly created Post
     */
    protected function generateSlug()
    {
        $slug = str_slug($this->slug);
    
        if (static::slug($slug)->exists()) {
            $slug .= '-' . $this->id;
        }
    
        $this->slug = $slug;
        $this->save();
    }
    
    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'slug';
    }
    
    /**
     * Constrain the query to the provided slug
     *
     * @param $query
     * @param $slug
     * @return mixed
     */
    public function scopeSlug($query, $slug)
    {
        return $query->where('slug', $slug);
    }
    

    So, once the Post is created the generateSlug method is called. This will make a slug out of the title of the Post. It will then just do a quick check to see if a Post already has that slug and it so it will just append the id of the Post to the end of it. It will then save it.
    The getRouteKeyName method just means that with your Route::resource Laravel will automatically use the slug field rather than the id to resolve model.

    Obviously, feel free to change how you make the slug unique, I’ve just used the id as it’s a simple example.

    Hope this helps!

    Login or Signup to reply.
  2. You can keep the id in the url and change the route with id and slug so that if you have any link which has id will be redirected to corresponding proper url with slug.

    You can read this article to have some detailed idea.
    Sites like Stackoverflow, medium etc. follow the similar thing to make the URL SEO friendly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search