Laravel Mail overview
In a nutshell
Laravel provides a clean, simple email API powered by the popular Symfony Mailer component. Laravel and Symfony Mailer provide drivers for sending email via SMTP, Mailgun, Postmark, Resend, Amazon SES, and sendmail
, allowing you to quickly get started sending mail through a local or cloud based service of your choice.
Configuration
Laravel’s email services may be configured via your application’s config/mail.php
configuration file. Each mailer configured within this file may have its own unique configuration and even its own unique “transport”, allowing your application to use different email services to send certain email messages. For example, your application might use Postmark to send transactional emails while using Amazon SES to send bulk emails.
Within your mail
configuration file, you will find a mailers
configuration array. This array contains a sample configuration entry for each of the major mail drivers / transports supported by Laravel, while the default
configuration value determines which mailer will be used by default when your application needs to send an email message.
Generate Mailables
When building Laravel applications, each type of email sent by your application is represented as a “mailable” class. These classes are stored in the app/Mail
directory.
php artisan make:mail OrderShipped
Writing Mailables
Once you have generated a mailable class, open it up so we can explore its contents. Mailable class configuration is done in several methods, including the envelope
, content
, and attachments
methods.
envelope
: Theenvelope
method returns anIlluminate\Mail\Mailables\Envelope
object that defines the subject and, sometimes, the recipients of the message.content
: Thecontent
method returns anIlluminate\Mail\Mailables\Content
object that defines the Blade template that will be used to generate the message content.
Configuring the Sender
You can configure the sender in two ways:
Configure HTML view
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
);
}
Configure Text view
return new Content(
html: 'mail.orders.shipped',
text: 'mail.orders.shipped-text'
);
Pass data to views
Via public properties
<?php
namespace App\Mail;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
public Order $order,
) {}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
);
}
}
Via the with
parameter
<?php
namespace App\Mail;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
protected Order $order,
) {}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.orders.shipped',
with: [
'orderName' => $this->order->name,
'orderPrice' => $this->order->price,
],
);
}
}
Generate Markdown Mailables
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
use Illuminate\Mail\Mailables\Content;
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: [
'url' => $this->orderUrl,
],
);
}
Send mail
To send a message, use the to
method on the Mail
facade. The to
method accepts an email address, a user instance, or a collection of users. If you pass an object or collection of objects, the mailer will automatically use their email
and name
properties when determining the email’s recipients, so make sure these attributes are available on your objects. Once you have specified your recipients, you may pass an instance of your mailable class to the send
method:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class OrderShipmentController extends Controller
{
/**
* Ship the given order.
*/
public function store(Request $request): RedirectResponse
{
$order = Order::findOrFail($request->order_id);
// Ship the order...
Mail::to($request->user())->send(new OrderShipped($order));
return redirect('/orders');
}
}
Queue a mail
1. Call Mail#queue()
Mail::to($request->user())
->cc($moreUsers)
->bcc($evenMoreUsers)
->queue(new OrderShipped($order));
This method will automatically take care of pushing a job onto the queue so the message is sent in the background. You will need to configure your queues before using this feature.
2. Make your Mailable class implement the ShouldQueue
contract
use Illuminate\Contracts\Queue\ShouldQueue;
class OrderShipped extends Mailable implements ShouldQueue
{
// ...
}
Queue a mail to be sent after a delay
Mail::to($request->user())
->cc($moreUsers)
->bcc($evenMoreUsers)
->later(now()->addMinutes(10), new OrderShipped($order));
Render a Mailable without sending it
use App\Mail\InvoicePaid;
use App\Models\Invoice;
$invoice = Invoice::find(1);
return (new InvoicePaid($invoice))->render();
Preview Mailables in the browser
Route::get('/mailable', function () {
$invoice = App\Models\Invoice::find(1);
return new App\Mail\InvoicePaid($invoice);
});