Weave Code
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

Sendgrid Mailer Laravel Package

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.

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require symfony/mailer symfony/sendgrid-mailer
    
  2. 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
    
  3. 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).


Implementation Patterns

Core Workflows

  1. Sending Emails

    • Basic Emails: Use Symfony\Component\Mime\Email for plain-text or HTML emails.
      $email = (new Email())
          ->html('<h1>Hello!</h1><p>This is an HTML email.</p>');
      
    • Attachments: Add files dynamically.
      $email->attachFromPath('/path/to/file.pdf');
      
    • Async Sending: Use Laravel’s queues with MailerInterface:
      Queue::later(now()->addMinutes(5), fn() => $mailer->send($email));
      
  2. Templates with Blade

    • Store templates in resources/views/emails/ (e.g., welcome.blade.php).
    • Render and send:
      $email = (new Email())
          ->subject('Welcome!')
          ->html(view('emails.welcome', ['name' => 'John']));
      
  3. Batch Processing

    • Loop through recipients and send in bulk (avoid rate limits):
      foreach ($recipients as $email) {
          $mailer->send((new Email())
              ->to($email)
              ->subject('Batch Notification')
              ->text('Your update...'));
      }
      

Integration Tips

  • Laravel Notifications: Extend 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()));
    }
    
  • Custom Transport: Override the default SendGrid transport for testing:
    $mailer = new Mailer(
        new Transport(
            new SendgridTransport('api_key', ['host' => 'test.sendgrid.com'])
        )
    );
    
  • Event Listeners: Hook into MailerEvents (e.g., MessageSentEvent) for logging or analytics:
    $mailer->on('message.sent', function (MessageSentEvent $event) {
        logger()->info('Email sent to: ' . $event->getMessage()->getTo());
    });
    

Gotchas and Tips

Pitfalls

  1. API Key Exposure

    • Never hardcode api_key in config/mail.php. Always use .env.
    • Restrict SendGrid API key permissions to only what’s needed (e.g., "Mail Send").
  2. Rate Limits

    • SendGrid has sending limits. Monitor usage via:
      curl https://api.sendgrid.com/v3/usage/get -H "Authorization: Bearer $API_KEY"
      
    • Implement exponential backoff for retries:
      use Symfony\Component\Mailer\Exception\TransportException;
      
      try {
          $mailer->send($email);
      } catch (TransportException $e) {
          sleep(2 ** $attempt); // Exponential backoff
          $mailer->send($email);
      }
      
  3. HTML vs. Text Emails

    • SendGrid may block emails with low "spam score." Ensure both text and html parts are provided:
      $email->text('Plain text fallback')->html('<h1>HTML</h1>');
      
  4. Laravel Caching Quirks

    • If using Laravel’s queue:work, ensure the symfony/mailer process isn’t cached aggressively. Use:
      php artisan queue:work --sleep=3 --tries=3
      

Debugging

  • Enable Verbose Logging Set MAIL_MAILER_DSN to include ?logger=1 for debug logs:
    MAILER_DSN=sendgrid+api://key@default?logger=1
    
  • Test Mode Use a fake transport for local testing:
    $mailer = new Mailer(new Transport(new FakeTransport()));
    
    Inspect sent emails with:
    $fakeTransport->getMessages();
    

Extension Points

  1. Custom Headers Add headers like X-SMTPAPI for SendGrid templates or tracking:

    $email->getHeaders()->addTextHeader('X-SMTPAPI', json_encode([
        'template_id' => 1234,
    ]));
    
  2. Substitutions Use SendGrid’s substitution tags for dynamic content:

    $email->getHeaders()->addTextHeader('X-SMTPAPI', json_encode([
        'sub' => ['name' => 'John'],
    ]));
    
  3. 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'),
    ]);
    
  4. Retry Logic Implement custom retry logic for failed sends:

    $mailer->on('message.failed', function (MessageFailedEvent $event) {
        if ($event->getFailureCount() < 3) {
            $event->retry();
        }
    });
    

Performance

  • Batch Processing: For >1000 emails, use SendGrid’s Batch API instead of individual sends.
  • Async Queues: Offload sending to Laravel queues to avoid blocking requests:
    Mail::to($email)->send(new WelcomeMail($user)); // Uses Laravel's Mail facade (under the hood uses Symfony Mailer)
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport