jeffersongoncalves / filament-mail
Complete email management UI for Filament: mail logs with preview, database templates with multi-locale editing, delivery tracking, analytics dashboard, and suppression management.
Package info
github.com/jeffersongoncalves/filament-mail
pkg:composer/jeffersongoncalves/filament-mail
Fund package maintenance!
Requires
- php: ^8.2
- filament/filament: ^5.0
- jeffersongoncalves/laravel-mail: ^1.2
- lara-zeus/spatie-translatable: ^2.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.24
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
README
Filament Mail
Complete email management UI for Filament. Built on top of jeffersongoncalves/laravel-mail, it provides a rich interface for managing email logs, database templates with multi-locale editing, delivery tracking, analytics dashboard, and suppression management.
Compatibility
| Package | Filament | Laravel | PHP |
|---|---|---|---|
| 1.x | 3.x | 10+ | 8.1+ |
| 2.x | 4.x | 11+ | 8.2+ |
| 3.x | 5.x | 11+ | 8.2+ |
Features
- Mail Logs — Browse, search, and view all sent emails with HTML preview, attachments, headers, and metadata
- Resend & Retry — Resend any email or retry failed deliveries directly from the UI
- Mail Templates — Create and edit database-driven email templates with multi-locale support (via spatie/laravel-translatable)
- Swappable Template Editor — Use Filament RichEditor (default) or Unlayer visual drag-and-drop editor
- MailNotification — Send template-based notifications with variable binding, cc, bcc, attachments
- Template Versioning — Automatic version history with change tracking
- Live Preview — Preview rendered templates with example data in an iframe sandbox
- Send Test Email — Send test emails from any template with locale selection
- Delivery Tracking — View tracking events (delivered, bounced, opened, clicked, complained) from 5 providers
- Analytics Dashboard — Stats overview, daily analytics chart, and delivery rate chart with period filters
- Suppression Management — Manage suppressed emails (hard bounces, complaints, manual suppressions)
- Multi-tenant — Optional tenant scoping for all queries
- Configurable — Disable/enable individual resources, widgets, and pages
Installation
composer require jeffersongoncalves/filament-mail
The package requires jeffersongoncalves/laravel-mail as a dependency. Make sure to run its migrations first:
php artisan vendor:publish --tag="laravel-mail-migrations"
php artisan migrate
Optionally, publish the config file:
php artisan vendor:publish --tag="filament-mail-config"
Usage
Register the plugin in your Filament panel provider:
use JeffersonGoncalves\FilamentMail\FilamentMailPlugin; use LaraZeus\SpatieTranslatable\SpatieTranslatablePlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ FilamentMailPlugin::make(), // Required for multi-locale template editing SpatieTranslatablePlugin::make() ->defaultLocales(['en', 'pt_BR', 'es']), ]); }
The SpatieTranslatablePlugin is required for multi-locale template editing. It provides a locale switcher in the header of all template pages (create, edit, view, list). Configure the locales you need in the defaultLocales() method.
Customization
FilamentMailPlugin::make() ->navigationGroup('Email') ->navigationIcon('heroicon-o-envelope') ->navigationSort(50) ->mailLogResource() // Enable/disable mail log resource ->mailTemplateResource() // Enable/disable template resource ->mailSuppressionResource() // Enable/disable suppression resource ->statsWidgets() // Enable/disable stats widgets ->analyticsWidget() // Enable/disable analytics charts ->dashboard() // Enable/disable dashboard page ->tenantScoping() // Enable/disable tenant scoping
Disabling Features
FilamentMailPlugin::make() ->mailSuppressionResource(false) // Disable suppression management ->analyticsWidget(false) // Disable analytics charts ->dashboard(false) // Disable dashboard page
Configuration
// config/filament-mail.php return [ 'resources' => [ 'mail_log' => [ 'enabled' => true, 'label' => 'Mail Log', 'plural_label' => 'Mail Logs', ], 'mail_template' => [ 'enabled' => true, 'label' => 'Mail Template', 'plural_label' => 'Mail Templates', ], 'mail_suppression' => [ 'enabled' => true, 'label' => 'Suppression', 'plural_label' => 'Suppressions', ], ], 'widgets' => [ 'stats_overview' => true, 'analytics_chart' => true, 'delivery_rate_chart' => true, ], 'dashboard' => [ 'enabled' => true, ], 'navigation' => [ 'group' => 'Email', 'icon' => 'heroicon-o-envelope', 'sort' => 50, ], 'template_editor' => [ 'driver' => env('FILAMENT_MAIL_EDITOR', 'rich_editor'), 'locales' => ['en'], 'default_locale' => 'en', 'unlayer_project_id' => env('UNLAYER_PROJECT_ID'), 'merge_tags' => [], ], 'preview' => [ 'max_width' => '800px', 'sandbox' => true, ], 'tenant_scoping' => false, ];
Template Editor
The template editor is swappable via config. Set the FILAMENT_MAIL_EDITOR environment variable:
# Default: standard Filament RichEditor FILAMENT_MAIL_EDITOR=rich_editor # Visual drag-and-drop editor via Unlayer FILAMENT_MAIL_EDITOR=unlayer UNLAYER_PROJECT_ID=your-project-id
When using Unlayer, publish and run the migration for the body_design column:
php artisan vendor:publish --tag="filament-mail-migrations"
php artisan migrate
Creating a Custom Editor Driver
Implement TemplateEditorContract and bind it in a service provider:
use JeffersonGoncalves\FilamentMail\Contracts\TemplateEditorContract; class MyEditorDriver implements TemplateEditorContract { public function getFormField(string $fieldName = 'html_body'): Component { return MyCustomField::make($fieldName)->columnSpanFull(); } public function render(string $content, array $variables): string { foreach ($variables as $key => $value) { $content = str_replace( ['{{' . $key . '}}', '{{ ' . $key . ' }}'], (string) $value, $content ); } return $content; } } // In a service provider: $this->app->bind(TemplateEditorContract::class, MyEditorDriver::class);
MailNotification
Send emails using database templates with variable binding:
use JeffersonGoncalves\FilamentMail\Notifications\MailNotification; // Simple notification $user->notify(new MailNotification( templateKey: 'auth.welcome', variables: [ 'name' => $user->name, 'login_url' => route('login'), ], )); // With locale, cc, and attachments $user->notify(new MailNotification( templateKey: 'transactional.invoice', variables: [ 'invoice_number' => $invoice->number, 'total' => number_format($invoice->total, 2, ',', '.'), 'due_date' => $invoice->due_date->format('d/m/Y'), ], metadata: [ 'locale' => 'pt_BR', 'cc' => ['finance@company.com'], 'attachments' => [storage_path("invoices/{$invoice->number}.pdf")], ], )); // Without a notifiable (via Notification facade) use Illuminate\Support\Facades\Notification; Notification::route('mail', $email)->notify( new MailNotification('auth.reset-password', ['url' => $resetUrl]) );
HasMailTemplate Trait
For traditional Mailables, use the HasMailTemplate trait:
use JeffersonGoncalves\FilamentMail\Traits\HasMailTemplate; use Illuminate\Mail\Mailable; class WelcomeMail extends Mailable { use HasMailTemplate; public function __construct(User $user) { $this->templateKey = 'auth.welcome'; $this->templateVariables = ['name' => $user->name]; } public function build(): static { return $this->buildContent(); } }
Extending Resources
You can extend the default resources by creating your own classes and updating the config:
// config/filament-mail.php 'resources' => [ 'mail_log' => [ 'class' => App\Filament\Resources\CustomMailLogResource::class, ], ],
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
