Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

The new alternative mailable syntax in Laravel 9.x

The latest version of Laravel 9.x has just been released and it comes with a lot of new features and improvements. In this article, I’ll talk about one of the new features in Laravel 9.x which is the new alternative mailable syntax.

So, if you’re using Laravel 8.x, you might have used the Mailable class to send emails. For example, you might have used the Mailable class like so.

use Illuminate\Mail\Mailable;

class WelcomeEmail extends Mailable
{
    public function build()
    {
        return $this->from('[email protected]', 'Example')
                ->subject('Welcome to our website')
                ->view('emails.welcome');
    }
}

As you can tell, we can use the Mailable class to send emails. Here, we can use the from(), subject(), and view() methods to set the sender, subject, and view of the email in the build() method. And then, we can use the send() method to send the email like so.

(new WelcomeEmail)->send($user);

Now, if you’re using Laravel 9.x, you can use the new alternative mailable syntax to send emails. The new alternative mailable syntax introduced a new way to define the sender, subject, and view of the email. Let’s see how it works with an example.

The new alternative mailable syntax

If you have upgraded to Laravel 9.x, you can use the new alternative mailable syntax to send emails. So, if you generate a new mailable class using the make:mail command, you’ll get a mailable class that uses the new alternative mailable syntax.

$ php artisan make:mail RenewAccountEmail

This will generate a new mailable class that uses the new alternative mailable syntax like so.

<?php

namespace App\Mail;

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

class RenewAccountEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the message envelope.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Renew Account Email',
        );
    }

    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'view.name',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

As you can tell, the new alternative mailable syntax has introduced a terse syntax to define the sender, subject, and view of the email. So, instead of using the from(), subject(), and view() methods, you can use the envelope() and content() methods to define the sender and the subject of the email. And then, you can use the attachments() method to define the attachments of the email.

The envelope() method

The envelope() method is used to define the sender and the subject of the email. So, if you want to define the sender and the subject of the email, you can use the envelope() method like so.

/**
 * Get the message envelope.
 *
 * @return \Illuminate\Mail\Mailables\Envelope
 */
public function envelope()
{
    return new Envelope(
        subject: 'Renew Account Email',
        from: '[email protected]',
    )
}

As you can tell, from within the envelope() method, you can return a new instance of the \Illuminate\Mail\Mailables\Envelope class with the subject and from properties set. The from property is optional and you can omit it if you don’t want to set the sender of the email.

You can set several other properties like to, cc, bcc, tags, metadata etc on the Envelope class as well.

The content() method

The content() method is used to define the view of the email. So, if you want to define the view of the email, you can use the content() method like so.

/**
 * Get the message content definition.
 *
 * @return \Illuminate\Mail\Mailables\Content
 */
public function content()
{
    return new Content(
        view: 'renew-account-email',
    );
}

As you can tell, from within the content() method, you can return a new instance of the \Illuminate\Mail\Mailables\Content class with the view property set. The view property is required and you can’t omit it.

You can set several other properties like text, markdown, html, and with etc on the Content to set the email content in different formats.

The attachments() method

The attachments() method is used to define the attachments of the email. So, if you want to define the attachments of the email, you can use the attachments() method like so.

/**
 * Get the attachments for the message.
 *
 * @return array
 */
public function attachments()
{
    return [
        'path/to/file' => [
            'as' => 'name.pdf',
            'mime' => 'application/pdf',
        ],
    ];
}

The headers() method

There’s one more optional method that you can use to define the headers of the email. So, if you want to define the headers of the email, you can use the headers() method like so.

use Illuminate\Mail\Mailables\Headers;

public function headers()
{
    return new Headers(
        text: [
            'X-Header-Name' => 'Header Value',
        ],
    );
}

Content-only mailables

With this new alternative mailable syntax, you can also define content-only mailables. So, if you want to define a content-only mailable, you can use the content() method to define the content of the email omitting the envelope() and attachments() methods.

For example, you can define a content-only mailable like so.

<?php

namespace App\Mail;

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

class MaintenenceNotification extends Mailable
{
    use Queueable, SerializesModels;
    
    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'maintenance-notification',
        );
    }
}

In closing

In this article, we have learned how to send emails in Laravel. We have also learned how to use the new alternative mailable syntax introduced in Laravel 9.x to send emails.

The real motivation behind this new syntax according to Taylor Otwell is to inspect mailables in a better way, to separate components of the mailables, and to improve the overall developer experience by leveraging the use of PHP 8’s named parameters.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?