monzer/filament-email-verification-alert
Filament plugin that displays an alert prompting authenticated users to verify their email address, with a resend verification option and configurable messaging to help ensure accounts are confirmed.
This is a small, single-purpose Filament plugin. It surfaces an alert (typically a banner or notification) to authenticated panel users whose email address is not yet verified, and gives them an on-the-fly path to resend the verification email — without you hand-rolling a Livewire component or a custom widget.
Install and register
composer require monzer/filament-email-verification-alert
Then register the plugin on the panel(s) where you want the alert to appear, inside your PanelProvider:
use Monzer\FilamentEmailVerificationAlert\EmailVerificationAlertPlugin;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(EmailVerificationAlertPlugin::make());
}
Prerequisites to confirm before you wire anything up
User model implements Illuminate\Contracts\Auth\MustVerifyEmail.App\Models\User uses the Illuminate\Auth\MustVerifyEmail trait (usually already present).verification.verify named route exists (it ships with AuthServiceProvider / Breeze / Jetstream scaffolding).First use case to validate
Log in as an unverified user and confirm the alert renders, the "resend" action fires, and the signed verification URL in the email actually lands back on your panel. That single loop is the whole package — if it works, you're done.
Panel-scoped registration. Register the plugin only on the panels where it makes sense. A common split is an admin panel (where staff are pre-verified) and a customer/app panel (where self-registration happens). Registering globally means your admins see a nag they can't dismiss.
// app/Providers/Filament/AppPanelProvider.php
->plugin(EmailVerificationAlertPlugin::make())
Pair it with Filament's built-in verification features. Filament 3 exposes ->emailVerification() on the panel, which handles the "verified" middleware and redirect flow. The pattern that works well:
->emailVerification() — enforces verification for protected routes.mustVerifyEmail route group — the destination after clicking the signed link.Treat the plugin as the UX layer over Filament's enforcement layer, not a replacement.
Customizing the message and action. Depending on the version, config is typically exposed via a published config file or fluent methods on the plugin instance. Publish first, then adjust copy so it matches your product voice:
php artisan vendor:publish --tag="filament-email-verification-alert-config"
If the package supports fluent configuration, prefer that over editing vendor-published views — it survives upgrades.
Composing with other panel concerns. Since the alert is a panel-level concern, keep it out of your resource/table code entirely. If you need per-resource variants (e.g., only show on the dashboard), that's a signal to conditionally register the plugin rather than subclass it.
Testing pattern. Filament's testing helpers make this straightforward:
$user = User::factory()->unverified()->create();
$this->actingAs($user);
livewire(Dashboard::class)
->assertSee('verify'); // adjust to your copy
Also assert the happy path — a verified user (User::factory()->create() with email_verified_at set) does not see the alert. That inverted test catches over-broad rendering more often than the positive one.
Resend throttling. Laravel's VerificationController already throttles resends (default 6/minute via the throttle:6,1 middleware). Don't add your own throttle on top unless you intentionally want a stricter limit — double-throttling produces confusing "too many attempts" UX.
MustVerifyEmail is not optional. If your User model doesn't implement the contract, hasVerifiedEmail() and sendEmailVerificationNotification() won't behave as the plugin expects. This is the #1 silent failure: the alert never renders because Filament considers the user "verified" (the trait-less default), or the resend action no-ops.
Queueing and mail drivers. In local dev with MAIL_MAILER=log, "resend" appears to do nothing. That's expected — check storage/logs/laravel.log for the verification email body. In production, if ShouldQueue is on your VerifyEmail notification, a stalled queue worker looks identical to a broken plugin.
Signed URL host mismatch. The verification link is a signed URL tied to APP_URL. If you develop behind a proxy, on a subdomain, or with a different host than APP_URL, the signature check fails and users get a 403 after clicking. Set APP_URL correctly and trust your proxy headers (TrustProxies) before blaming the package.
Filament version compatibility. With 7 stars and 0 dependents, this is a very early-stage package. Pin your Filament constraint and verify the installed version explicitly:
composer show monzer/filament-email-verification-alert
Check the composer.json of the package for its filament/filament constraint. A minor Filament bump can break the view or the action contract. Given the low adoption, budget time to read the source (it's tiny — likely a handful of files) rather than relying on docs.
Read the source first. With packages this young, the README may lag the code. vendor/monzer/filament-email-verification-alert/src is your real documentation. Identify: the plugin class name, whether config is published or hardcoded, and which Blade view renders the alert. That gives you every extension point in about ten minutes.
Extension points to prefer.
resources/views/vendor/... if you need layout changes — more stable than forking.Consider the build-vs-adopt tradeoff honestly. The core deliverable — a banner with a resend button — is roughly 30–60 lines of Livewire plus a Blade view, and you get full control over copy, styling, dismissal, and Filament-version resilience. Adopt this package if you want it today and are comfortable maintaining a fork when Filament moves; otherwise, a small in-house component may be lower total cost given the 0-dependents risk profile. Either way, the implementation patterns above (panel-scoped registration, MustVerifyEmail contract, signed-URL host sanity, throttling) apply identically.
How can I help you explore Laravel packages today?