symfony/sendgrid-mailer
Symfony Mailer transport for SendGrid. Send emails via SendGrid’s API with Symfony’s mailer component, supporting templated messages, attachments, and configuration through standard DSN/env settings. Ideal for integrating SendGrid delivery into Symfony apps.
Installation
composer require symfony/mailer symfony/sendgrid-mailer
Configure in config/mail.php
'dsn' => env('MAILER_DSN', 'sendgrid+api://api_key:default@default'),
Set MAILER_DSN in .env:
MAILER_DSN=sendgrid+api://your_sendgrid_api_key@default
First Use Case: Sending a Test Email
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
public function sendTestEmail(MailerInterface $mailer)
{
$email = (new Email())
->from('noreply@example.com')
->to('recipient@example.com')
->subject('Test Email')
->text('Hello, this is a test!');
$mailer->send($email);
}
Register MailerInterface in your service container (Laravel handles this automatically via Symfony Mailer bridge).
Sending Emails
Symfony\Component\Mime\Email for plain-text or HTML emails.
$email = (new Email())
->html('<h1>Hello!</h1><p>This is an HTML email.</p>');
$email->attachFromPath('/path/to/file.pdf');
MailerInterface:
Queue::later(now()->addMinutes(5), fn() => $mailer->send($email));
Templates with Blade
resources/views/emails/ (e.g., welcome.blade.php).$email = (new Email())
->subject('Welcome!')
->html(view('emails.welcome', ['name' => 'John']));
Batch Processing
foreach ($recipients as $email) {
$mailer->send((new Email())
->to($email)
->subject('Batch Notification')
->text('Your update...'));
}
Mailable to use MailerInterface:
use Symfony\Component\Mailer\MailerInterface;
public function toMail($notifiable)
{
$mailer = app(MailerInterface::class);
$mailer->send((new Email())
->to($notifiable->email)
->subject('Notification')
->html($this->buildHtmlContent()));
}
$mailer = new Mailer(
new Transport(
new SendgridTransport('api_key', ['host' => 'test.sendgrid.com'])
)
);
MailerEvents (e.g., MessageSentEvent) for logging or analytics:
$mailer->on('message.sent', function (MessageSentEvent $event) {
logger()->info('Email sent to: ' . $event->getMessage()->getTo());
});
API Key Exposure
api_key in config/mail.php. Always use .env.Rate Limits
curl https://api.sendgrid.com/v3/usage/get -H "Authorization: Bearer $API_KEY"
use Symfony\Component\Mailer\Exception\TransportException;
try {
$mailer->send($email);
} catch (TransportException $e) {
sleep(2 ** $attempt); // Exponential backoff
$mailer->send($email);
}
HTML vs. Text Emails
text and html parts are provided:
$email->text('Plain text fallback')->html('<h1>HTML</h1>');
Laravel Caching Quirks
queue:work, ensure the symfony/mailer process isn’t cached aggressively. Use:
php artisan queue:work --sleep=3 --tries=3
MAIL_MAILER_DSN to include ?logger=1 for debug logs:
MAILER_DSN=sendgrid+api://key@default?logger=1
$mailer = new Mailer(new Transport(new FakeTransport()));
Inspect sent emails with:
$fakeTransport->getMessages();
Custom Headers
Add headers like X-SMTPAPI for SendGrid templates or tracking:
$email->getHeaders()->addTextHeader('X-SMTPAPI', json_encode([
'template_id' => 1234,
]));
Substitutions Use SendGrid’s substitution tags for dynamic content:
$email->getHeaders()->addTextHeader('X-SMTPAPI', json_encode([
'sub' => ['name' => 'John'],
]));
Webhook Validation Validate SendGrid webhook signatures (e.g., for event notifications):
use Symfony\Component\Mailer\Transport\SendgridTransport;
$transport = new SendgridTransport($apiKey, [
'webhook_secret' => env('SENDGRID_WEBHOOK_SECRET'),
]);
Retry Logic Implement custom retry logic for failed sends:
$mailer->on('message.failed', function (MessageFailedEvent $event) {
if ($event->getFailureCount() < 3) {
$event->retry();
}
});
Mail::to($email)->send(new WelcomeMail($user)); // Uses Laravel's Mail facade (under the hood uses Symfony Mailer)
How can I help you explore Laravel packages today?