actengage/sluggable

A simple trait to ensure Laravel models have slugs.

Maintainers

Package info

github.com/actengage/sluggable

pkg:composer/actengage/sluggable

Statistics

Installs: 1 708

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v7.0.1 2026-03-17 19:27 UTC

README

A simple package for managing "slugs" on Eloquent models. Sluggable is a trait for Eloquent models to ensure a slug exists for the model and is saved in a column.

Installation

composer require actengage/sluggable

Implementation

Add the Sluggable trait to your model.

namespace App\Models;

use Actengage\Sluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    use Sluggable;

    protected $fillable = [
        'title', 'slug',
    ];
}

Basic Example

$page = Page::create([
    'title' => 'This is some title',
]);

$page->slug; // 'this-is-some-title'

PHP Attributes

You can use PHP attributes to declaratively configure sluggable behavior instead of overriding methods.

#[Slug] — Set the qualifier

The qualifier is the model attribute used to generate the slug. Defaults to title.

use Actengage\Sluggable\Slug;

#[Slug('name')]
class Product extends Model
{
    use Sluggable;
}

#[SlugAttribute] — Set the slug column

The column where the slug is stored. Defaults to slug.

use Actengage\Sluggable\SlugAttribute;

#[SlugAttribute('url_slug')]
class Product extends Model
{
    use Sluggable;
}

#[SlugDelimiter] — Set the delimiter

The character used to separate words in the slug. Defaults to -.

use Actengage\Sluggable\SlugDelimiter;

#[SlugDelimiter('_')]
class Product extends Model
{
    use Sluggable;
}

#[PreventDuplicateSlugs] — Control duplicate prevention

By default, duplicate slugs are prevented by appending an incrementing number. Use this attribute to disable that behavior.

use Actengage\Sluggable\PreventDuplicateSlugs;

#[PreventDuplicateSlugs(false)]
class Product extends Model
{
    use Sluggable;
}

Combining attributes

use Actengage\Sluggable\PreventDuplicateSlugs;
use Actengage\Sluggable\Slug;
use Actengage\Sluggable\SlugAttribute;
use Actengage\Sluggable\SlugDelimiter;

#[Slug('name')]
#[SlugAttribute('url_slug')]
#[SlugDelimiter('_')]
#[PreventDuplicateSlugs(false)]
class Product extends Model
{
    use Sluggable;
}

Finding by Slug

$page = Page::findBySlug('this-is-some-title');

Slug Scope

$page = Page::slug('this-is-some-title')->first();

Duplicate Slug Prevention

By default, Sluggable prevents duplicate slugs by appending an incrementing number.

Page::create(['title' => 'test']); // slug: 'test'
Page::create(['title' => 'test']); // slug: 'test-1'
Page::create(['title' => 'test']); // slug: 'test-2'

This can be disabled with the #[PreventDuplicateSlugs] attribute or by setting the property on the model:

class Page extends Model
{
    use Sluggable;

    protected $preventDuplicateSlugs = false;
}

Publishing a New Release

This package uses changesets for automated versioning and releases.

  1. Create a branch and make your changes
  2. Add a changeset describing the change:
    pnpm changeset
    
    Select the bump level (patch, minor, or major) and write a summary. See the changeset skill for semver rules specific to this package.
  3. Open a PR — CI runs Pint, PHPStan, Rector, and Pest
  4. Merge the PR — the release workflow creates a "Version Packages" PR that bumps the version in package.json and updates CHANGELOG.md
  5. Review and merge the "Version Packages" PR — a git tag and GitHub Release are created automatically