Using Laravel, I created an app to summarize and chat with YouTube videos. Check it out!
Benjamin Crozat
Laravel

Send emails with Laravel using Mailtrap's SMTP

Ivan Djuric
Ivan Djuric and 1 contributor
Published on Mar 20, 2024 0 comments Edit on GitHub
Send emails with Laravel using Mailtrap's SMTP

Introduction to sending emails in Laravel

In any serious Laravel application, sending emails is crucial. Whether it’s a welcome email, a password reset email, etc., you need to make sure your they’re delivered to the right inbox every time.

One way to achieve this is to write reliable code. Another way is to use a reliable email-sending service.

That’s where Mailtrap comes into play. They provide a free and fast SMTP server for both sending and testing emails with a great delivery rate. Which is perfect to start our journey.

So, without further ado, let’s see how to send emails in Laravel using Mailtrap’s SMTP.

Setting up a Laravel project

Before I show you how to send emails in Laravel, let me show you how to set the project itself up first.

Configuration

Your best friend for configuring Laravel email services will be the config/mail.php file. It contains a mailers configuration array with a sample configuration entry for each major mail drivers/transports supported by Laravel.

The default configuration your new best friend config file has is exactly what determines which mailer will be used by default when you’re sending an email from your Laravel application.

This gives us plenty of flexibility, because thanks to the mailers configuration in the config/mail.php file, we can use different email-sending services for different types of emails.

Generating and writing mailables

In Laravel, a “mailable” class stored in the app/Mail directory represents different types of emails.

Note that you won’t be able to find the app/Mail directory in your application as it’s not present there by default. Instead, it’s generated when you create the first mailable class.

To do this, I used the following command of the Artisan CLI (included in Laravel):

php artisan make:mail MailableName

After creating a mailable class, I was able to see the contents and configure the class itself. For this, I used the methods in the table below:

Method Explanation
Envelope Returns the Illuminate\Mail\Mailables\Envelope object, which defines the subject and the recipients.
Content Returns the Illuminate\Mail\Mailables\Content object, which defines the Blade template used for generating message content.
Attachments Returns an array of attachments.

Sender configuration

Once we have our mailables, we need to specify the sender or the from email address and name. For this, we can either:

  • Specify the sender in the message Envelope object:
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
 
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
   return new Envelope(
       from: new Address('example@example.com', 'Test Sender'),
       subject: 'Test Email',
   );
}
  • Specify the sender in config/mail.php with a global from address:
return [
    'from' => ['address' => 'example@example.com', 'name' => 'App Name']
];

Pro Tip: You should use the global from address if you plan to use it in all of the emails your application sends. I found this quite convenient as it prevented me from having to call from method in each of my mailable classes. On top of that, it served as my default from address as I didn’t specify any other.

How to send email in Laravel using Mailtrap Email Sending SMTP?

And finally, we’ve come to the fun part.

First I’ll show you how to set up Mailtrap as the SMTP in your application/project and then I’ll show you how I created the mailable classes and ran tests.

Insert Mailtrap SMTP credentials

The first thing I did was insert my SMTP mail server credentials provided by Mailtrap Email Sending into the .env of my application.

To do this, all you have to do is create a Mailtrap account, log in, and navigate to Sending Domains under Email Sending. There you need to add and verify your domain, which takes only a few seconds.

If you’re a visual learner, Mailtrap has an easy-to-follow video for you.

Once you’ve verified your domain, Mailtrap will take you to the page from where you can copy the SMTP credentials and easily paste them into your project, app, or email-sending service.

SMTP credentials on Mailtrap.

And here’s what your credentials should look like once you integrate them into your Laravel code:

// .env file

MAIL_MAILER=smtp
MAIL_HOST=live.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=//your username
MAIL_PASSWORD=// your password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME=//your app name

Verify your SMTP setup

Once I inserted the credentials and sent a test mail from my Laravel project, Mailtrap verified my SMTP setup.

Here’s what you should receive as a response if your test email was sent successfully:

  • “250 2.0.0 Ok: queued as …”

Then, simply click on the “Verify Setup,” which will start the verification process.

The “Verify Setup” button on Mailtrap.

Enable Mailtrap tracking settings (optional)

Now, this step is optional, but I highly recommend it as it allows me to monitor my email performance.

Namely, Mailtrap provides you with in-depth analytics through which you can keep an eye out on your opens, clicks, bounces, and more.

Tracking settings on Mailtrap.

Here’s what I see when I open my stats:

Email logs on Mailtrap.

And here’s the stats overview:

Stats overview on Mailtrap.

Create mailable classes

Remember those mailable classes I told you about previously? It’s time to create them with the following command:

php artisan make:mail MyTestEmail

After running this command, you should see the MyTestEmail class under “app/mailMyTestEmail.php”.

Here’s the class code for your convenience:

namespace App\Mail;

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 MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the message envelope.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }

    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'view.name',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

See anything interesting? That’s right, the content() method returns a view. So, let’s go to resources/views and create a new folder with a blade.php file in it.

Ready to finally write some text? You can do so in the blade.php file, likewise:

Now, let’s return to the content() method and replace the name of the view it returned with the name of our newly created one.

You can also make things a bit more dynamic by making your email template/blade.php file include the recipient’s name using the with attribute to pass the name.

Check it out.

namespace App\Mail;

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 MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(private $name)
    {
        //
    }

    /**
     * Get the message envelope.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }

    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }
}

To make this work, I had to make a small change in the test-email.blade.php view file as well. What this does is it allows it to accept the $name variable.

// resources/views/mail/test-email.blade.php

Hey {{$name}}, 
Can your Laravel app send emails yet? 😉 
Mailtrap

And lastly, let’s create a route in the routes/web.php file with this code:

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail;

Route::get('/testroute', function() {
    $name = "Funny Coder";

    // The email sending is done using the to method on the Mail facade
    Mail::to('testreceiver@gmail.com'')->send(new MyTestEmail($name));
});

Here’s how the file should look then:

And, the moment of truth has come. I tested things out by running php artisan serve command and going to my browser, where I pasted the route I created. In my case, it was localhost:8000/testroute.

In case everything works, your email should land in the inbox of the “to” address you specified.

How to send HTML emails in Laravel

Sending attention-grabbing emails in Laravel is quite simple. All you have to do is add HTML code to your Blade view file. If you remember, we used test-email.blade.php in this guide.

And this is how your plain text email should look like in HTML form:

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <style>
            p {
                font-size: 12px;
            }

            .signature {
                font-style: italic;
            }
        </style>
    </head>
    <body>
        <div>
            <p>Hey {{ $name }},</p>
            <p>Can your Laravel app send emails yet? 😉 </p>
            <p class="signature">Mailtrap</p>
        </div>
    </body>
</html>

How to send email with attachments in Laravel

To add attachments to my emails in Laravel, I simply modified the attachments method in the example code for sending emails I showed you earlier.

I first made them in the MyTestEmail class:

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Get the message envelope.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }

    /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Then I made some changes in the testroute code under routes/web.php:

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "Funny Coder";

    Mail::to('testreceiver@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

And that’s pretty much it. If you used this code, your email should now come with an ICO attachment named favicon.ico, as you can see in the snippet above.

How to send emails to multiple recipients in Laravel

To send emails to multiple people in Laravel, I used the following code:

foreach (['First Coder' => 'first-recipient@gmail.com', 'Second Coder' => 'second-recipient@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

What this code does is iterate over an array of recipients. It also re-creates the mailable instance each time, which is super useful as it prevents the sending of another email to every previous recipient at every iteration through the loop. Just imagine the headache. 🤕

“But how do I send emails to just one recipient while also cc-ing and bcc-ing a few others?,” you might be wondering. Simply follow this example in the MyTestEmail class:

return new Envelope(
    subject: 'My Test Email',
    cc: ['testreceiver-cc@gmail.com'],
    bcc: ['testreceiver-bcc@gmail.com']
);

How to test email sending and emails with Mailtrap Email Testing

If you don’t want to have your emails sent from a blacklisted domain, marked as spam, or their HTML template poorly rendered by web browsers, you should test your emails.

Yes, you can do this with your personal inbox, but why affect your domain reputation and floods your inbox with junk, when you can use Mailtrap Email Testing?

Besides allowing you to send emails, Mailtrap also comes with other benefits that can help you solve numerous testing problems while keeping the email testing process secure.

Namely, Mailtrap Email Testing gives you a sandbox where you can catch testing emails and then preview them, check their spam score, analyze their HTML/CSS, and more before you send them out.

The HTML check feature in the test inbox on Mailtrap.

Compared to testing emails with your personal inbox, Mailtrap Email Testing keeps things neatly organized by allowing you to create multiple inboxes for different projects and their stages.

This testing solution also provides you with the original values of email headers and the option to forward your testing emails to whitelisted recipients, either manually or automatically.

And what I like the most about Email Testing is that it will only take you a few minutes to set it all up. All you have to do is:

  • Log in to your Mailtrap account
  • Navigate to Email Testing → Inboxes → SMTP Settings
  • Select the desired Laravel version from the list of integrations

SMTP settings on Mailtrap.

  • Copy the code snippet generated by Mailtrap and paste it into your email-sending script
  • Run the script

As a result, you should get the test email in your Email Testing virtual inbox.

Mailtrap Email Testing will also provide you with SMTP credentials for each of your inboxes, which you can find by clicking on “Show Credentials” on the SMTP Settings page. This way, you can use credentials over code snippets for integrating this testing solution. You can simply copy and paste them into your email-sending script, MTA settings, email client settings, or any system that supports them.

Alternatively, you can also integrate Email Testing into your Laravel app via Mailtrap email API. For more details, check out the official API documentation.

Wrapping up

And that’s it!

I’ve shown you how I send emails in Laravel with Mailtrap SMTP and how I test them with the Email Testing solution.

Hopefully, you’ll be able to use this article as your go-to resource for sending emails in Laravel.

Good luck!


This article was written by Ivan Djuric and 1 contributor

Many thanks to Benjamin Crozat for the help!

Wait, there's more!

Be the first to comment!

Get help or share something of value with other readers!

Great deals for enterprise developers
  • ZoneWatcher
    Get instant alerts on DNS changes across all major providers, before your customers notice.
    25% off for 12 months using the promo code CROZAT.
    Try ZoneWatcher for free
  • Quickly build highly customizable admin panels for Laravel projects.
    20% off on the pro version using the promo code CROZAT.
    Try Backpack for free
  • Summarize and talk to YouTube videos. Bypass ads, sponsors, chit-chat, and get to the point.
    Try Nobinge →
  • Monitor the health of your apps: downtimes, certificates, broken links, and more.
    20% off the first 3 months using the promo code CROZAT.
    Try Oh Dear for free
  • Keep the customers coming; monitor your Google rankings.
    30% off your first month using the promo code WELCOME30
    Try Wincher for free →
The latest community links
- / -