Laravel’s mail system offers a clean, simple API for sending emails using various drivers such as SMTP, Mailgun, Postmark, and Amazon SES. With Laravel, you can send plain text, HTML, and even Markdown emails with ease.

Configuration

Configuring the Laravel mail system involves setting up the config/mail.php file, where you define the mailers and specify the default mailer. Each mailer can have its unique configuration, allowing for diverse email services within the same application.

Configuration File

// config/mail.php
return [
    'default' => env('MAIL_MAILER', 'smtp'),
    'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.mailtrap.io'),
            'port' => env('MAIL_PORT', 2525),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => env('MAIL_USERNAME'),
            'password' => env('MAIL_PASSWORD'),
        ],
        'mailgun' => [
            'transport' => 'mailgun',
        ],
        'postmark' => [
            'transport' => 'postmark',
        ],
        'ses' => [
            'transport' => 'ses',
        ],
        'sendmail' => [
            'transport' => 'sendmail',
            'path' => '/usr/sbin/sendmail -bs',
        ],
        'log' => [
            'transport' => 'log',
        ],
    ],
    'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
        'name' => env('MAIL_FROM_NAME', 'Example'),
    ],
];

Sending Mail

Laravel provides a simple way to send emails through its Mail facade. You can send emails synchronously or queue them for background sending.

use Illuminate\Support\Facades\Mail;
use App\Mail\YourMailable;

Mail::to('recipient@example.com')->send(new YourMailable($data));

Generating and Writing Mailables

Generating Mailables

php artisan make:mail YourMailable

Writing Mailables

// app/Mail/YourMailable.php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class YourMailable extends Mailable
{
    use Queueable, SerializesModels;

    public $data;

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

    public function build()
    {
        return $this->view('emails.your_view')
                    ->with(['data' => $this->data]);
    }
}

Using Attachments in Laravel Mail

Attaching Files

public function build()
{
    return $this->view('emails.your_view')
                ->with(['data' => $this->data])
                ->attach('/path/to/file');
}

Inline Attachments

public function build()
{
    return $this->view('emails.your_view')
                ->with(['data' => $this->data])
                ->attach('/path/to/file', [
                    'as' => 'filename.pdf',
                    'mime' => 'application/pdf',
                ]);
}

Handling Headers, Tags, and Metadata

Custom Headers

public function build()
{
    return $this->view('emails.your_view')
                ->with(['data' => $this->data])
                ->withSwiftMessage(function ($message) {
                    $message->getHeaders()
                            ->addTextHeader('Custom-Header', 'HeaderValue');
                });
}

Markdown Mailables

Generating Markdown Mailables

php artisan make:mail YourMarkdownMailable --markdown=emails.markdown_view

Writing Markdown Messages

// app/Mail/YourMarkdownMailable.php
public function build()
{
    return $this->markdown('emails.markdown_view')
                ->with(['data' => $this->data]);
}

Sending Mail

Mail::to('recipient@example.com')->send(new YourMailable($data));

Queueing Mail

Mail::to('recipient@example.com')->queue(new YourMailable($data));

Debugging Laravel Mail

Logging Mail

// config/mail.php
'mailers' => [
    'log' => [
        'transport' => 'log',
    ],
],

Using Mailpit

Configure the config/mail.php to use Mailpit:

'mailers' => [
    'smtp' => [
        'transport' => 'smtp',
        'host' => 'mailpit.example.com',
        'port' => 1025,
        'encryption' => null,
        'username' => null,
        'password' => null,
    ],
],

Sending Mail to Multiple Recipients

Mail::to('recipient@example.com')
    ->cc('cc@example.com')
    ->bcc('bcc@example.com')
    ->send(new YourMailable($data));

Handling Failed Mail Deliveries

Failover Configuration

// config/mail.php
'mailers' => [
    'failover' => [
        'transport' => 'failover',
        'mailers' => ['smtp', 'mailgun'],
    ],
],

Localizing Mailables

Mail::to($user)->locale($user->preferred_locale)->send(new YourMailable($data));

Testing Laravel Mail

use Illuminate\Support\Facades\Mail;
use App\Mail\YourMailable;

Mail::fake();

Mail::to('recipient@example.com')->send(new YourMailable($data));

Mail::assertSent(YourMailable::class);

Events and Listeners in Laravel Mail

use Illuminate\Mail\Events\MessageSending;
use Illuminate\Mail\Events\MessageSent;

Event::listen(MessageSending::class, function (MessageSending $event) {
    // Handle the event
});

Event::listen(MessageSent::class, function (MessageSent $event) {
    // Handle the event
});

Customizing the Symfony Message

public function build()
{
    return $this->view('emails.your_view')
                ->with(['data' => $this->data])
                ->withSwiftMessage(function ($message) {
                    $message->setPriority(2);
                });
}

Mail and Local Development

Log Driver

// config/mail.php
'mailers' => [
    'log' => [
        'transport' => 'log',
    ],
],

Global Address

Mail::alwaysTo('test@example.com');

Common Issues and Troubleshooting

Email Not Sent

Check your mail configuration and ensure that your .env settings are correct:

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"

Incorrect Configurations

Ensure your config/mail.php and config/services.php files are correctly configured.

Advanced Laravel Mail Techniques

High Availability

Configure failover mailers to ensure your emails are sent even if one mail service is down:

'mailers' => [
    'failover' => [
        'transport' => 'failover',
        'mailers' => ['smtp', 'mailgun'],
    ],
],

Load Balancing

Use round robin transport to distribute your email workload across multiple mailers:

'mailers' => [
    'round_robin' => [
        'transport' => 'round_robin',
        'mailers' => ['smtp', 'mailgun', 'postmark'],
    ],
],

Real-World Examples

Sending an Email

use App\Mail\YourMailable;
use Illuminate\Support\Facades\Mail;

$data = ['message' => 'This is a test email'];

Mail::to('recipient@example.com')->send(new YourMailable($data));

Attaching a File

Mail::to('recipient@example.com')->send(new YourMailable($data, ['/path/to/file.pdf']));

Best Practices

  • Security: Use environment variables for sensitive information.
  • Performance: Queue emails to improve response times.
  • Maintainability: Keep email content in Blade templates.

Frequently Asked Questions (FAQs)

How do I send an email using Laravel?

Mail::to('recipient@example.com')->send(new YourMailable($data));

Can I send mail to multiple recipients in Laravel?

Mail::to('recipient@example.com')->cc('cc@example.com')->bcc('bcc@example.com')->send(new YourMailable($data));

How do I attach files to an email in Laravel?

public function build()
{
    return $this->view('emails.your_view')
                ->with(['data' => $this->data])
                ->attach('/path/to/file');
}

How can I debug mail sending issues in Laravel?

// config/mail.php
'mailers' => [
    'log' => [
        'transport' => 'log',
    ],
],

What is the best way to test mail in Laravel?

Mail::fake();

Mail::to('recipient@example.com')->send(new YourMailable($data));

Mail::assertSent(YourMailable::class);

How do I configure the sender for my emails?

// config/mail.php
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
    'name' => env('MAIL_FROM_NAME', 'Example'),
],

Conclusion

Laravel’s mail system is powerful and flexible, allowing you to send emails using various drivers and configurations. By understanding the configuration, generating mailables, using attachments, handling headers, and debugging issues, you can effectively manage email sending in your Laravel applications. Remember to follow best practices and leverage Laravel’s robust testing capabilities to ensure your emails are sent reliably and efficiently.

Categorized in: