symfony/sendgrid-mailer
Symfony mailer transport for SendGrid. Send emails via SendGrid API using Symfony Mailer, with support for templates, attachments, and robust delivery options. Ideal for integrating SendGrid into Symfony apps with a familiar mailer interface.
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?