Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Mails Laravel Package

vormkracht10/filament-mails

Filament Mails brings outgoing email into your Filament admin panel. Browse, search, and inspect sent messages, preview HTML and attachments, resend mail, and debug delivery issues—all from a clean Laravel-native interface.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and let Laravel's package discovery register the service provider:

composer require backstage/mails
php artisan vendor:publish --tag="mails-config"   # config/mails.php
php artisan vendor:publish --tag="mails-migrations"
php artisan migrate

If you want the admin UI, register the Filament plugin in your panel provider (app/Providers/Filament/AdminPanelProvider.php) rather than wiring resources by hand — that is what pulls in MailResource and its pages (ListMails, etc.).

Where to look first:

  1. config/mails.php — the knobs you will actually touch (mailables/models, storage, UI toggles).
  2. The published migrations — confirm the table names before you write any queries or reports against them.
  3. Backstage\Mails\Resources\MailResource — the Filament entry point; browse it before customising, since it tells you which pages, actions, and tables are already provided.

First use case: get one real mail flowing end-to-end in a local environment — send through the package's mailable, then confirm it appears in the Filament mail list. That single loop exercises config, migrations, the model layer, and the panel registration in one go, and surfaces most setup mistakes immediately.

Implementation Patterns

Treat the package as the mail layer, not a wrapper around Mail::. Send through the provided mailables so records land in the package's tables; wrapping Mail::to()->send() around your own mailable bypasses whatever persistence and event hooks the package relies on.

Filament integration. Register the plugin once, at the panel level. If you need a trimmed-down UI, prefer hiding resources/pages through the plugin's configuration over forking the resource classes — forks are what break on minor Filament bumps (see Gotchas).

Customising pages. When you must extend a package page (e.g. adding a bulk action to ListMails), subclass it and re-register the page on the resource, keeping parent method signatures intact:

class ListMails extends \Backstage\Mails\Resources\MailResource\Pages\ListMails
{
    protected function getHeaderActions(): array
    {
        return [...parent::getHeaderActions(), $this->myAction()];
    }
}

Testing. Use Mail::fake() for assertions on dispatch, and assert against the package's records separately for persistence behaviour — the fake short-circuits the transport, so anything the package does after the transport boundary needs its own assertions. Wrap mail-triggering tests in RefreshDatabase since the package writes rows.

Queued sending. If you queue mail, verify the package's records are written on dispatch (not on worker completion) — otherwise a failed job leaves you with a mail that was attempted but no visible trace in the UI.

Scheduling and reporting. Because records are plain Eloquent models, day-to-day reporting (counts by status, resend of failures) is best done as small query classes or console commands over those models rather than through the Filament UI.

Gotchas and Tips

Filament 5.7.0+ requires backstage/mails v3.0.15 or later. This is the headline fix in this release. Filament widened the parent signature:

// Filament\Pages\BasePage
public function unmountAction(string|bool|null $cancelParentActions = null): void

The package's ListMails override declared bool $canCancelParentActions = true, a narrower parameter type. PHP rejects that as an incompatible override, and because it happens at class-load time during php artisan package:discover, the whole application dies — not just the Filament panel. The symptom looks like a broken install rather than a version mismatch, so check this first if you upgrade Filament and everything 500s.

If you override unmountAction yourself, match the widest signature. Any subclass of ListMails (or of Filament pages generally) that redeclares this method with bool $canCancelParentActions = true reintroduces the same fatal. Use string|bool|null $cancelParentActions = null and forward with func_get_args() / ...$args if you need pass-through, exactly as the package now does — that keeps you working across the whole filament/filament: ^5.0 range, including the new "cancel up to a named parent action" string form.

Upgrading is a no-op on your side: composer update backstage/mails. No migrations, no config republish, no code changes. Pin ^3.0.15 explicitly if you have a lockfile you are not refreshing regularly, so a fresh CI install cannot resolve an older 3.0.x alongside Filament 5.7+.

Debugging discovery failures. When the app dies before booting, composer dump-autoload -o and php artisan package:discover give you the class and both signatures in the error message. Cross-reference composer show filament/filament backstage/mails before reading any further.

Clear caches after config or plugin changes — php artisan config:clear && php artisan filament:clear-cached-components. A stale cached panel registration is a common false alarm when a resource "disappears".

Version skew is the main risk surface here. This package ships compatibility fixes keyed to Filament minors, so keep both on a schedule: bump Filament, run php artisan package:discover in CI before deploying, and let the failure surface there rather than in production. A one-line smoke test (php artisan about) catches this entire class of bug.

Extension points, in order of safety: config values → plugin configuration → subclassing pages with signature-compatible overrides → publishing and overriding views. Forking resource classes outright is the option that costs you on every Filament patch release.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource