Home » Laravel » How to Create Unique Slug in Laravel

How to Create Unique Slug in Laravel

Very often there is a need to refer to a model by slug. For example, you may want to hide a real model ID in the URL and replace it with a slug for better readability. Slugs must contain only digits or letters and hyphens. And they must be unique.

In this article we will explain how to create a unique slug in Laravel for models using spatie/sluggable package.

Creating Unique Slug in Laravel

I assume that you have installed Laravel. If not, see this article.

1. Prepare Model

Imagine, that you have the Article model that has a title field and you want to create a slug based on this field. Let’s create the model and the migration for it:

php artisan make:model Article php artisan make:migration CreateArticlesTable return new class extends Migration { public function up() { Schema::create("articles", function (Blueprint $table) { $table->id(); $table->string("title"); $table->text("content"); $table->timestamps(); }); } public function down() { Schema::dropIfExists("articles"); } };

Then, migrate it using this command:

php artisan migrate

2. Make Factory

You can use the factory for this example to fill the articles table and test how the slugs will be generated. Use this command:

php artisan make:factory ArticleFactory

The factory will appear in the database/factories directory. You don’t need to specify the model, it will be obtained automatically from the class name.

class ArticleFactory extends Factory { public function definition() { return [ "title" => $this->faker->text(100), "content" => $this->faker->text(200), ]; } }

2. Install Package

You can generate slugs manually. But it would be more convenient if you use the spatie/laravel-sluggable package. Install it using this command:

composer require spatie/laravel-sluggable

3. Configure the Model

Your model should have Spatie\Sluggable\HasSlug trait and implement method getSlugOptions() that will return the SlugOptions class. So, change your Article class to this:

use Illuminate\Database\Eloquent\Model; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; class Article extends Model { use HasSlug; public function getSlugOptions(): SlugOptions { return (new SlugOptions()) ->generateSlugsFrom("title") ->saveSlugsTo("slug") ->usingSeparator("-"); } }

In the getSLugOptions() method you can configure slug-generating options. In this example slugs will be generated based on the title field and saved to the slug field. If the slug needs a separator, the generator uses a hyphen. Now your model is ready for using slugs. You can find more configuration examples in the official documentation for the package.

4. Test Auto Generation

By default, slugs will be generated at the time of model creation. So, let’s create a command that will generate a few models:

php artisan make:command CreateDummyArticlesCommand

Paste this code into the handle() method:

public function handle(): int { Article::factory() ->count(10) ->create(); return self::SUCCESS; }

This code will create ten articles with unique slugs. Don’t forget to change $signature to dummy:articles:create and run this command:

php artisan dummy:articles:create

After this you can check generated slugs in the database or create any command or resource that will display articles for you.

5. Generate Slugs for Permalinks

By default this package updates slugs when you update data in your model. If you use slugs in URLs for SEO, this is not good behavior. You make slugs immutable. Add method the doNotGenerateSlugsOnUpdate() call to the getSlugOptions() method:

public function getSlugOptions(): SlugOptions { return (new SlugOptions()) ->generateSlugsFrom("title") ->saveSlugsTo("slug") ->usingSeparator("-") ->doNotGenerateSlugsOnUpdate(); }

6. Generate Slugs Manually

When you disable slug generation on model updating and you have old models, the package will not generate slugs for them. You should do it manually. Just call the generateSlug() method for the needed model. For example, you can create a command that will update slugs for all articles:

php artisan make:command ArticleSlugsUpdateCommand

Then, paste this code into the handle() method:

$articles = Article::all(); foreach ($articles as $article) { /** @var Article $article */ $article->generateSlug(); } return self::SUCCESS;

Now, you can run this command and update slugs for all models.

Wrapping Up

In this short article we have explained how to generate unique slugs in Laravel for Eloquent models. As you can see it is pretty simple. Just install the package, add configuration and it will do all the work for you. What package do you use for generating slugs? Tell us using the comment form below.

Your Reaction

Leave a Comment