---
title: "The Slugs facade — Sluggable for Laravel | Roundly"
description: "One entry point for everything that is not a model hook — flat verbs for one model, and Slugs::model(Product::class) for class-wide work."
url: https://roundly-consulting.com/open-source/docs/sluggable-for-laravel/facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Sluggable for Laravel](https://roundly-consulting.com/open-source/docs/sluggable-for-laravel.md)

# The Slugs facade

The Slugs facade is the one entry point for everything that is not a model hook: flat verbs for text and a single model, and Slugs::model(Product::class) — a class name or its morph alias — for class-wide backfills, audits, indexes and history lookups:

```php
use RoundlyConsulting\Sluggable\Enums\RegenerationMode;
use RoundlyConsulting\Sluggable\Facades\Slugs;

// Text and one model
Slugs::slugify('Žltý kôň @ home', language: 'sk');     // 'zlty-kon-at-home'
Slugs::generate($product, column: 'slug');              // the value it would get; sets nothing
Slugs::apply($product);                                 // run the save-time pass now (before saveQuietly/imports)
Slugs::recompute($product, columns: ['slug']);          // recompute from the sources; you save
Slugs::regenerate($product, columns: ['slug']);         // recompute + save
Slugs::withoutGeneration(fn () => $importer->run());    // nestable, exception-safe toggles
Slugs::unlocked(fn () => $product->update(['slug' => 'new']));
Slugs::locales();                                       // SlugLocales

// A whole model class (a class name or its morph alias)
$products = Slugs::model(Product::class);
$products->regenerate(mode: RegenerationMode::Stale, dryRun: true);   // RegenerationReport
$products->regenerate(mode: RegenerationMode::Missing, withHistory: true, columns: ['slug']);
$products->queueRegeneration(mode: RegenerationMode::All, chunk: 1000); // jobs dispatched (int)
$products->duplicates(column: 'slug', locale: 'sk');   // list<SlugDuplicate> a unique index would reject
$products->indexes(dryRun: true);                      // SlugIndexReport: the DDL, nothing executed
$products->indexes();                                  // create the missing engine-native indexes
$products->findInHistory('old-name', locale: 'sk');    // the row that retired a slug, or null
$products->options();                                  // ResolvedSlugOptions
```

## Flat methods

| Method | Purpose |
| --- | --- |
| `slugify(string $text, ?string $language = null, ?string $separator = null): string` | The pipeline with the configured defaults. |
| `generate(Model $model, ?string $column = null, ?string $locale = null): string` | The unique value the model would get; sets nothing. |
| `apply(Model $model, ?array $columns = null, ?array $locales = null): SlugGenerationResult` | Run the save-time pass now (before saveQuietly() or imports). |
| `recompute(Model $model, ?array $columns = null, ?array $locales = null): SlugGenerationResult` | Recompute from the sources on the instance; you save. |
| `regenerate(Model $model, ?array $columns = null, ?array $locales = null): Model` | recompute() + save(). |
| `model(string $model): ModelSlugs` | Class-wide work for a class name or morph alias (below). |
| `withoutGeneration(Closure $callback): mixed` | Hooks off (nestable, exception-safe). |
| `unlocked(Closure $callback): mixed` | Bypass locks. |
| `isGenerationEnabled(): bool, isUnlocked(): bool` | Toggle state. |
| `locales(): SlugLocales` | The bound locale source. |

## Class-wide: Slugs::model()

| Method | Purpose |
| --- | --- |
| `regenerate(mode, dryRun, withHistory, columns, locales, chunk, withoutEvents, force): RegenerationReport` | Backfill or recompute the whole class — the same options as sluggable:regenerate. |
| `queueRegeneration(mode, withHistory, columns, locales, chunk, withoutEvents, force): int` | Dispatch one RegenerateSlugsJob per chunk; returns the job count. |
| `duplicates(?string $column = null, ?string $locale = null): array` | list<SlugDuplicate> a unique index would reject. |
| `indexes(bool $dryRun = false, ?array $columns = null): SlugIndexReport` | Create the missing engine-native indexes, or only plan them. |
| `findInHistory(string $slug, ?string $column = null, ?string $locale = null, Builder\|Relation\|null $within = null): ?Model` | The row that retired a slug, through the default or the given query. |
| `options(): ResolvedSlugOptions` | The resolved definitions. |

- regenerate() and queueRegeneration() scan rows without global scopes; each changed row is saved normally, so history and events apply. mode takes a RegenerationMode — Missing (default), Stale or All.
- findInHistory() resolves through the model’s default query (global scopes applied) or the query you pass as within — a retired slug never reveals a row that query would not return.
- Each Artisan command is the same call: sluggable:regenerate, :indexes and :duplicates run model()->regenerate() / queueRegeneration(), indexes() and duplicates().

The toggles are depth counters released in finally blocks — nestable, exception-safe and never left set between Octane requests. On a model, $model->regenerateSlugs() is Slugs::recompute($model) from the model side: it recomputes on the instance and leaves saving to you; Slugs::regenerate() does both.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/sluggable-for-laravel.md)
