
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:
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:
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:
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
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
.env file has APP_URL set to the URL provided by Firebase Studio.