Skip to main content

The Create Page

The Create page displays a form for creating new records. When you generate a resource, Filament creates a CreateCustomer.php page class:
packages/panels/src/Resources/Pages/CreateRecord.php
class CreateRecord extends Page
{
    public ?array $data = [];
    
    protected static bool $canCreateAnother = true;
    
    public function create(bool $another = false): void
    {
        // Creation logic
    }
}

Form Definition

The create form is defined in your resource’s form() method. This is typically referenced from a separate schema file:
use App\Filament\Resources\Customers\Schemas\CustomerForm;
use Filament\Schemas\Schema;

public static function form(Schema $schema): Schema
{
    return CustomerForm::configure($schema);
}
In the form schema file:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;

public static function configure(Schema $schema): Schema
{
    return $schema
        ->components([
            TextInput::make('name')
                ->required()
                ->maxLength(255),
            TextInput::make('email')
                ->email()
                ->required(),
        ]);
}

Validation

Validation is handled automatically through field rules:
TextInput::make('email')
    ->email()
    ->required()
    ->unique(Customer::class, 'email'),

TextInput::make('phone')
    ->tel()
    ->rules(['regex:/^[0-9]{10}$/']),
Validation runs when the form is submitted, before beforeCreate() hook.

Lifecycle Hooks

Hooks allow you to execute code at specific points in the creation process:
packages/panels/src/Resources/Pages/CreateRecord.php
protected function beforeFill(): void
{
    // Runs before the form fields are populated with default values
}

protected function afterFill(): void
{
    // Runs after the form fields are populated with default values
}

protected function beforeValidate(): void
{
    // Runs before the form fields are validated
}

protected function afterValidate(): void
{
    // Runs after the form fields are validated
}

protected function beforeCreate(): void
{
    // Runs before the form fields are saved to the database
}

protected function afterCreate(): void
{
    // Runs after the form fields are saved to the database
}
protected function mutateFormDataBeforeCreate(array $data): array
{
    $data['user_id'] = auth()->id();
    
    return $data;
}

Mutating Data

Modify form data before saving:
packages/panels/src/Resources/Pages/CreateRecord.php
protected function mutateFormDataBeforeCreate(array $data): array
{
    $data['user_id'] = auth()->id();
    $data['status'] = 'pending';
    
    return $data;
}

Customizing Creation Process

Override how records are created:
packages/panels/src/Resources/Pages/CreateRecord.php
protected function handleRecordCreation(array $data): Model
{
    $record = new ($this->getModel())($data);
    
    if ($parentRecord = $this->getParentRecord()) {
        return $this->associateRecordWithParent($record, $parentRecord);
    }
    
    $record->save();
    
    return $record;
}
For custom creation logic:
use Illuminate\Database\Eloquent\Model;

protected function handleRecordCreation(array $data): Model
{
    // Custom creation logic
    $customer = Customer::create([
        'name' => $data['name'],
        'email' => $data['email'],
    ]);
    
    // Create related records
    $customer->settings()->create([
        'theme' => 'dark',
    ]);
    
    return $customer;
}

Redirects After Creation

By default, users are redirected to the Edit page (or View page if it exists).

Redirect to List Page

protected function getRedirectUrl(): string
{
    return $this->getResource()::getUrl('index');
}

Redirect to View Page

protected function getRedirectUrl(): string
{
    return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]);
}

Redirect to Previous Page

protected function getRedirectUrl(): string
{
    return $this->previousUrl ?? $this->getResource()::getUrl('index');
}

Global Redirect Configuration

Set a default redirect for all resources:
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        ->resourceCreatePageRedirect('index') // or 'view' or 'edit'
        // ...
}

Success Notifications

Customize the success notification:
packages/panels/src/Resources/Pages/CreateRecord.php
protected function getCreatedNotificationTitle(): ?string
{
    return 'Customer registered successfully';
}
For complete customization:
use Filament\Notifications\Notification;

protected function getCreatedNotification(): ?Notification
{
    return Notification::make()
        ->success()
        ->title('Customer registered')
        ->body('The customer has been created successfully.');
}
To disable notifications:
protected function getCreatedNotification(): ?Notification
{
    return null;
}

Create Another

The “Create & create another” button allows users to create multiple records quickly.

Disabling Create Another

protected static bool $canCreateAnother = false;
Or dynamically:
public function canCreateAnother(): bool
{
    return auth()->user()->can('create_multiple_customers');
}

Preserving Form Data

Keep some fields filled when creating another record:
packages/panels/src/Resources/Pages/CreateRecord.php
use Illuminate\Support\Arr;

protected function preserveFormDataWhenCreatingAnother(array $data): array
{
    return Arr::only($data, ['organization_id', 'country']);
}
To preserve all data:
protected function preserveFormDataWhenCreatingAnother(array $data): array
{
    return $data;
}

Halting Creation

Stop the creation process at any point:
use Filament\Actions\Action;
use Filament\Notifications\Notification;

protected function beforeCreate(): void
{
    if (! auth()->user()->team->subscribed()) {
        Notification::make()
            ->warning()
            ->title('You don\'t have an active subscription!')
            ->body('Choose a plan to continue.')
            ->persistent()
            ->actions([
                Action::make('subscribe')
                    ->button()
                    ->url(route('subscribe'), shouldOpenInNewTab: true),
            ])
            ->send();
        
        $this->halt();
    }
}

Wizards

Transform the create page into a multi-step wizard:
1

Add the trait

packages/panels/src/Resources/Pages/CreateRecord.php
use App\Filament\Resources\Categories\CategoryResource;
use Filament\Resources\Pages\CreateRecord;

class CreateCategory extends CreateRecord
{
    use CreateRecord\Concerns\HasWizard;
    
    protected static string $resource = CategoryResource::class;
}
2

Define steps

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Wizard\Step;

protected function getSteps(): array
{
    return [
        Step::make('Name')
            ->description('Give the category a clear and unique name')
            ->schema([
                TextInput::make('name')->required(),
                TextInput::make('slug')->required(),
            ]),
        Step::make('Description')
            ->schema([
                // ...
            ]),
    ];
}
3

Allow skipping (optional)

public function hasSkippableSteps(): bool
{
    return true;
}

Custom Actions

Add custom buttons to the form:

Header Actions

use Filament\Actions;

protected function getHeaderActions(): array
{
    return [
        Actions\ImportAction::make()
            ->importer(CustomerImporter::class),
    ];
}

Form Actions

use Filament\Actions\Action;

protected function getFormActions(): array
{
    return [
        ...parent::getFormActions(),
        Action::make('createAndEmail')
            ->action('createAndEmail'),
    ];
}

public function createAndEmail(): void
{
    // Custom logic
}

Moving Create to Header

protected function getHeaderActions(): array
{
    return [
        $this->getCreateFormAction()
            ->formId('form'),
    ];
}

protected function getFormActions(): array
{
    return [];
}

Authorization

Users can access the Create page if the create() method of the model policy returns true:
public function create(User $user): bool
{
    return $user->can('create customers');
}

Build docs developers (and LLMs) love