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 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.

View on GitHub
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai