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

Mailer Laravel Package

symfony/mailer

Symfony Mailer is a flexible component for sending emails via SMTP and other transports. Compose rich messages with Symfony Mime, add CC/BCC and priorities, and optionally render Twig templates with TemplatedEmail and BodyRenderer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package:

    composer require symfony/mailer
    

    Laravel already includes Symfony Mailer as a dependency, so no additional installation is needed.

  2. Configure .env: Add your mail transport configuration (e.g., SMTP, Sendmail, or API-based):

    MAIL_MAILER=smtp
    MAIL_HOST=mail.example.com
    MAIL_PORT=587
    MAIL_USERNAME=your_username
    MAIL_PASSWORD=your_password
    MAIL_ENCRYPTION=tls
    MAIL_FROM_ADDRESS="hello@example.com"
    MAIL_FROM_NAME="${APP_NAME}"
    
  3. First Use Case: Send a simple email in a controller or service:

    use Illuminate\Support\Facades\Mail;
    use Symfony\Component\Mime\Email;
    
    Mail::send(new Email()
        ->from('noreply@example.com')
        ->to('user@example.com')
        ->subject('Welcome!')
        ->text('Thanks for signing up!')
    );
    
  4. Where to Look First:


Implementation Patterns

1. Basic Email Workflow

  • Plain Text Emails:
    Mail::send(new Email()
        ->to('user@example.com')
        ->subject('Plain Text Email')
        ->text('This is a plain text email.')
    );
    
  • HTML Emails:
    Mail::send(new Email()
        ->to('user@example.com')
        ->subject('HTML Email')
        ->html('<h1>Hello!</h1><p>This is an HTML email.</p>')
    );
    

2. Templated Emails (Twig Integration)

Laravel’s Mailable classes leverage Twig under the hood. Example:

// app/Mail/WelcomeMail.php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;
    public $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->subject('Welcome!')
            ->view('emails.welcome', ['user' => $this->user]);
    }
}

Send it via:

Mail::to('user@example.com')->send(new WelcomeMail($user));

3. Attachments and Embeds

$email = new Email()
    ->to('user@example.com')
    ->subject('Email with Attachments')
    ->text('Check the attachment!')
    ->attachFromPath('/path/to/file.pdf', 'filename.pdf')
    ->embedFromPath('/path/to/image.png', 'image_id');

$email->html('<img src="cid:image_id">');
Mail::send($email);

4. API-Based Transports (SendGrid, Mailgun, etc.)

Configure in .env:

MAIL_MAILER=sendgrid
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=apikey
MAIL_PASSWORD=SG.your_api_key

Use Laravel’s Mail facade as usual—it abstracts the transport.

5. Queueing Emails

Laravel’s queue system works seamlessly with Symfony Mailer:

Mail::to('user@example.com')->queue(new WelcomeMail($user));

Configure queue in .env:

QUEUE_CONNECTION=database

6. Event Listeners and Logging

Symfony Mailer supports event listeners for logging or modifying emails:

// app/Providers/AppServiceProvider.php
use Symfony\Component\Mailer\EventListener\MessageListener;
use Symfony\Component\Mime\Email;

public function boot()
{
    Mail::getSwiftMailer()->registerPlugin(new MessageListener(
        function (Email $email) {
            // Log or modify the email before sending
            \Log::info('Sending email to: ' . $email->getTo()[0]);
        }
    ));
}

7. Testing Emails

Use Laravel’s MailFake for testing:

use Illuminate\Mail\Testing\Mails;
use Illuminate\Support\Facades\Mail;

public function test_welcome_email()
{
    Mail::fake();
    $this->post('/register', ['email' => 'user@example.com']);

    Mail::assertSent(WelcomeMail::class, function ($mail) {
        return $mail->hasTo('user@example.com');
    });
}

Gotchas and Tips

1. Common Pitfalls

  • DSN Configuration: Ensure your .env DSN is correct. For SMTP:

    MAIL_MAILER=smtp
    MAILER_DSN=smtp://user:pass@smtp.example.com:587?encryption=tls
    

    For API-based transports (e.g., SendGrid):

    MAILER_DSN=sendgrid://apikey:SG.key@example.com
    

    Gotcha: Forgetting ?encryption=tls or ?encryption=ssl can cause connection failures.

  • TLS/SSL Issues: If emails fail silently, check:

    • Firewall rules blocking port 587 (TLS) or 465 (SSL).
    • SMTP server requirements (e.g., some require authentication even for TLS). Fix: Use telnet or openssl to test connectivity:
    openssl s_client -connect smtp.example.com:587 -starttls smtp
    
  • HTML vs. Text Parts: Always include a text part for emails. Some clients (e.g., Outlook) ignore HTML if no plain text is provided. Example:

    $email->text('Plain text fallback')->html('<h1>HTML</h1>');
    
  • Queueing Delays: Emails sent via queues may not appear immediately in logs or tests. Use Mail::flush() to force delivery in tests:

    Mail::fake();
    Mail::to('user@example.com')->send(new WelcomeMail($user));
    Mail::flush(); // Force delivery for testing
    
  • Attachment Size Limits: Some transports (e.g., SendGrid) have size limits (~20MB for SMTP). For larger files, use cloud storage (S3) and link to the file.

2. Debugging Tips

  • Enable Verbose Logging: Add to .env:

    MAIL_LOG_LEVEL=debug
    

    Check logs in storage/logs/laravel.log.

  • Inspect Raw Emails: Use Symfony’s RawMessage to debug:

    use Symfony\Component\Mailer\MailerInterface;
    use Symfony\Component\Mime\RawMessage;
    
    $mailer = app(MailerInterface::class);
    $rawMessage = $mailer->createTransport()->getRawMessage();
    \Log::info($rawMessage->getBody());
    
  • Test with Mailtrap: Configure Mailtrap in .env:

    MAIL_MAILER=smtp
    MAIL_HOST=smtp.mailtrap.io
    MAIL_PORT=2525
    MAIL_USERNAME=your_username
    MAIL_PASSWORD=your_password
    

    Mailtrap provides a sandbox for testing without sending real emails.

3. Performance Optimization

  • Batch Emails: Use RoundRobinTransport to distribute emails across multiple transports:

    use Symfony\Component\Mailer\Transport\TransportInterface;
    use Symfony\Component\Mailer\Transport\RoundRobinTransport;
    
    $transport1 = Transport::fromDsn('smtp://user:pass@smtp1.example.com');
    $transport2 = Transport::fromDsn('smtp://user:pass@smtp2.example.com');
    $roundRobin = new RoundRobinTransport([$transport1, $transport2]);
    
    $mailer = new Mailer($roundRobin);
    

    Configure in Laravel via config/mail.php:

    'transports' => [
        'roundrobin' => [
            'dsn' => 'roundrobin://smtp://user:pass@smtp1.example.com,smtp://user:pass@smtp2.example.com',
        ],
    ],
    
  • Avoid Blocking Calls: Always queue emails in long-running processes (e.g., commands, jobs):

    Mail::to('user@example.com')->queue
    
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