PHPackages                             levintoo/self-healing-urls - 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. levintoo/self-healing-urls

ActiveLibrary

levintoo/self-healing-urls
==========================

1.0.0(12mo ago)05MITPHPPHP ^8.1|^8.2|^8.3|^8.4CI passing

Since May 15Pushed 12mo agoCompare

[ Source](https://github.com/levintoo/self-healing-urls)[ Packagist](https://packagist.org/packages/levintoo/self-healing-urls)[ RSS](/packages/levintoo-self-healing-urls/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (4)Versions (2)Used By (0)

Self Healing URLs
=================

[](#self-healing-urls)

> This package was originally written by [Luke Downing](https://github.com/lukeraymonddowning).

Self Healing URLs is a simple Laravel package inspired by [this video from Aaron Francis](https://www.youtube.com/watch?v=a6lnfyES-LA&t=554s).

It allows you to mark Eloquent models as self-healing so that the URLs generated for said models can include an SEO friendly slug whilst not breaking should the slug alter in any way.

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

[](#installation)

The package can be installed via Composer:

```
composer require levintoo/self-healing-urls

```

Once installed, add the `HasSelfHealingUrls` trait to any Eloquent model:

```
use Levintoo\SelfHealingUrls\Concerns\HasSelfHealingUrls;

class Post extends Model
{
    use HasSelfHealingUrls;
}
```

If your model has a column named `slug`, you're all set. Otherwise, define a `$slug` property on your model to inform the package which column to use instead:

```
use Levintoo\SelfHealingUrls\Concerns\HasSelfHealingUrls;

class Post extends Model
{
    use HasSelfHealingUrls;

    protected $slug = 'title';
}
```

Don't worry if your "slug" isn't URL friendly; the package will take care of formatting it for you. In fact, it doesn't even have to be unique because the defined unique identifier for your model will also be included at the end.

Limitations
-----------

[](#limitations)

By default, the package requires that your unique identifier (such as the `id` or `uuid` column) not have any `-` characters. You can implement your own `IdentifierHandler` as detailed in the next section.

Unless you implement a custom `Rerouter`, the package requires that you have defined names to the routes you want to use with self healing URLs.

Using a custom `IdentifierHandler`
----------------------------------

[](#using-a-custom-identifierhandler)

If you need to customize how a slug is joined to a model identifier (which by default is just a hyphen), you can create your own class implementing `IdentifierHandler` and register it in the register method of your `AppServiceProvider`.

Here is an example using an `_` instead of a hyphen:

```
class UnderscoreIdentifierHandler implements IdentifierHandler
{
    public function joinToSlug(string $slug, string|int $identifier): string
    {
        return "{$slug}_{$identifier}";
    }

    public function separateFromSlug(string $value): string
    {
        return Str::afterLast($value, '_');
    }
}
```

Register the custom handler in your `AppServiceProvider` like so:

```
class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(IdentifierHandler::class, UnderscoreIdentifierHandler::class);
    }
}
```

Attributions
------------

[](#attributions)

Without [Aaron's video](https://www.youtube.com/watch?v=a6lnfyES-LA&t=554s), I wouldn't have even thought about this, so props to him. Go watch the video.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance50

Moderate activity, may be stable

Popularity4

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% 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

Unknown

Total

1

Last Release

360d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/23132a4c3a6cf3be2b5a0cd7b5ad9ad86199a5cbf6e9c2a23578ddfe100583b3?d=identicon)[levintoo](/maintainers/levintoo)

---

Top Contributors

[![lukeraymonddowning](https://avatars.githubusercontent.com/u/12202279?v=4)](https://github.com/lukeraymonddowning "lukeraymonddowning (24 commits)")[![levintoo](https://avatars.githubusercontent.com/u/44953808?v=4)](https://github.com/levintoo "levintoo (2 commits)")[![imanghafoori1](https://avatars.githubusercontent.com/u/6961695?v=4)](https://github.com/imanghafoori1 "imanghafoori1 (2 commits)")[![YonkoSam](https://avatars.githubusercontent.com/u/161728760?v=4)](https://github.com/YonkoSam "YonkoSam (1 commits)")[![Lakshan-Madushanka](https://avatars.githubusercontent.com/u/47297673?v=4)](https://github.com/Lakshan-Madushanka "Lakshan-Madushanka (1 commits)")[![ju-gow](https://avatars.githubusercontent.com/u/5887244?v=4)](https://github.com/ju-gow "ju-gow (1 commits)")[![alexjustesen](https://avatars.githubusercontent.com/u/1144087?v=4)](https://github.com/alexjustesen "alexjustesen (1 commits)")

---

Tags

package

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/levintoo-self-healing-urls/health.svg)

```
[![Health](https://phpackages.com/badges/levintoo-self-healing-urls/health.svg)](https://phpackages.com/packages/levintoo-self-healing-urls)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[namu/wirechat

A Laravel Livewire messaging app for teams with private chats and group conversations.

54324.5k](/packages/namu-wirechat)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135192.6k5](/packages/statamic-rad-pack-runway)

PHPackages © 2026

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