Tricks

Generate slugs from a title whilst typing (without overriding)

Jun 8, 2022
Ralph J. Smit
Form builder

Sometimes you want your users to input a title (e.g. for a blog post) and automatically generate a slug from that title. However, you want to stop overriding the slug when the user has made at least one manual change.

Luckily, this is quite easy to achieve with a hidden field, to store an addition value:

TextInput::make('title')
->afterStateUpdated(function (Closure $get, Closure $set, ?string $state) {
if (! $get('is_slug_changed_manually') && filled($state)) {
$set('slug', Str::slug($state));
}
})
->reactive()
->required(),
TextInput::make('slug')
->afterStateUpdated(function (Closure $set) {
$set('is_slug_changed_manually', true);
})
->required(),
Hidden::make('is_slug_changed_manually')
->default(false)
->dehydrated(false),
avatar

I have created a filament plugin to help you enter titles & slugs, which includes the feature described above.

"Title with Slug" Input - Simple Permalink Slugs for Filament Forms

https://filamentphp.com/plugins/title-with-slug-permalink

Simply add the Field to your Filament form, and all title and slug related editing functions are available.

\Camya\Filament\Forms\Components\TitleWithSlugInput::make(
fieldTitle: 'title',
fieldSlug: 'slug',
)

Best, Andreas

avatar

It does not work with Filament v3. have anyone a solution ?

👍 1
avatar

Mabe you have to change ->reactive() in ->live(onBlur: true)

avatar

Here's how I got it working:

Forms\Components\TextInput::make('title')
->required()
->maxLength(255)
->live(onBlur: true)
->afterStateUpdated(function (Set $set, $state) {
$set('slug', Str::slug($state));
}),
Forms\Components\TextInput::make('slug')
->required()
->maxLength(255),

Don't forget to import Set (use Filament\Forms\Set;)