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

Nova Mail Manager Laravel Package

binarybuilds/nova-mail-manager

Nova Mail Manager is a Laravel Nova tool for inspecting and managing emails sent by your app. Browse a searchable log of outgoing mail, preview rendered HTML, resend messages, and download attachments from a clean Nova interface.

View on GitHub
Deep Wiki
Context7

Getting Started

Check compatibility before you run composer require. The last release is 2020‑08‑02, which puts this package in the Laravel 7/8 + Nova 3 era. Open the package's composer.json and confirm the laravel/nova constraint covers your installed version — on Nova 4/5 or Laravel 9+ (Symfony Mailer) expect breakage and budget for a fork. The MIT licence and small surface area make forking practical.

Minimal setup:

  1. composer require binarybuilds/nova-mail-manager
  2. Publish config + migrations using the provider printed by php artisan vendor:publish (publish them separately so you can edit the migration before running it).
  3. php artisan migrate — this creates the table that stores sent‑mail snapshots.
  4. Register the tool in app/Providers/NovaServiceProvider.php:
public function tools()
{
    return [
        new \BinaryBuilds\NovaMailManager\NovaMailManager(),
    ];
}
  1. Gate the tool to admins/support (canSee on the tool or a Gate check) before it ever reaches production.

Where to look first: the published config/nova-mail-manager.php (table name, queue, capture toggles), src/MailManager.php (the send/resend entry points), src/NovaMailManager.php (the UI), and the migration stub — the migration tells you exactly what is persisted (recipients, subject, HTML body, mailable class, serialized payload, attachments) and therefore what a resend can actually rebuild.

First use case: the "customer says they never got the invoice" ticket. Support opens Nova → Mail Manager, filters by recipient/subject/date, opens the record, hits Resend. No need to impersonate the user or replay the order flow. Wire only that mail path through the manager first, verify a resend lands in your provider's logs, then expand.

Implementation Patterns

  • Route mail selectively, not globally. If the package captures via a send wrapper, adopt it in the specific flows you want resendable (invoices, order confirmations, receipts, account notifications) rather than wrapping every Mail::send in the app. Otherwise the table fills with marketing/newsletter traffic and the Nova index becomes useless.
  • Keep mailables rebuildable from stored data. Pass IDs and scalars into the mailable constructor, not authenticated users or request state. A resend happens days later in a different request context; anything resolved via auth(), request(), or a session value will be wrong or null.
  • Treat a resend as a new send. It bypasses your application flow: no side effects, no status transitions, no idempotency guard. If the original send also flipped an invoice_sent_at column, a resend from Nova won't — decide whether that's acceptable or whether you need a small listener/observer.
  • Make records findable. Prefix subjects consistently (Invoice #1042 — Acme Ltd) and include the domain reference in the stored payload so support can search by order number rather than by email address.
  • Split read vs. send permissions. The tool is a support-facing screen; a read-only view of what was sent is often all a first-line agent needs. Use Nova's tool authorization plus a Gate for the resend action so the destructive capability is narrower than the viewing capability.
  • Pair with delivery telemetry. Resending from Nova proves you handed the message to the transport, not that it was delivered. Correlate with your provider's bounce/complaint webhooks before telling a customer "we've resent it."
  • Testing. Mail::fake() in your application tests is unaffected; add one integration test asserting a record is written when the manager sends. In local dev, point MAIL_MAILER=log so resends go to storage/logs/laravel.log and you can diff the rendered output against the original before trusting the tool in production.
  • Queues. If your mailables implement ShouldQueue, the capture write happens in the worker. Verify the record is written on the queued path (not just the synchronous one), and keep an eye on long-running workers holding stale DB connections.

Gotchas and Tips

  • Maintenance risk is the headline. Last release 2020, 19 stars, single maintainer. There is effectively no community support: no Stack Overflow corpus, no issue triage. Read src/ end-to-end before depending on it — it's small enough to audit in an afternoon.
  • Mailable serialization is the failure point. Mailables with closures, non-serializable properties, or data streamed with attachData()/attachFromStorage() frequently don't survive a round trip. Test resends for every mailable you register, attachments especially: know whether bytes are stored, and what happens when the source file has since been deleted.
  • Snapshot vs. rebuild — know which you're getting. If a resend re-renders from the stored body, it may ship stale pricing or an expired link. If it rebuilds from the database, it ships current data but fails outright when the record has been deleted. Either behaviour is defensible; not knowing which you have is not.
  • Double-send / double-record risk. If you adopt a send wrapper and the package registers a mail event listener, you can end up writing two rows per email or sending twice. Confirm a single capture path is active.
  • The table is a PII archive. Full HTML bodies plus serialized payloads for every stored mail, forever. Add a pruning command and a retention window, and treat the table as in-scope for GDPR/data-deletion requests — deleting a user in your app does not delete their mail copies here.
  • Table growth. Bodies and base64 attachments add up fast on high-volume transactional mail. Check the column types in the migration (LONGTEXT vs TEXT) before you discover truncated HTML at 64KB.
  • Migration and config quirks. Publish the migration to a custom table name via config before running it in production to avoid collisions with an existing emails/mail_logs table; run php artisan config:cache after publishing, and php artisan optimize:clear if the tool doesn't appear in the sidebar after registration.
  • Nova 4+ UI layer. If you do get it running under a newer Nova, the tool's resource/fields are the most likely thing to break — that's the file to patch in your fork.
  • Best extension points: a custom model binding in config, published views for the detail screen, and a Gate around the resend action. These are cheaper than modifying the send path, which is where the serialization landmines live.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource