Send beautifully formatted emails from your Laravel application using mailable classes, Blade templates, Markdown components, and popular mail services.
Laravel’s mail system is powered by Symfony Mailer and supports SMTP, Mailgun, Postmark, Resend, Amazon SES, and sendmail out of the box.Each type of email you send is represented as a mailable class. Mailables encapsulate all the configuration—who it’s from, the subject, the view, and attachments—in one place.
After installing the package, set MAIL_MAILER in .env to the driver name (mailgun, postmark, resend, or ses) and add the corresponding credentials to config/services.php.
<?phpnamespace App\Mail;use App\Models\Order;use Illuminate\Bus\Queueable;use Illuminate\Mail\Mailable;use Illuminate\Mail\Mailables\Address;use Illuminate\Mail\Mailables\Content;use Illuminate\Mail\Mailables\Envelope;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 envelope. */ public function envelope(): Envelope { return new Envelope( subject: 'Your Order Has Shipped', ); } /** * Get the message content definition. */ public function content(): Content { return new Content( view: 'emails.orders.shipped', ); } /** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */ public function attachments(): array { return []; }}
Public properties of the mailable are automatically available in the Blade view:
{{-- resources/views/emails/orders/shipped.blade.php --}}<p>Your order #{{ $order->id }} has shipped!</p><p>Estimated delivery: {{ $order->estimated_delivery->format('M j, Y') }}</p>
Markdown mailables use Laravel’s pre-built email components to produce responsive, well-designed emails without writing custom HTML.Generate a Markdown mailable:
This creates the mailable class and a Markdown Blade template at resources/views/emails/orders/shipped.blade.php:
<x-mail::message># Order ShippedYour order #{{ $order->id }} has shipped.<x-mail::button :url="route('orders.show', $order)">View Order</x-mail::button>Thanks,<br>{{ config('app.name') }}</x-mail::message>
The content method uses markdown instead of view:
public function content(): Content{ return new Content( markdown: 'emails.orders.shipped', );}
Markdown mailables are the easiest way to create good-looking transactional emails. Laravel handles the responsive HTML and plain-text fallback automatically.
Assert a mailable was sent without actually sending email:
Pest
PHPUnit
use App\Mail\OrderShipped;use Illuminate\Support\Facades\Mail;test('order confirmation is emailed', function () { Mail::fake(); $order = Order::factory()->create(); $this->post("/orders/{$order->id}/ship"); Mail::assertSent(OrderShipped::class, function ($mail) use ($order) { return $mail->order->id === $order->id; });});
use App\Mail\OrderShipped;use Illuminate\Support\Facades\Mail;public function test_order_confirmation_is_emailed(): void{ Mail::fake(); $order = Order::factory()->create(); $this->post("/orders/{$order->id}/ship"); Mail::assertSent(OrderShipped::class, function ($mail) use ($order) { return $mail->order->id === $order->id; });}
<?phpnamespace App\Mail;use App\Models\User;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 WelcomeMail extends Mailable implements ShouldQueue{ use Queueable, SerializesModels; public function __construct( public User $user, ) {} public function envelope(): Envelope { return new Envelope( subject: 'Welcome to '.config('app.name'), ); } public function content(): Content { return new Content( markdown: 'emails.welcome', ); } public function attachments(): array { return []; }}
3
Write the Blade template
{{-- resources/views/emails/welcome.blade.php --}}<x-mail::message># Welcome, {{ $user->name }}!Thanks for signing up. Click below to get started.<x-mail::button :url="url('/')">Go to Dashboard</x-mail::button>Thanks,<br>{{ config('app.name') }}</x-mail::message>
4
Send after user registration
use App\Mail\WelcomeMail;use Illuminate\Support\Facades\Mail;public function store(Request $request): RedirectResponse{ $user = User::create($request->validated()); Mail::to($user)->send(new WelcomeMail($user)); return redirect('/dashboard');}
Notifications
Send multi-channel notifications—email, SMS, Slack, and database—with a single notification class.