Title + slug field for Filament v5 with auto-slug generation, live permalink preview, and inline editing.
Title + slug field for Filament v5 with auto-slug generation, live permalink preview, and inline editing.
use Blendbyte\FilamentTitleWithSlug\TitleWithSlugInput; TitleWithSlugInput::make()Requirements
| Package (blendbyte) | Filament | Laravel | Namespace |
|---|---|---|---|
^3.x |
^5.0 |
^11 / ^12 / ^13* |
Blendbyte\FilamentTitleWithSlug |
^2.x ⚠️ (deprecated) |
^4.0 |
^11 / ^12 |
Camya\Filament\Forms\Components |
^1.x ⚠️ (deprecated) |
^3.0 |
^10 / ^11 / ^12 |
Camya\Filament\Forms\Components |
*PHP 8.2 is not tested against Laravel 13.
v1.x and v2.x are not actively maintained. They receive security and severe bug fixes only — no new features. Please upgrade to v3.x. See the Upgrading section for migration steps.
Looking for Filament v2 support? The original package is at camya/filament-title-with-slug.
Featureshttps://example.com/blog/my-post)All upgrades to v3.x share one breaking change: the namespace changed from Camya\Filament\Forms\Components (used in v1 and v2) to Blendbyte\FilamentTitleWithSlug.
Find every import of the component in your app and update it:
// Before (v1.x and v2.x) use Camya\Filament\Forms\Components\TitleWithSlugInput; // After (v3.x) use Blendbyte\FilamentTitleWithSlug\TitleWithSlugInput;
The TitleWithSlugInput::make() call signature and all parameter names are unchanged.
composer require blendbyte/filament-title-with-slug:^3.0
New in v3: the titleField parameter for passing a custom field (e.g. translatable) as the title input.
composer require blendbyte/filament-title-with-slug:^3.0
camya/filament-title-with-slug (Filament v2)1. Swap the package:
composer remove camya/filament-title-with-slug composer require blendbyte/filament-title-with-slug:^3.0
2. Update the namespace as shown above.
3. Re-publish config and translations if you had published them previously:
php artisan vendor:publish --tag="filament-title-with-slug-config" --force php artisan vendor:publish --tag="filament-title-with-slug-translations" --force
4. Remove any manual CSS imports — v3 registers its stylesheet automatically.
5. See the Filament upgrade guide for app-level Filament changes.
Installationcomposer require blendbyte/filament-title-with-slug
Optionally publish the config file:
php artisan vendor:publish --tag="filament-title-with-slug-config"
TranslationPublish the translation files:
php artisan vendor:publish --tag="filament-title-with-slug-translations"
Published translations land at lang/vendor/filament-title-with-slug.
Included languages: English, French, Brazilian Portuguese, German, Dutch, Indonesian, Arabic.
Added a translation? Share it on our GitHub Discussions page.
Usage & ExamplesBasic usageAdd TitleWithSlugInput to any Filament form schema. It binds to title and slug by default:
use Blendbyte\FilamentTitleWithSlug\TitleWithSlugInput; class PostResource extends Resource { public static function form(Form $form): Form { return $form->schema([ TitleWithSlugInput::make(), ]); } }
Custom title fieldTip: Use
->columnSpan('full')to make the component span the full form width.
Pass any Filament field as the title input via titleField. This is useful when you need a translatable input or another custom field type from a third-party package:
TitleWithSlugInput::make( titleField: \Spatie\FilamentTranslatable\Forms\Components\TranslatableInput::make('title'), )
The package automatically wires slug auto-generation onto the provided field. The field name is derived from getName(), so you don't need to pass fieldTitle separately unless you want to override it.
All title-specific parameters (titleLabel, titleRules, titlePlaceholder, etc.) are ignored when titleField is provided — configure those directly on your field before passing it in.
The titleAfterStateUpdated and titleFieldWrapper parameters still work regardless:
TitleWithSlugInput::make( titleField: MyTranslatableField::make('title') ->label('Post Title') ->required(), titleAfterStateUpdated: function (Set $set, string $state) { // runs after every title update }, )Change model field names
Default field names are title and slug. Override them:
TitleWithSlugInput::make( fieldTitle: 'name', fieldSlug: 'identifier', )Change labels and placeholder
TitleWithSlugInput::make( urlPath: '/book/', urlVisitLinkLabel: 'Visit Book', titleLabel: 'Title', titlePlaceholder: 'Insert the title...', slugLabel: 'Link:', )Permalink preview: hide host
TitleWithSlugInput::make( urlHostVisible: false, )Permalink preview: change host and path
TitleWithSlugInput::make( urlPath: '/category/', urlHost: 'https://project.local', )Visit link via named route
Use a named route to generate the Visit link URL:
TitleWithSlugInput::make( urlPath: '/product/', urlHost: 'camya.com', urlVisitLinkRoute: fn(?Model $record) => $record?->slug ? route('product.show', ['slug' => $record->slug]) : null, )
Because the Visit URL is now route-generated, you can use a short urlHost just for the permalink preview display.
TitleWithSlugInput::make( urlVisitLinkVisible: false, )Style the title input
Pass extra HTML attributes directly to the title <input> element:
TitleWithSlugInput::make( titleExtraInputAttributes: ['class' => 'italic'], )Readonly title or slug
Lock either field, optionally based on context:
TitleWithSlugInput::make( titleIsReadonly: fn($context) => $context === 'edit', slugIsReadonly: fn($context) => $context === 'edit', )
When slugIsReadonly is true the slug row renders as a static permalink display (no edit link, no action buttons).
TitleWithSlugInput::make( titleRules: [ 'required', 'string', 'min:3', 'max:120', ], )
A unique rule is automatically applied to the slug. To customize it, see Custom unique validation.
Custom unique validationPass an array of named arguments that map to Filament's ->unique() method:
TitleWithSlugInput::make( slugRuleUniqueParameters: [ 'modifyRuleUsing' => fn(Unique $rule) => $rule->where('is_published', 1), 'ignorable' => fn(?Model $record) => $record, ], )
Available keys: ignorable, modifyRuleUsing, ignoreRecord, table, column.
Override validation messages in your resource class:
protected $messages = [ 'data.slug.regex' => 'Invalid slug. Use only a–z, 0–9, and hyphens.', ];Custom slugifier
Replace the default Str::slug() with your own closure:
TitleWithSlugInput::make( slugSlugifier: fn($string) => preg_replace('/[^a-z]/', '', $string), slugRuleRegex: '/^[a-z]*$/', )Dark mode Empty homepage slug
Remove the slug's required rule, then use / as the slug value to represent the homepage. The / bypasses the auto-regeneration that would trigger on an empty value:
TitleWithSlugInput::make(
slugRules: [],
)
Within a repeaterRepeater::make('FAQEntries') ->relationship() ->collapsible() ->schema([ TitleWithSlugInput::make( fieldTitle: 'title', fieldSlug: 'slug', urlPath: '/faq/', urlHostVisible: false, titleLabel: 'Title', titlePlaceholder: 'Insert FAQ title...', ), ]),URL slug sandwich
Place the slug in the middle of a path, e.g. /books/my-slug/detail/:
TitleWithSlugInput::make( urlPath: '/books/', urlVisitLinkRoute: fn(?Model $record) => $record?->slug ? '/books/' . $record->slug . '/detail' : null, slugLabelPostfix: '/detail/', urlVisitLinkLabel: 'Visit Book Details', ),Slug as subdomain
TitleWithSlugInput::make( fieldSlug: 'subdomain', urlPath: '', urlHostVisible: false, urlVisitLinkLabel: 'Visit Domain', urlVisitLinkRoute: fn(?Model $record) => $record?->slug ? 'https://' . $record->slug . '.camya.com' : null, slugLabel: 'Domain:', slugLabelPostfix: '.camya.com', ),Config file defaults
Publish the config to set global defaults:
php artisan vendor:publish --tag="filament-title-with-slug-config"
Published at config/filament-title-with-slug.php:
[
'field_title' => 'title', // Override per-field with fieldTitle:
'field_slug' => 'slug', // Override per-field with fieldSlug:
'url_host' => env('APP_URL'), // Override per-field with urlHost:
]
All available parametersAll parameters are optional and use named argument syntax. Parameters marked (ignored when titleField is set) only apply to the default TextInput.
TitleWithSlugInput::make( // Model fields fieldTitle: 'title', fieldSlug: 'slug', // Custom title field — replaces the default TextInput titleField: SomeField::make('title'), // URL urlPath: '/blog/', urlHost: 'https://www.example.com', urlHostVisible: true, urlVisitLinkLabel: 'View', urlVisitLinkRoute: fn(?Model $record) => $record?->slug ? route('post.show', ['slug' => $record->slug]) : null, urlVisitLinkVisible: true, // Title — ignored when titleField is provided titleLabel: 'The Title', titlePlaceholder: 'Post Title', titleExtraInputAttributes: ['class' => 'italic'], titleRules: ['required', 'string'], titleRuleUniqueParameters: [ 'modifyRuleUsing' => fn(Unique $rule) => $rule->where('is_published', 1), 'ignorable' => fn(?Model $record) => $record, ], titleIsReadonly: fn($context) => $context !== 'create', titleAutofocus: true, // Title callbacks — work with both default TextInput and custom titleField titleAfterStateUpdated: function ($state) {}, titleFieldWrapper: fn($field) => $field, // Slug slugLabel: 'The Slug:', slugRules: ['required', 'string'], slugRuleUniqueParameters: [ 'modifyRuleUsing' => fn(Unique $rule) => $rule->where('is_published', 1), 'ignorable' => fn(?Model $record) => $record, ], slugIsReadonly: fn($context) => $context !== 'create', slugSlugifier: fn($string) => Str::slug($string), slugRuleRegex: '/^[a-z0-9\-\_]*$/', slugAfterStateUpdated: function ($state) {}, slugLabelPostfix: '/suffix', )->columnSpan('full'),Credits
Originally created by Andreas Scheibel (camya). Inspired by packages from awcodes and the work of spatie. Tests built with Pest.
Please see the release changelog for version history, and contributing for how to get involved. Security vulnerabilities can be reported via our security policy.
Maintained by Blendbyte
Blendbyte builds cloud infrastructure, web apps, and developer tools.
We've been shipping software to production for 20+ years.
This package runs in our own stack, which is why we keep it maintained.
Issues and PRs get read. Good ones get merged.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | ivanharmat/crewgrid (v0.2.0) | 0 | 19.86 | 28-07-2026 |
| 2 | artisanpack-ui/visual-editor (1.5.3) | 0 | 24.06 | 28-07-2026 |
| 3 | moaines/illumi-search (1.21.4) | 0 | 37.46 | 28-07-2026 |
| 4 | laravel-workflow/waterline (2.0.0-rc.1) | 0 | 21.11 | 28-07-2026 |
| 5 | durable-workflow/waterline (2.0.0-rc.1) | 0 | 21.11 | 28-07-2026 |
| 6 | publish-php/statamic-standard-site (v1.0.1) | 0 | 19.09 | 28-07-2026 |
| 7 | linkrobins/birdseye (v1.5.0) | 0 | 14.17 | 28-07-2026 |
| 8 | sli-ui-toolkit 3.1.11 | 0 | 5 | 20-07-2026 |
| 9 | nswdpc/silverstripe-elemental-feature-video (v2.0.0) | 0 | 26.67 | 28-07-2026 |
| 10 | atlasdocs-theme 0.14.18 | 0 | 5 | 20-07-2026 |