Sending Emails in Laravel 13: Mailables, Queuing, and Resend

January 19, 2024 · 6 min read

2026 UPDATE - LARAVEL 13
We’re excited to announce that we have updated all of our blog post examples to reflect the new Laravel 13 version! Our previous examples were based on Laravel 10, but with the release of Laravel 13, we wanted to ensure that our readers have access to the most up-to-date information and examples.
Email communication with Laravel
Whether you're sending out newsletters, post notifications, or password reset links, email communication is a staple of any application. Laravel simplifies the process of sending emails with its clean, expressive API and support for a variety of mail services.
Understanding email configuration in Laravel
Before you start sending emails, you'll need to configure your mail service in Laravel. The framework supports several drivers out of the box, including SMTP, Mailgun, Postmark, Amazon SES, and since Laravel 13, Resend. You can set up your mail configuration in the config/mail.php file and your .env file with details like your mail server, port, username, and password.
Here's an example .env configuration for an SMTP server using Mailtrap:
// Other options
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_mailtrap_username
MAIL_PASSWORD=your_mailtrap_password
// Other optionsLocal email testing with Mailpit
For local development, Laravel ships with Mailpit as the default mail catcher. Mailpit is a lightweight local SMTP server that captures all outgoing emails from your application and displays them in a web interface, without actually delivering them to real inboxes.
If you use Laravel Sail, Mailpit is already included. The web interface is available at http://localhost:8025. Your .env file in a fresh Laravel 13 app comes pre-configured for Mailpit:
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=nullStart Mailpit alongside your application with php artisan serve (when using Sail it starts automatically). Any emails sent by your application will appear at http://localhost:8025 instead of being delivered.
Note: Mailpit replaces Mailhog, which was previously the standard local mail catcher. If you have older projects using Mailhog, switch the host/port to the Mailpit defaults above.
Creating Mailables
In Laravel, each type of email sent by your application is represented as a "Mailable" class. You can generate a new mailable using the command:
php artisan make:mail NewPostPublished
This command creates a new mailable class in the app/Mail directory. Within this class, you define the content and configuration of your email. Here's a simple example:
namespace App\Mail;
use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NewPostPublished extends Mailable
{
use Queueable, SerializesModels;
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function build()
{
return $this->view('emails.posts.published')
->subject('A New Post Has Been Published')
->with([
'title' => $this->post->title,
'content' => $this->post->content,
]);
}
}In the build method, you specify the view that will be used as the email's content and pass any necessary data to the view.
Markdown Mailables
Laravel supports Markdown-based email templates, which give you access to pre-built email components like buttons, panels, and tables that are already styled for email clients. Generate a Markdown mailable with:
php artisan make:mail NewPostPublished --markdown=emails.posts.published
This creates both the mailable class and a Blade view in resources/views/emails/posts/published.blade.php. The view uses Laravel's Markdown mail components:
<x-mail::message>
# A New Post Has Been Published
We wanted to let you know that **{{ $title }}** has just been published.
<x-mail::button :url="$url">
Read the Post
</x-mail::button>
Thanks,
{{ config('app.name') }}
</x-mail::message>Sending emails
To send an email, you use the Mail facade with the send method, passing in the mailable instance:
namespace App\Http\Controllers;
use App\Jobs\SendNewPostNotification;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request)
{
// Other stuff
// Store the blog post...
$post = Post::create($request->all());
// Send the email
Mail::to('email@example.com')->send(new NewPostPublished($post));
// Other stuff
}
}This code is placed in a part of your application where the email should be sent, such as after a new post is created.

Queueing Emails
Sending emails synchronously during a request can slow down your application. Laravel allows you to queue emails for background sending, improving response time for your users:
namespace App\Http\Controllers;
use App\Jobs\SendNewPostNotification;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request)
{
// Other stuff
// Store the blog post...
$post = Post::create($request->all());
// Send the email
Mail::to('email@example.com')->queue(new NewPostPublished($post));
// Other stuff
}
}To process queued emails, make sure you have set up your queue driver and are running a queue worker as we explained in a previous article.
Queueing via ShouldQueue on the Mailable
An alternative to calling ->queue() on the Mail facade is to implement the ShouldQueue interface directly on the Mailable class. When you do this, calling Mail::to(...)->send() will automatically queue the email:
use Illuminate\Contracts\Queue\ShouldQueue;
class NewPostPublished extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
// The rest of the class stays the same.
// Calling Mail::to(...)->send(new NewPostPublished($post))
// will now automatically queue the email.
}This approach is cleaner when you always want a particular email to be queued, regardless of how it is dispatched in your controllers.

Sending Emails via Resend in Laravel 13
Laravel 13 ships with a native Resend mail driver. Resend is a developer-focused transactional email service with a simple API, generous free tier, and strong deliverability. To use it, set the following in your .env:
MAIL_MAILER=resend
RESEND_KEY=re_your_api_key_hereYou do not need to install any extra package, the driver is built into Laravel 13. Get your API key from resend.com and set it as the RESEND_KEY environment variable. Make sure your sending domain is verified in the Resend dashboard.
On Laravel 11 or 12, you can use Resend by installing the resend/laravel package from Composer, which provides the same driver.
Testing emails with Mail::fake()
Laravel provides a Mail::fake() helper that prevents emails from actually being sent during tests. You can then assert that specific mailables were sent:
use Illuminate\Support\Facades\Mail;
use App\Mail\NewPostPublished;
public function test_email_is_sent_on_post_creation(): void
{
Mail::fake();
// Trigger the action
$this->post('/posts', ['title' => 'Hello World', 'content' => 'Content here']);
// Assert a mailable was sent to the correct address
Mail::assertSent(NewPostPublished::class, function ($mail) {
return $mail->hasTo('email@example.com');
});
// Assert a mailable was NOT sent
Mail::assertNotSent(AnotherMailable::class);
}If you want to test that an email was queued rather than sent immediately, use Mail::assertQueued() instead.
Conclusion
Sending emails in Laravel is a straightforward process that can greatly enhance the functionality of your application. Whether it's for user registration, post notifications, or marketing campaigns, Laravel's built-in email capabilities provide you with the tools to communicate effectively with your readers.
Upcoming Articles in the Series
This article is part of our series Laravel for Beginners: A Step-by-Step Guide to Learn the Concepts.
Bring Your Ideas to Life 🚀
If you need help with a Laravel project let's get in touch.
Lucky Media is proud to be recognized as a leading Laravel Development Agency
Frequently Asked Questions
What is the best mail driver for Laravel in production?
For transactional email in production, dedicated sending services like Resend, Mailgun, Postmark, or Amazon SES are strongly preferred over raw SMTP. They provide high deliverability, bounce and complaint handling, and detailed analytics. Laravel 13 includes a native Resend driver, set MAIL_MAILER=resend and add your RESEND_KEY to get started with no extra packages.
How do I test emails locally in Laravel?
Use Mailpit, which is the default local mail catcher shipped with Laravel Sail. Mailpit captures all outgoing emails and shows them in a browser UI at http://localhost:8025. No emails are actually delivered. Your fresh Laravel app already has the Mailpit SMTP settings in .env by default. For automated tests, use Mail::fake() to assert mailables without sending anything.
How do I queue emails in Laravel?
You have two options. First, call Mail::to(...)->queue(new YourMailable()) instead of ->send(). Second, implement the ShouldQueue interface on the Mailable class itself, which makes ->send() queue automatically. Either way, make sure your QUEUE_CONNECTION is set to something other than sync and that a queue worker is running.
What is the difference between a Mailable and a Notification in Laravel?
A Mailable is a dedicated class for a single email, it gives you full control over the template, subject, attachments, and headers. A Notification is a higher-level abstraction that can send messages across multiple channels (email, SMS, Slack, database) from a single class. For email-only communication, Mailables are more straightforward. For multi-channel alerts tied to a user or model event (such as a password reset or order shipped), Notifications are the better choice.
Technologies

Stay up-to-date
Be updated with all news, products and tips we share!
On this page
- 2026 UPDATE - LARAVEL 13
- Email communication with Laravel
- Understanding email configuration in Laravel
- Local email testing with Mailpit
- Creating Mailables
- Markdown Mailables
- Sending emails
- Queueing Emails
- Queueing via ShouldQueue on the Mailable
- Sending Emails via Resend in Laravel 13
- Testing emails with Mail::fake()
- Conclusion
- Upcoming Articles in the Series
- Bring Your Ideas to Life 🚀
- Frequently Asked Questions

