Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Building and Sending Emails with Laravel Mailables

In a Laravel app, code sends an email by creating a Mailable, a class that describes the message’s subject, content, and optional attachments. Laravel uses the class to prepare the message, then sends it through the configured mail service. Keeping these details in a Mailable makes the email easier to reuse and check.

The Mailable class sets the message details, and a Blade view, a template that Laravel fills in to create the email body, supplies the content. The sender usually chooses the recipient when calling Laravel’s Mail facade. These parts determine what the recipient receives. Laravel’s mail configuration overview covers the basic setup and sending pattern.

Define the Mailable

Create a Mailable with Artisan, Laravel’s command-line tool:

php artisan make:mail WelcomeEmail

The command creates a class under app/Mail. A Mailable can define an envelope with message details such as the subject and reply-to address, content that points to a view and supplies data for it, and an attachments method that returns files to include.

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(public string $name)
    {
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Welcome',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome',
        );
    }

    public function attachments(): array
    {
        return [];
    }
}

The constructor receives the data the email needs. In this example, the public $name property is available to the view. The current Mailable structure uses envelope for message details, content for the view and its data, and attachments for files. Older Laravel versions and existing projects may use a build method instead. Use the pattern supported by your installed Laravel version, and do not combine the two styles. The Mailable configuration example also shows the older build approach.

In a class that uses build, the method chains settings such as subject, view, and with. For example, $this->subject('Welcome')->view('mail.welcome')->with(['name' => $this->name]) sets the subject, selects the view, and passes data to it. With either style, specify the recipient separately when you send the Mailable.

Render the email view

Create the Blade template at resources/views/mail/welcome.blade.php to match the view name mail.welcome:

<h1>Hello, {{ $name }}</h1>
Welcome to our service.

Laravel renders the Blade template into the email body. The {{ $name }} expression escapes the value for HTML output, which helps stop untrusted text from being treated as markup. Use raw HTML output only when the content is trusted and must remain HTML.

A Mailable can also use a Markdown email template. Markdown mailables use Laravel’s email components, such as <x-mail::message>, and Laravel turns the template into email markup. The Markdown and Blade comparison describes the difference: Markdown offers email-specific components, while a regular Blade view gives you direct control over its markup.

Send the message

Call Mail::to with the recipient, then pass the Mailable to send:

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

Mail::to($user->email)->send(new WelcomeEmail($user->name));

Laravel combines the recipient with the Mailable’s details. In this example, envelope sets the subject, and the rendered mail.welcome view supplies the body. Laravel then sends the message through the configured mail transport, such as an SMTP server or another mail service. If the email goes to the wrong person, check the Mail::to call. If the subject or body is wrong, check the Mailable and its view.

Choose whether to queue the email

When you queue a Mailable, Laravel leaves it for a background worker to send, so the current request does not wait for delivery. To queue a Mailable explicitly, call queue on the mail call that specifies the recipient:

Mail::to($user->email)->queue(new WelcomeEmail($user->name));

A Mailable can also implement Laravel’s ShouldQueue interface. Laravel then queues it when you send it. The queue connection controls how Laravel handles queued work. When QUEUE_CONNECTION is set to sync, Laravel runs the job immediately instead of handing it to a background worker. Check that setting if a queued email still delays the request. Laravel’s mail configuration guidance discusses sending and queueing mail.

Test what the Mailable sends

Use Mail::fake() in a test to prevent Laravel from delivering real email, then assert that the expected Mailable was sent:

Mail::fake();

// Run the code that sends the email.

Mail::assertSent(WelcomeEmail::class);

This checks that the code sent a WelcomeEmail instance. Add assertions for the recipient or message details when the test needs to check those values. Laravel’s Mailable testing discussion also covers how to check Mailable attributes.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *