Free·

Registering a global action in Filament

Registering a global action in Filament

Sometimes, you need an action in your Filament app that triggers no matter what page the user is on. Maybe you need to force an important confirmation or collect some required data before the user can continue. That's where a global modal action comes in.

The scenario

Let's say you want to force the user to confirm their password before they can proceed. Instead of repeating the same modal across multiple pages, we can register one global action that appears automatically on every page in your Filament panel.

The trick

Start by creating a new Livewire component that will handle the logic for your modal:

php artisan make:livewire GlobalAction --inline

Next, define a custom Filament action:

app/Livewire/GlobalAction.php
public function confirmPasswordAction(): Action
{
    return Action::make('confirmPassword')
        ->modalHeading('Confirm your password')
        ->modalDescription('Please enter your password to proceed.')
        ->modalWidth(Width::ExtraSmall)
        ->closeModalByClickingAway(false)
        ->modalCancelAction(false)
        ->closeModalByEscaping(false)
        ->modalCloseButton(false)
        ->modalSubmitAction(fn (Action $action): Action => $action
            ->outlined()
            ->color('gray')
            ->label('Confirm')
            ->extraAttributes(['class' => 'w-full'])
        )
        ->schema([
            TextInput::make('password')
                ->hiddenLabel()
                ->required()
                ->placeholder('******')
                ->password(),
        ])
        ->action(function (array $data) {

            // Here you would typically verify the password.
            // For demonstration purposes, we'll assume it's always correct.

            Notification::make()
                ->title('Password confirmed!')
                ->success()
                ->send();
        });
}

To trigger the modal as soon as the page loads, you can use the wire:init directive in your Blade file or component view:

app/Livewire/GlobalAction.php
   public function triggerAction(): void
    {
        if (! auth()->check()) {
            return;
        }

        $this->mountAction('confirmPassword');
    }

    public function render(): string
    {
        return <<<'HTML'
            <div wire:init="triggerAction">
                <x-filament-actions::modals />
            </div>  
        HTML;
    }

This ensures the modal shows up immediately when the user lands on any page.

Finally, register your new action inside a panel hook so it's available across the entire Filament application:

app/Providers/Filament/AdminPanelProvider.php
return $panel
    ->renderHook(
        name: PanelsRenderHook::BODY_END,
        hook: fn (): string => Blade::render('@livewire(App\Livewire\GlobalAction::class)'))

Now, every time a user navigates to a new page in your Filament panel, the modal will appear, forcing them to confirm their password before they can do anything else.

Conclusion

This technique is perfect for scenarios where you need to enforce user actions globally, like confirming passwords, accepting terms, or completing required setup steps.

With a few lines of code, you can register a global Filament action that follows users throughout your app!

Download source code

Download on GitHub

Join the Discussion

Run project on Firebase Studio

  • Open studio.firebase.google.com and import the repository https://github.com/wiremodel/simple-blog
  • Run the project. Once it's up, switch to the correct branch:
git checkout v4/global-action

Update dependencies and migrate the database:

composer update -W
php artisan migrate:fresh --seed
Make sure your .env file has APP_URL set to the URL provided by Firebase Studio.