Laravel Packages

Laravel Sluggable

Published
Laravel Sluggable image

Nuno Maduro released Laravel Sluggable, a package for automatic slug generation on Eloquent models. Rather than reaching for a trait or a base class, the package uses a single PHP attribute #[Sluggable], placed directly on the model.

Beyond the basics, it covers the edge cases that tend to surface in real apps: collision handling, scoped uniqueness (per-tenant, per-locale), multi-column sources, soft-deleted record collisions, and full Unicode and CJK transliteration.

Get Started

Install the package via Composer:

composer require nunomaduro/laravel-sluggable

Note: This package requires PHP 8.5+ and Laravel 13.5+

The quickest way to wire up a model is the included make:sluggable Artisan command:

php artisan make:sluggable Post

It reads your model's table schema, picks the most likely source column (title, name, headline, or subject), adds the #[Sluggable] attribute to the model class, and creates a migration in database/migrations:

use NunoMaduro\LaravelSluggable\Attributes\Sluggable;
 
#[Sluggable(from: 'title')]
class Post extends Model
{
}
Schema::table('posts', function (Blueprint $table) {
$table
->string('slug')
// ->nullable()
->unique()
->after('id');
});

Review the migration before running it. You may need to make the column nullable if the table already has rows before you run php artisan migrate.

After that, slug generation is automatic:

$post = Post::create(['title' => 'Laravel News Rocks']);
$post->slug; // "laravel-news-rocks"

Configuration

All options live on the attribute itself. The from and to parameters control which columns are read and written, and from accepts an array when you want to combine multiple columns:

#[Sluggable(from: ['first_name', 'last_name'], to: 'slug')]
class Author extends Model {}
 
$author = Author::create(['first_name' => 'John', 'last_name' => 'Tolkien']);
$author->slug; // "john-tolkien"

For multi-tenant apps or anything with per-scope uniqueness, pass a scope column (or an array of columns):

#[Sluggable(from: 'title', scope: 'team_id')]

Other notable options include maxLength to cap slug length, separator to swap out the dash, and onUpdating to regenerate the slug whenever the source column changes. By default, slugs are locked after creation — manually assigned slug values are always preserved regardless of this setting.

Error Handling

If a slug cannot be generated, the package throws a CouldNotGenerateSlugException. In HTTP contexts, it automatically renders as a 422 response with a validation-style error payload, so it drops into existing error handling without extra work. The error key defaults to the source column name but can be overridden via errorKey. Because it extends ValidationException, it won't show up in your application logs.

Unicode Support

The pipeline transliterates non-Latin scripts to readable Latin slugs and is domain-aware — values that look like hostnames or file paths keep their dots intact instead of being collapsed to dashes.

You can learn more about Laravel Sluggable on the projects GitHub repo.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Sponsored

tinkerwell logo
Tinkerwell

Enjoy coding and debugging in an editor designed for fast feedback and quick iterations. It's like a shell for your application – but with multi-line editing, code completion, and more.

Visit Tinkerwell

The latest

View all →
CPX: The Composer Package Executor for PHP image

CPX: The Composer Package Executor for PHP

Read article
Laravel AI SDK Adds Human-in-the-Loop Tool Approval image

Laravel AI SDK Adds Human-in-the-Loop Tool Approval

Read article
Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals image

Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals

Read article
Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs image

Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs

Read article
Blade Formatting in Laravel Pint image

Blade Formatting in Laravel Pint

Read article
Inertia DevTools Is Now on the Chrome Web Store image

Inertia DevTools Is Now on the Chrome Web Store

Read article