how to generate unique slug in laravel

How to Generate Unique Slug in Laravel?

In this tutorial, I will give you an example of How to Generate Unique Slug in Laravel, So you can easily apply it with your laravel 5, laravel 6, laravel 7, and laravel 8 application.

If you are working with a project or blog where records require a so-called slug to Generate a Unique slug From the Title.

First, what we’re doing here, This is the example :

Generate Unique Slug in Laravel
Generate Unique Slug in Laravel

So we have many options to use slug instead of id in Url and get the data using slug from URL, to create unique slugs for every post or page in Laravel. The slug works like the Primary Key and it will be always unique.

it’s convenient to generate a unique slug immediately after the title has been typed in. In this article, I will show you Generate Slug Keyword from Title in the Laravel application, with AJAX, and with a help of a sluggable package.

Make Seo Friendly URL using Laravel Sluggable Package

A slug is a simplified version of a string, typically URL-friendly, we use the slug to make user-friendly URLs and SEO friendly URL which is easy to read and this is very useful for SEO and digital marketing.

For example, if you have an e-commerce with products, you could refer to each product via the ID:

www.yourdomain.com/product/1
www.yourdomain.com/product/2

So with the help of sluggable package and Str::slug() method to convert that title into something friendlier we create unique Seo friendly URLs:

www.yourdomain.com/product/realme-android-phone
www.yourdomain.com/product/apple-iphone-se

So, let’s start with scratch to Generate a Unique slug From the Title :

Installation

Depending on your version of Laravel, you should install a different version of the package.

Generate Unique Slug in Laravel

Install the package via Composer :

composer require cviebrock/eloquent-sluggable

The package will automatically register its service provider.

Optionally, publish the configuration file if you want to change any defaults :

php artisan vendor:publish --provider="Cviebrock\EloquentSluggable\ServiceProvider"

Generating Migration :

php artisan make:migration create_custom_slug_examples_table

Migration Structure :

database\migrations\CreateCustomSlugExamplesTable

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCustomSlugExamplesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('custom_slug_examples', function (Blueprint $table) {
            $table->id();
            $table->string('product_name');
            $table->double('product_price',8,2);
            $table->string('title');
            $table->string('slug');
            $table->longText('product_description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('custom_slug_examples');
    }
}

Run Migration :

php artisan:migrate
generate slug from title in laravel

Create Model :

php artisan make:model Model/CustomSlugExample

App\Model\CustomSlugExample

<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;

class CustomSlugExample extends Model
{
     use Sluggable;
     protected $table = 'custom_slug_examples';
     protected $fillable = ['title','slug'];

     public function sluggable()
     {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}

Create Routes :

routes\web.php

#Generate Slug Example
Route::get('/add-product','CustomSlugExampleController@addProduct')->name('product.create');
Route::get('package/check_slug','CustomSlugExampleController@checkPackage_Slug')->name('check.slug');
Route::post('package/store','CustomSlugExampleController@storeProduct')->name('product.store');
Route::get('/list-product','CustomSlugExampleController@listProduct')->name('product.list');
Route::get('/view-product/{slug}','CustomSlugExampleController@viewProduct')->name('product.view');

Create Controller :

php artisan make:controller CustomSlugExampleController

App\Http\Controllers\CustomSlugExampleController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Model\CustomSlugExample;
use Cviebrock\EloquentSluggable\Services\SlugService;

class CustomSlugExampleController extends Controller
{
    public function addProduct(){
    	return view('slugExample.create');
    }

    public function checkPackage_Slug(Request $request)
    {
        $slug = SlugService::createSlug(CustomSlugExample::class , 'slug', $request->title);
        return response()->json(['slug' => $slug]);
    }

    public function storeProduct(Request $request){
    	$data = new CustomSlugExample();
    	$data->product_name  = $request->product_name;
    	$data->product_price = $request->product_price;
    	$data->title         = $request->title;
    	$data->slug          = $request->slug;
    	$data->product_description = $request->product_description;
    	$data->save();
    	return redirect()->route('product.list')->with('message','Product Added Successfully');
    }

    public function listProduct(){
    	$productData = CustomSlugExample::get();
    	return view('slugExample.list',compact('productData'));
    }

    public function viewProduct($slug){
    	$viewProductData = CustomSlugExample::where('slug',$slug)->first();
    	return view('slugExample.view',compact('viewProductData'));
    }

}

Create Blade Files :

resources\views\slugExample\create.blade.php

Generate Unique Slug in Laravel
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Unique Slug Generate | Laravel</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
   </head>
   <body>
      <div class="container">
         <h3>Unique Slug Generate in Laravel | Seo Friendly URL's | www.8bityard.com</h3>
         <div class="card">
            <form name="generate_slug" method="post" action="{{route('product.store')}}">
               @csrf
               <div class="card-header">Please fill up all the Field's.</div>
               <div class="card-body">
                  <div class="row">
                     <div class="col-md-6">
                        <label for="Product Name">Product Name :</label>
                        <input type="text" class="form-control" placeholder="Enter product name" name="product_name" required>
                     </div>
                     <div class="col-md-6">
                        <label for="Product Name">Product Price :</label>
                        <input type="number" class="form-control" placeholder="Enter product price" name="product_price" required>
                     </div>
                     <div class="col-md-6">
                        <label for="Product title">SLUG Title :</label>
                        <input type="text" id="title" class="form-control" placeholder="Enter product Title" name="title" required>
                     </div>
                     <div class="col-md-6">
                        <label for="Product Slug">SLUG URL :</label>
                        <input type="text" id="Pkgslug" class="form-control" name="slug">
                     </div>
                     <div class="col-md-6">
                        <label for="Product Description">Product Description :</label>
                       <textarea class="form-control" name="product_description" placeholder="Enter product description" rows="4" cols="50"></textarea>
                     </div>
                  </div>
               </div>
               <div class="col-md-3">
                  <button type="submit" class="btn btn-block btn-info btn-sm">Save</button>
               </div>
         </div>
         </form>
      </div>
   </body>
</html>
<script>
   $('#title').change(function(e) {
     $.get('{{ route('check.slug') }}',
       { 'title': $(this).val() },
       function( data ) {
         $('#Pkgslug').val(data.slug);
       }
     );
   });
</script>

resources\views\slugExample\list.blade.php

Generate Unique Slug in Laravel
Generate Unique Slug in Laravel
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Unique Slug Generate | Laravel</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
   </head>
   <body>
      <div class="container">
         <h4>Unique Slug Generate in Laravel | Seo Friendly URL's | www.8bityard.com</h4>
         <div class="row justify-content-end mb-1">
            <div class="col-sm-8">
               @if(Session::has('message'))
               <div class="alert alert-success alert-dismissible p-2">
                  <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
                  <strong>Success!</strong> {!! session('message')!!}.
               </div>
               @endif
            </div>
         </div>
         <table class="table table-bordered table-sm">
            <thead>
               <tr>
                  <th>S.no</th>
                  <th>Product</th>
                  <th>Price</th>
                  <th>Title</th>
                  <th>Slug Url</th>
                  <th>Description</th>
                  <th>Action</th>
               </tr>
            </thead>
            <tbody>
                @if ($productData->count() > 0 )
               @foreach($productData as $key => $data)
               <tr>
                  <td>{{ $key+1 }}</td>
                  <td>{{$data->product_name}}</td>
                  <td>{{$data->product_price}}</td>
                  <td>{{$data->title}}</td>
                  <td>{{$data->slug}}</td>
                  <td>{{$data->product_description}}</td>
                  <td>
                <a href="{{route('product.view',$data->slug)}}" class="btn btn-info btn-sm" role="button">View</a>
                 </td>
               </tr>
            </tbody>
            @endforeach
            @else
            <h2>No Data Found !</h2>
            @endif
         </table>
      </div>
   </body>
</html>

resources\views\slugExample\view.blade.php

Generate Unique Slug in Laravel
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Unique Slug Generate | Laravel</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
   </head>
   <body>
      <div class="container">
         <h3>Unique Slug Generate in Laravel | Seo Friendly URL's | www.8bityard.com</h3>
         <div class="card">
            <form>
               <div class="card-header">View Product</div>
               <div class="card-body">
                  <div class="row">
                     <div class="col-md-6">
                        <label for="Product Name">Product Name :</label>
                        <input type="text" class="form-control" value="{{$viewProductData->product_name}}" readonly>
                     </div>
                     <div class="col-md-6">
                        <label for="Product Name">Product Price :</label>
                        <input type="text" class="form-control" value="{{$viewProductData->product_price}}" readonly>
                     </div>
                     <div class="col-md-6">
                        <label for="Product title">SLUG Title :</label>
                        <input type="text" id="title" class="form-control" value="{{$viewProductData->title}}" readonly>
                     </div>
                     <div class="col-md-6">
                        <label for="Product Slug">SLUG URL :</label>
                        <input type="text" id="Pkgslug" class="form-control" value="{{$viewProductData->slug}}" readonly>
                     </div>
                     <div class="col-md-6">
                        <label for="Product Description">Product Description :</label>
                        <textarea  disabled class="form-control" rows="4" cols="50">{{$viewProductData->product_description}}</textarea>
                     </div>
                  </div>
               </div>
               <div class="col-md-3"> 
                  &nbsp;<a href="{{route('product.list')}}">Go Back</a>
               </div>
         </div>
         </form>
      </div>
   </body>
</html>

URL Duplicacy :

Slugs tend to be unique as well. So if you add another product with the same title, you’d want to distinguish between them somehow, typically with an incremental counter added to the end of the slug.

www.yourdomain.com/product/brand-new-realme-s8-plus
www.yourdomain.com/product/brand-new-realme-s8-plus-1
Generate Unique Slug in Laravel
Generate Unique Slug in Laravel

In this article, we learned How to Generate Unique Slug in Laravel, I hope this article will help you with your Laravel application Project.

Read Also : Restore back deleted record in Laravel.