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.
| 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+ |
- 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
composer require jeffersongoncalves/filament-mailThe 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 migrateOptionally, publish the config file:
php artisan vendor:publish --tag="filament-mail-config"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.
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 scopingFilamentMailPlugin::make()
->mailSuppressionResource(false) // Disable suppression management
->analyticsWidget(false) // Disable analytics charts
->dashboard(false) // Disable dashboard page// 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,
];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-idWhen using Unlayer, publish and run the migration for the body_design column:
php artisan vendor:publish --tag="filament-mail-migrations"
php artisan migrateImplement 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);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])
);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();
}
}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,
],
],composer testPlease see CHANGELOG for more information on what has changed recently.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.
