Streamlining Email Handling with Laravel Mailables

Streamlining Email Handling with Laravel Mailables

Laravel Mailables provide an expressive, object-oriented approach to composing emails in your applications. This feature simplifies the process of creating and sending emails, making your code more readable and maintainable. Let's explore how to leverage Mailables effectively in your Laravel projects.

Creating a Mailable

To create a new Mailable, use Laravel's Artisan command:

php artisan make:mail OrderShipped

This generates a new Mailable class:

use Illuminate\Mail\Mailable;

class OrderShipped extends Mailable
{
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

Adding Data to Your Mailable

You can easily pass data to your email template:

class OrderShipped extends Mailable
{
    public $order;

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

    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

The public properties on the Mailable will automatically be available in your view.

Using Markdown for Email Templates

Laravel supports Markdown for email templates, which can be easier to write and maintain:

public function build()
{
    return $this->markdown('emails.orders.shipped');
}

To create a Markdown template:

php artisan make:mail OrderShipped --markdown=emails.orders.shipped

Customizing the Sender

You can easily customize the sender of your email:

public function build()
{
    return $this->from('sales@example.com')
                ->markdown('emails.orders.shipped');
}

Adding Attachments

Attaching files to your email is straightforward:

public function build()
{
    return $this->markdown('emails.orders.shipped')
                ->attach('/path/to/file');
}

Queueing Mail

For better performance, you can queue your emails:

Mail::to($user)->queue(new OrderShipped($order));

Make sure your Mailable class implements ShouldQueue:

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}

Testing Mailables

Laravel makes it easy to test your Mailables:

use App\Mail\OrderShipped;
use App\Models\Order;

public function test_order_shipped_email()
{
    $order = Order::factory()->create();

    $mailable = new OrderShipped($order);

    $mailable->assertSeeInHtml($order->number);
    $mailable->assertSeeInText('Thank you for your order');
}

Real-World Example

Here's a more comprehensive example of a Mailable:

class InvoicePaid extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public $invoice;

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

    public function build()
    {
        return $this->markdown('emails.invoices.paid')
                    ->subject('Invoice Paid')
                    ->with([
                        'url' => route('invoices.show', $this->invoice),
                        'amount' => $this->invoice->amount,
                    ])
                    ->attach($this->invoice->pdf_path, [
                        'as' => 'invoice.pdf',
                        'mime' => 'application/pdf',
                    ]);
    }
}

Laravel Mailables offer a clean, expressive way to handle email generation and sending in your applications. By encapsulating email logic in dedicated classes, you can create more maintainable and testable code for your email functionality.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe