dniccum/custom-email-sender
dniccum/custom-email-sender lets Laravel apps override the default mail sender per message, so mailables and notifications can go out from custom addresses, names, or SMTP configurations without touching global config. Lightweight and easy to drop into existing projects.
Prerequisites: a Laravel app with Laravel Nova installed and a working mail configuration. Note the last release was December 2020, so it targets the Nova 3 era — verify compatibility before dropping it into a Nova 4/5 app.
composer require dniccum/custom-email-sender
app/Providers/NovaServiceProvider.php:
public function tools()
{
return [
new \Dniccum\CustomEmailSender\CustomEmailSender(),
// some versions: CustomEmailSender::make()
];
}
php artisan vendor:publish --provider="Dniccum\CustomEmailSender\ToolServiceProvider"
# or --tag=custom-email-sender-config / --tag=views
php artisan config:clear
MAIL_MAILER, MAIL_FROM_ADDRESS, and MAIL_FROM_NAME are what you actually want recipients to see — the tool reuses the app's mailer, so whatever is in .env is what goes out.Where to look first: the published config file. It defines the recipient sources (which Eloquent model/columns the dropdown reads), the sender identity, and the default mail view. After that, vendor/dniccum/custom-email-sender/src for the tool class and the Mailable it wraps.
First use case: a one-off maintenance notice or product update to a filtered subset of users, sent from the Nova sidebar without writing a Mailable, command, or tinker script.
Point the config at your recipient model. The core configuration maps a model to the columns the tool should use for display and addressing:
'models' => [
\App\Models\User::class => [
'label' => 'Users',
'email' => 'email',
'name' => 'name',
],
],
Add a second entry for a customers table if you have non-user recipients. Make sure the email column is indexed — the picker does LIKE searches.
Gate access explicitly. The default behavior exposes the tool to anyone who can reach Nova. Lock it down at registration:
(new CustomEmailSender())
->canSee(fn ($request) => $request->user()->hasRole('admin'));
Treat the UI as the ad-hoc path, not the campaign path. For anything recurring or templated, extract the send logic into a service/job and let the tool call it, or fork the tool's controller. Sending through the UI is fine for one-offs; it's the wrong layer for lifecycle email.
Queue large sends. Check whether the underlying Mailable implements ShouldQueue. If not, wrap the send in a job — otherwise the Nova request will hit PHP's max_execution_time or a 504 on a few hundred recipients, and SES/SMTP rate limits will bite.
Override the view. If a mail view is published, edit the vendored Blade/Markdown template rather than patching vendor/. This is the intended customization seam for branding, footers, and layout.
Audit what was sent. These tools generally don't log by default. Hook MessageSending/MessageSent events or wrap the send to record sender, subject, recipient count, and timestamp — the first "did we email that customer?" support ticket will make this worth the effort.
Localization. If the tool supports per-recipient locale, pass it; if not, chunk recipients by locale and queue one job per locale rather than sending a single mixed-language blast.
composer.json, and budget for a fork rather than expecting upstream fixes — Nova's frontend tooling has moved on since.log.Mail::fake() works only if the package sends through the Mail facade. If it uses a custom transport, test the extracted service instead and treat the Nova tool as a thin view over it.MAIL_LOG_CHANNEL so failures land in laravel.log; without it, send errors often appear only as a transient UI message.How can I help you explore Laravel packages today?