Sending Email
Laravel's mail layer separates the message definition from the transport. You define a mailable class and a Blade view, then send through SMTP, a local log driver, or a transactional provider.
Configuration
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=mailer@example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="Acme"
During development, set MAIL_MAILER=log to write messages to the log, or use a local mail catcher. Testing against real addresses risks sending accidental messages to customers.
Creating a mailable
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
namespace App\Mail;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Order $order)
{
}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Your order has shipped',
);
}
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: ['trackingUrl' => $this->order->tracking_url],
);
}
}
Sending
use Illuminate\Support\Facades\Mail;
Mail::to($order->user->email)->send(new OrderShipped($order));
Mail::to($user)->cc($accountant)->send(new InvoiceReady($invoice));
Mail::to($user)->queue(new WelcomeEmail($user));
queue() hands the message to the queue worker so the web request does not wait for SMTP. Configure a queue driver and run a worker before relying on it.
Markdown mail
Markdown mailables produce responsive HTML and a plain-text alternative. Components such as buttons, panels, and tables keep messages consistent across clients.
@component('mail::message')
# Hello {{ $user->name }}
Your order is on its way.
@component('mail::button', ['url' => $trackingUrl])
Track package
@endcomponent
Thanks,<br>
{{ config('app.name') }}
@endcomponent
Attachments
public function attachments(): array
{
return [
Attachment::fromStorage('invoices/'.$this->invoice->id.'.pdf')
->as('invoice.pdf')
->withMime('application/pdf'),
];
}
Localization and templates
Mailables are normal classes, so they can use the recipient's locale. Set the locale before sending and pass translated strings into the view.
Deliverability basics
- Use a verified sending domain with SPF, DKIM, and DMARC records.
- Send from a monitored address and set a reply-to when appropriate.
- Keep transactional and marketing mail on separate streams.
- Handle bounces and complaints through your provider's webhooks.
Back to course overview · Previous: File Uploading · Next: Ajax