PHPackages                             sibche/eloquent-sluggable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. sibche/eloquent-sluggable

ActiveLibrary[Database &amp; ORM](/categories/database)

sibche/eloquent-sluggable
=========================

Easy creation of slugs for your Eloquent models in Laravel 5.

6.0.2(6y ago)0467MITPHPPHP ^7.2

Since Jun 11Pushed 5y agoCompare

[ Source](https://github.com/sibche/eloquent-sluggable)[ Packagist](https://packagist.org/packages/sibche/eloquent-sluggable)[ Docs](https://github.com/cviebrock/eloquent-sluggable)[ RSS](/packages/sibche-eloquent-sluggable/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (9)Versions (59)Used By (0)

Eloquent-Sluggable
==================

[](#eloquent-sluggable)

Easy creation of slugs for your Eloquent models in Laravel.

> **NOTE**: These instructions are for Laravel 5.8. If you are using Laravel 5.7, please see the [previous version's docs](https://github.com/cviebrock/eloquent-sluggable/tree/4.7.0).

[![Build Status](https://camo.githubusercontent.com/d3e2c9487d83ac7d87296d45b9323254334274deec7f409e460d8a619ab56595/68747470733a2f2f7472617669732d63692e6f72672f6376696562726f636b2f656c6f7175656e742d736c75676761626c652e7376673f6272616e63683d6d617374657226666f726d61743d666c6174)](https://travis-ci.org/cviebrock/eloquent-sluggable)[![Total Downloads](https://camo.githubusercontent.com/58e6fff5c5ac3d8606ee05ec1486ee1931ffa7d014e2935ddc23975c2f81e307/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d736c75676761626c652f646f776e6c6f6164733f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-sluggable)[![Latest Stable Version](https://camo.githubusercontent.com/2c6cbc83c46cfefb9aa938898da85876ecef43150160932633826d2b3594ac40/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d736c75676761626c652f762f737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-sluggable)[![Latest Unstable Version](https://camo.githubusercontent.com/c8cb7f0de8430a75c0578c538ca89dd9fa0c72477a781755ef8b912d8f115dbb/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d736c75676761626c652f762f756e737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-sluggable)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/ed6ff08ae66bc65ce55447c783c91a080a378bf661b5e7da8f447451feae8f18/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6376696562726f636b2f656c6f7175656e742d736c75676761626c652f6261646765732f7175616c6974792d73636f72652e706e673f666f726d61743d666c6174)](https://scrutinizer-ci.com/g/cviebrock/eloquent-sluggable)[![SensioLabsInsight](https://camo.githubusercontent.com/5058a32c46c8195ffadf9ffda34a99d1fc2ed04407a266937810e72004768c00/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f30623936366531332d366136612d346431372d626365612d3631303337663034636665372f6d696e692e706e67)](https://insight.sensiolabs.com/projects/0b966e13-6a6a-4d17-bcea-61037f04cfe7)[![License: MIT](https://camo.githubusercontent.com/c2bffd81d308ced1cc3b0d66fb0ed453ab478a5e17c988b780f9de986a390ee2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://opensource.org/licenses/MIT)

- [Background: What is a slug](#background-what-is-a-slug)
- [Installation](#installation)
- [Updating your Eloquent Models](#updating-your-eloquent-models)
- [Usage](#usage)
- [The SlugService Class](#the-slugservice-class)
- [Events](#events)
- [Configuration](#configuration)
    - [includeTrashed](#includetrashed)
    - [maxLength](#maxlength)
    - [maxLengthKeepWords](#maxlengthkeepwords)
    - [method](#method)
    - [onUpdate](#onupdate)
    - [reserved](#reserved)
    - [separator](#separator)
    - [source](#source)
    - [unique](#unique)
    - [uniqueSuffix](#uniquesuffix)
- [Extending Sluggable](#extending-sluggable)
    - [customizeSlugEngine](#customizeslugengine)
    - [scopeWithUniqueSlugConstraints](#scopewithuniqueslugconstraints)
    - [scopeFindSimilarSlugs](#scopefindsimilarslugs)
- [SluggableScopeHelpers Trait](#sluggablescopehelpers-trait)
- [Route Model Binding](#route-model-binding)
- [Bugs, Suggestions, Contributions and Support](#bugs-suggestions-contributions-and-support)
- [Copyright and License](#copyright-and-license)

Background: What is a slug?
---------------------------

[](#background-what-is-a-slug)

A slug is a simplified version of a string, typically URL-friendly. The act of "slugging" a string usually involves converting it to one case, and removing any non-URL-friendly characters (spaces, accented letters, ampersands, etc.). The resulting string can then be used as an identifier for a particular resource.

For example, if you have a blog with posts, you could refer to each post via the ID:

```
http://example.com/post/1
http://example.com/post/2

```

... but that's not particularly friendly (especially for [SEO](http://en.wikipedia.org/wiki/Search_engine_optimization)). You probably would prefer to use the post's title in the URL, but that becomes a problem if your post is titled "My Dinner With André &amp; François", because this is pretty ugly too:

```
http://example.com/post/My+Dinner+With+Andr%C3%A9+%26+Fran%C3%A7ois

```

The solution is to create a slug for the title and use that instead. You might want to use Laravel's built-in `Str::slug()` method to convert that title into something friendlier:

```
http://example.com/post/my-dinner-with-andre-francois

```

A URL like that will make users happier (it's readable, easier to type, etc.).

For more information, you might want to read [this](http://en.wikipedia.org/wiki/Slug_(web_publishing)#Slug) description on Wikipedia.

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

```
http://example.com/post/my-dinner-with-andre-francois
http://example.com/post/my-dinner-with-andre-francois-1
http://example.com/post/my-dinner-with-andre-francois-2

```

This keeps the URLs unique.

The **Eloquent-Sluggable** package for Laravel 5 aims to handle all of this for you automatically, with minimal configuration.

Installation
------------

[](#installation)

> **NOTE**: Depending on your version of Laravel, you should install a different version of the package:
>
> Laravel VersionPackage Version5.84.8.\*5.74.6.\*5.64.5.\*5.54.3.\*5.44.2.\*Older versions of Laravel can use older versions of the package, although they are no longer supported or maintained. See [CHANGELOG.md](CHANGELOG.md) and [UPGRADING.md](UPGRADING.md) for specifics, and be sure that you are reading the correct README.md for your version (Github displays the version in the *master* branch by default, which might not be what you want).

1. Install the package via Composer:

    ```
    $ composer require cviebrock/eloquent-sluggable:^4.8
    ```

    The package will automatically register its service provider.
2. Optionally, publish the configuration file if you want to change any defaults:

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

Updating your Eloquent Models
-----------------------------

[](#updating-your-eloquent-models)

Your models should use the Sluggable trait, which has an abstract method `sluggable()`that you need to define. This is where any model-specific configuration is set (see [Configuration](#configuration) below for details):

```
use Cviebrock\EloquentSluggable\Sluggable;

class Post extends Model
{
    use Sluggable;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}
```

Of course, your model and database will need a column in which to store the slug. You can use `slug` or any other appropriate name you want; your configuration array will determine to which field the data will be stored. You will need to add the column manually via your own migration.

That's it ... your model is now "sluggable"!

Usage
-----

[](#usage)

Saving a model is easy:

```
$post = new Post([
    'title' => 'My Awesome Blog Post',
]);

$post->save();
```

And so is retrieving the slug:

```
echo $post->slug;
```

Also note that if you are replicating your models using Eloquent's `replicate()` method, the package will automatically re-slug the model afterwards to ensure uniqueness.

```
$post = new Post([
    'title' => 'My Awesome Blog Post',
]);

$post->save();
// $post->slug is "my-awesome-blog-post"

$newPost = $post->replicate();
// $newPost->slug is "my-awesome-blog-post-1"
```

Note that empty strings, non-strings or other "odd" source values will result in different slugs:

Source ValueResulting Slugstringstringempty string*no slug will be set*`null`*no slug will be set*`0``"0"``1``"1"``false``"0"``true``"1"`(The above values would be subject to any unique or other checks as well.)

The SlugService Class
---------------------

[](#the-slugservice-class)

All the logic to generate slugs is handled by the `\Cviebrock\EloquentSluggable\Services\SlugService` class.

Generally, you don't need to access this class directly, although there is one static method that can be used to generate a slug for a given string without actually creating or saving an associated model.

```
use \Cviebrock\EloquentSluggable\Services\SlugService;

$slug = SlugService::createSlug(Post::class, 'slug', 'My First Post');
```

This would be useful for Ajax-y controllers or the like, where you want to show a user what the unique slug *would* be for a given test input, before actually creating a model. The first two arguments to the method are the model and slug field being tested, and the third argument is the source string to use for testing the slug.

You can also pass an optional array of configuration values as the fourth argument. These will take precedence over the normal configuration values for the slug field being tested. For example, if your model is configured to use unique slugs, but you want to generate the "base" version of a slug for some reason, you could do:

```
$slug = SlugService::createSlug(Post::class, 'slug', 'My First Post', ['unique' => false]);
```

Events
------

[](#events)

> **NOTE:** Events should be working but are not fully tested yet. [Please help me out!](#bugs-suggestions-and-contributions)

Sluggable models will fire two Eloquent model events: "slugging" and "slugged".

The "slugging" event is fired just before the slug is generated. If the callback from this event returns false, then the slugging is not performed.

The "slugged" event is fired just after a slug is generated. It won't be called in the case where the model doesn't need slugging (as determined by the `needsSlugging()`method).

You can hook into either of these events just like any other Eloquent model event:

```
Post::registerModelEvent('slugging', function($post) {
    if ($post->someCondition()) {
        // the model won't be slugged
        return false;
    }
});

Post::registerModelEvent('slugged', function($post) {
    Log::info('Post slugged: ' . $post->getSlug());
});
```

Configuration
-------------

[](#configuration)

Configuration was designed to be as flexible as possible. You can set up defaults for all of your Eloquent models, and then override those settings for individual models.

By default, global configuration is set in the `app/config/sluggable.php` file. If a configuration isn't set, then the package defaults are used. Here is an example configuration, with all the default settings shown:

```
return [
    'source'             => null,
    'maxLength'          => null,
    'maxLengthKeepWords' => true,
    'method'             => null,
    'separator'          => '-',
    'unique'             => true,
    'uniqueSuffix'       => null,
    'includeTrashed'     => false,
    'reserved'           => null,
    'onUpdate'           => false,
];
```

For individual models, configuration is handled in the `sluggable()` method that you need to implement. That method should return an indexed array where the keys represent the fields where the slug value is stored and the values are the configuration for that field. This means you can create multiple slugs for the same model, based on different source strings and with different configuration options.

```
public function sluggable()
{
    return [
        'title-slug' => [
            'source' => 'title'
        ],
        'author-slug' => [
            'source' => ['author.lastname', 'author.firstname'],
            'separator' => '_'
        ],
    ];
}
```

### source

[](#source)

This is the field or array of fields from which to build the slug. Each `$model->field`is concatenated (with space separation) to build the sluggable string. These can be model attributes (i.e. fields in the database), relationship attributes, or custom getters.

To reference fields from related models, use dot-notation. For example, the slug for the following book will be generated from its author's name and the book's title:

```
class Book extends Eloquent
{
    use Sluggable;

    protected $fillable = ['title'];

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

    public function author() {
        return $this->belongsTo(Author::class);
    }
}
...
class Author extends Eloquent
{
    protected $fillable = ['name'];
}
```

An example using a custom getter:

```
class Person extends Eloquent
{
    use Sluggable;

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

    public function getFullnameAttribute() {
        return $this->firstname . ' ' . $this->lastname;
    }
}
```

If `source` is empty, false or null, then the value of `$model->__toString()` is used as the source for slug generation.

### maxLength

[](#maxlength)

Setting this to a positive integer will ensure that your generated slugs are restricted to a maximum length (e.g. to ensure that they fit within your database fields). By default, this value is null and no limit is enforced.

Note: If `unique` is enabled (which it is by default), and you anticipate having several models with the same slug, then you should set this value to a few characters less than the length of your database field. The reason why is that the class will append "-1", "-2", "-3", etc., to subsequent models in order to maintain uniqueness. These incremental extensions aren't included in part of the `maxLength` calculation.

### maxLengthKeepWords

[](#maxlengthkeepwords)

If you are truncating your slugs with the `maxLength` setting, than you probably want to ensure that your slugs don't get truncated in the middle of a word. For example, if your source string is "My First Post", and your `maxLength` is 10, the generated slug would end up being "my-first-p", which isn't ideal.

By default, the `maxLengthKeepWords` value is set to true which would trim the partial words off the end of the slug, resulting in "my-first" instead of "my-first-p".

If you want to keep partial words, then set this configuration to false.

### method

[](#method)

Defines the method used to turn the sluggable string into a slug. There are three possible options for this configuration:

1. When `method` is null (the default setting), the package uses the default slugging engine -- [cocur/slugify](https://github.com/cocur/slugify) -- to create the slug.
2. When `method` is a callable, then that function or class method is used. The function/method should expect two parameters: the string to process, and a separator string. For example, to use Laravel's `Str::slug`, you could do:

```
'method' => ['Illuminate\\Support\\Str', 'slug'],
```

3. You can also define `method` as a closure (again, expecting two parameters):

```
'method' => function ($string, $separator) {
    return strtolower(preg_replace('/[^a-z]+/i', $separator, $string));
},
```

Any other values for `method` will throw an exception.

For more complex slugging requirements, see [Extending Sluggable](#extending-sluggable) below.

### onUpdate

[](#onupdate)

By default, updating a model will not try and generate a new slug value. It is assumed that once your slug is generated, you won't want it to change (this may be especially true if you are using slugs for URLs and don't want to mess up your SEO mojo).

If you want to regenerate one or more of your model's slug fields, you can set those fields to null or an empty string before the update:

```
$post->slug = null;
$post->update(['title' => 'My New Title']);
```

If this is the behaviour you want every time you update a model, then set the `onUpdate`option to true.

### separator

[](#separator)

This defines the separator used when building a slug, and is passed to the `method`defined above. The default value is a hyphen.

### unique

[](#unique)

This is a boolean defining whether slugs should be unique among all models of the given type. For example, if you have two blog posts and both are called "My Blog Post", then they will both sluggify to "my-blog-post" if `unique` is false. This could be a problem, e.g. if you use the slug in URLs.

By setting `unique` to true, then the second Post model will sluggify to "my-blog-post-1". If there is a third post with the same title, it will sluggify to "my-blog-post-2" and so on. Each subsequent model will get an incremental value appended to the end of the slug, ensuring uniqueness.

### uniqueSuffix

[](#uniquesuffix)

If you want to use a different way of identifying uniqueness (other than auto-incrementing integers), you can set the `uniqueSuffix` configuration to a function or callable that generates the "unique" values for you.

The function should take three parameters: the base slug (i.e. the non-unique slug), the separator string, and an `\Illuminate\Support\Collection` of all the other slug strings that start with the same slug. You can then do whatever you want to create a new suffix that hasn't been used by any of the slugs in the collection. For example, if you wanted to use letters instead of numbers as a suffix, this is one way to achieve that:

```
'uniqueSuffix' => function ($slug, $separator, Collection $list) {
    $size = count($list);

    return chr($size + 96);
}
```

### includeTrashed

[](#includetrashed)

Setting this to `true` will also check deleted models when trying to enforce uniqueness. This only affects Eloquent models that are using the [softDelete](http://laravel.com/docs/eloquent#soft-deleting) feature. Default is `false`, so soft-deleted models don't count when checking for uniqueness.

### reserved

[](#reserved)

An array of values that will never be allowed as slugs, e.g. to prevent collisions with existing routes or controller methods, etc.. This can be an array, or a closure that returns an array. Defaults to `null`: no reserved slug names.

Short Configuration
-------------------

[](#short-configuration)

The package supports a really short configuration syntax, if you are truly lazy:

```
public function sluggable() {
    return [
        'slug'
    ];
}
```

This will use all the default options from `app/config/sluggable.php`, use the model's `__toString()` method as the source, and store the slug in the `slug` field.

Extending Sluggable
-------------------

[](#extending-sluggable)

Sometimes the configuration options aren't sufficient for complex needs (e.g. maybe the uniqueness test needs to take other attributes into account).

In instances like these, the package offers hooks into the slugging workflow where you can use your own functions, either on a per-model basis, or in your own trait that extends the package's trait.

### customizeSlugEngine

[](#customizeslugengine)

```
/**
 * @param \Cocur\Slugify\Slugify $engine
 * @param string $attribute
 * @return \Cocur\Slugify\Slugify
 */
public function customizeSlugEngine(Slugify $engine, $attribute)
{
    ...
}
```

If this method exists on your model, the Slugify engine can be customized before slugging occurs. This might be where you change the character mappings that are used, or alter language files, etc..

You can customize the engine on a per-model and per-attribute basis (maybe your model has two slug fields, and one of them needs customization).

Take a look at `tests/Models/PostWithCustomEngine.php` for an example.

### scopeWithUniqueSlugConstraints

[](#scopewithuniqueslugconstraints)

```
/**
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @param \Illuminate\Database\Eloquent\Model $model
 * @param string $attribute
 * @param array $config
 * @param string $slug
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeWithUniqueSlugConstraints(Builder $query, Model $model, $attribute, $config, $slug)
{
    ...
}
```

If this scope exists on your model, then it will also be applied to the query used to determine if a given slug is unique. The arguments passed to the scope are:

- `$model` -- the object being slugged
- `$attribute` -- the slug field being generated,
- `$config` -- the configuration array for the given model and attribute
- `$slug` -- the "base" slug (before any unique suffixes are applied)

Feel free to use these values anyway you like in your query scope. As an example, look at `tests/Models/PostWithUniqueSlugConstraints.php` where the slug is generated for a post from it's title, but the slug is scoped to the author. So Bob can have a post with the same title as Pam's post, but both will have the same slug.

### scopeFindSimilarSlugs

[](#scopefindsimilarslugs)

```
/**
 * Query scope for finding "similar" slugs, used to determine uniqueness.
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @param string $attribute
 * @param array $config
 * @param string $slug
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeFindSimilarSlugs(Builder $query, $attribute, $config, $slug)
{
    ...
}
```

This is the default scope for finding "similar" slugs for a model. Basically, the package looks for existing slugs that are the same as the `$slug` argument, or that start with `$slug` plus the separator string. The resulting collection is what is passed to the `uniqueSuffix` handler.

Generally, this query scope (which is defined in the Sluggable trait) should be left alone. However, you are free to overload it in your models.

SluggableScopeHelpers Trait
---------------------------

[](#sluggablescopehelpers-trait)

Adding the optional `SluggableScopeHelpers` trait to your model allows you to work with models and their slugs. For example:

```
$post = Post::whereSlug($slugString)->get();

$post = Post::findBySlug($slugString);

$post = Post::findBySlugOrFail($slugString);
```

Because models can have more than one slug, this requires a bit more configuration. See [SCOPE-HELPERS.md](SCOPE-HELPERS.md) for all the details.

Route Model Binding
-------------------

[](#route-model-binding)

See [ROUTE-MODEL-BINDING.md](ROUTE-MODEL-BINDING.md) for details.

Bugs, Suggestions, Contributions and Support
--------------------------------------------

[](#bugs-suggestions-contributions-and-support)

Thanks to [everyone](https://github.com/cviebrock/eloquent-taggable/graphs/contributors)who has contributed to this project! Special thanks to [JetBrains](https://www.jetbrains.com/?from=cviebrock/eloquent-sluggable) for their Open Source License Program ... and the excellent PHPStorm IDE, of course!

[![JetBrains](./.github/jetbrains.svg)](https://www.jetbrains.com/?from=cviebrock/eloquent-sluggable)

Please use [Github](https://github.com/cviebrock/eloquent-sluggable) for reporting bugs, and making comments or suggestions.

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute changes.

Copyright and License
---------------------

[](#copyright-and-license)

[eloquent-sluggable](https://github.com/cviebrock/eloquent-sluggable)was written by [Colin Viebrock](http://viebrock.ca) and is released under the [MIT License](LICENSE.md).

Copyright (c) 2013 Colin Viebrock

###  Health Score

33

—

LowBetter than 74% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 86.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~48 days

Recently: every ~110 days

Total

57

Last Release

1986d ago

Major Versions

1.0.8 → 2.0.02014-04-28

2.0.5 → 3.0.0-alpha2015-02-11

3.1.4 → 4.0.0-beta2016-06-01

2.x-dev → 4.0.02016-06-10

4.8.x-dev → 6.0.02019-09-04

PHP version history (10 changes)1.0.0-alpha3PHP &gt;=5.3.0

2.0.0PHP &gt;=5.4.0

3.1.4PHP &gt;=5.5

4.0.0PHP ^5.5.9 || ^7.0

4.1.0PHP ^5.6 || ^7.0

4.2.1PHP &gt;=5.6.4 || ^7.0

4.3.0PHP ^7.0

4.8.0PHP ^7.1

6.0.0PHP ^7.2

4.9.1PHP ^7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/fa72ec88ecd099cdcc983cf4e8f3137c61b2832630a7c6ba4684ad17faf56b2f?d=identicon)[roboticsexpert](/maintainers/roboticsexpert)

---

Top Contributors

[![cviebrock](https://avatars.githubusercontent.com/u/166810?v=4)](https://github.com/cviebrock "cviebrock (375 commits)")[![Keoghan](https://avatars.githubusercontent.com/u/6714599?v=4)](https://github.com/Keoghan "Keoghan (10 commits)")[![hannesvdvreken](https://avatars.githubusercontent.com/u/1410358?v=4)](https://github.com/hannesvdvreken "hannesvdvreken (6 commits)")[![maddhatter](https://avatars.githubusercontent.com/u/4449339?v=4)](https://github.com/maddhatter "maddhatter (4 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (4 commits)")[![haddowg](https://avatars.githubusercontent.com/u/10784397?v=4)](https://github.com/haddowg "haddowg (4 commits)")[![roboticsexpert](https://avatars.githubusercontent.com/u/9366277?v=4)](https://github.com/roboticsexpert "roboticsexpert (3 commits)")[![artrz](https://avatars.githubusercontent.com/u/2359890?v=4)](https://github.com/artrz "artrz (2 commits)")[![GregPeden](https://avatars.githubusercontent.com/u/1343049?v=4)](https://github.com/GregPeden "GregPeden (2 commits)")[![nicolasbinet](https://avatars.githubusercontent.com/u/867710?v=4)](https://github.com/nicolasbinet "nicolasbinet (2 commits)")[![phroggyy](https://avatars.githubusercontent.com/u/7256451?v=4)](https://github.com/phroggyy "phroggyy (2 commits)")[![Sleavely](https://avatars.githubusercontent.com/u/677030?v=4)](https://github.com/Sleavely "Sleavely (2 commits)")[![unstoppablecarl](https://avatars.githubusercontent.com/u/913047?v=4)](https://github.com/unstoppablecarl "unstoppablecarl (2 commits)")[![mylgeorge](https://avatars.githubusercontent.com/u/12344433?v=4)](https://github.com/mylgeorge "mylgeorge (1 commits)")[![phpguru](https://avatars.githubusercontent.com/u/798500?v=4)](https://github.com/phpguru "phpguru (1 commits)")[![skyrpex](https://avatars.githubusercontent.com/u/1077520?v=4)](https://github.com/skyrpex "skyrpex (1 commits)")[![303K](https://avatars.githubusercontent.com/u/3934941?v=4)](https://github.com/303K "303K (1 commits)")[![xcopy](https://avatars.githubusercontent.com/u/202339?v=4)](https://github.com/xcopy "xcopy (1 commits)")[![39digits](https://avatars.githubusercontent.com/u/719731?v=4)](https://github.com/39digits "39digits (1 commits)")[![alnutile](https://avatars.githubusercontent.com/u/365385?v=4)](https://github.com/alnutile "alnutile (1 commits)")

---

Tags

sluglaravellumeneloquentsluggableeloquent-sluggable

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sibche-eloquent-sluggable/health.svg)

```
[![Health](https://phpackages.com/badges/sibche-eloquent-sluggable/health.svg)](https://phpackages.com/packages/sibche-eloquent-sluggable)
```

###  Alternatives

[cviebrock/eloquent-sluggable

Easy creation of slugs for your Eloquent models in Laravel

4.0k13.6M251](/packages/cviebrock-eloquent-sluggable)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[cviebrock/eloquent-taggable

Easy ability to tag your Eloquent models in Laravel.

567694.8k3](/packages/cviebrock-eloquent-taggable)[cybercog/laravel-love

Make Laravel Eloquent models reactable with any type of emotions in a minutes!

1.2k302.7k1](/packages/cybercog-laravel-love)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)[veelasky/laravel-hashid

HashId Implementation on Laravel Eloquent ORM

46168.5k3](/packages/veelasky-laravel-hashid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
