Mailing in Laravel
Laravel provides a clean, simple API for sending emails through various delivery services. The mail system is built on Symfony Mailer and supports SMTP, Mailgun, Postmark, and more.
You configure your mail settings in the config/mail.php file. Set your default driver, SMTP host, port, and credentials there.
Creating a Mailable
A Mailable is a class that defines how an email should be constructed. Generate one with artisan.
php artisan make:mail WelcomeMail
The build() method is where you define the email subject, from address, and view. You can return a view or a markdown template.
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class WelcomeMail extends Mailable
{
use Queueable, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function build()
{
return $this->subject('Welcome to Our App')
->from('hello@example.com')
->view('emails.welcome');
}
}
The $user property is automatically available in the email view since it is public. Laravel makes this easy.
Sending Emails
Once you have a Mailable class, sending it is straightforward. Use the Mail facade or the to() method on the Mailable itself.
use App\Models\User;
use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Mail;
$user = User::find(1);
Mail::to($user->email)->send(new WelcomeMail($user));
You can also chain multiple recipients or send to multiple addresses at once.
Mail::to('admin@example.com')
->cc('manager@example.com')
->bcc('archive@example.com')
->send(new WelcomeMail($user));
The send method is synchronous by default. For better performance in production, consider queuing your mail.
Markdown Mailables
Laravel offers markdown-based mailables that come with pre-built components for common email patterns like buttons, panels, and tables.
namespace App\Mail;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public $order;
public function __construct(Order $order)
{
$this->order = $order;
}
public function build()
{
return $this->subject('Your Order Has Shipped')
->markdown('emails.orders.shipped');
}
}
In your blade view, use the @component directive to access components like @component('mail::message'), @component('mail::button'), and @component('mail::table').
Attachments and Queueing
You can attach files to your emails using the attach() method. Attachments can come from storage or from raw data.
public function build()
{
return $this->subject('Your Invoice')
->view('emails.invoice')
->attach(storage_path('invoices/invoice-1.pdf'), [
'as' => 'invoice.pdf',
'mime' => 'application/pdf',
]);
}
To queue a mailable, implement the ShouldQueue interface. The email will then be sent in the background through your queue workers.
use Illuminate\Contracts\Queue\ShouldQueue;
class WelcomeMail extends Mailable implements ShouldQueue
{
// everything works the same
}
Queueing mail is recommended for production environments where you do not want users waiting for email delivery.