Laravel Sending Emails | The Easiest and Simple Way

Laravel Mail provides functionality to send large number of emails without affecting the performance of the server by using queues in laravel.

Sending emails are generic tasks done my more applications. And core PHP also provides you with a mail() function for sending the email. But developers at laravel made is an interesting and intuitive task when it comes to sending emails.

These may be sending smaller mails, blasting emails to large recipients or dispatching emails as a background task so that they don’t affect or slow down system resources can and will suit different tasks. And developers can easily expand its functionality and build over it.

Laravel Developer has done a very appreciable job and also provided with different drivers and the option of sending emails. Some of those drivers are mailgun, postmark, Amazon SES driver, SMTP etc.

Note

In this post, we’ll be covering topic regarding sending emails through laravel using SMTP services.

Table of Contents

Configuring Mails using SMTP settings

In your project root, you’ll find .env file which consists of all the environment setting for laravel application. There replace MAIL section with below code.

MAIL_DRIVER=smtp
MAIL_HOST=smtp.googlemail.com
MAIL_PORT=587
MAIL_USERNAME=<email ID>
MAIL_PASSWORD=<app-password>
MAIL_ENCRYPTION=tls

The above is a simple and easiest configuration for sending the email. Our email drive in this case is MAIL_DRIVER and I’m using MAIL_HOST of google which provides free SMTP settings for sending an email.
Also, goto this google app password setting page to create an app password for your email as the normal password doesn’t work.

Generating a Mailable class

The best point about laravel mailable is that it keeps code and email template separately and this makes managing multiple email class a simple task.
The below command will generate a mailable class in your project directory laravel_email/app/Mail/WelcomeEmail.php.

php artisan make:mail WelcomeEmail

The newly generated mailable class looks like below.

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

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

    /**
        * Build the message.
        *
        * @return $this
        */
    public function build()
    {
        
    }
}

The __construct() method is a magic method through which parameters can be passed to WelcomeEmail mailable class.
build() method prepares or binds class data to views for sending the email. But does not send unless it is passed through send() method of Mail class.
This method is automatically triggered by the class itself.

In the build() method you have to specify view for this email, from sender information and also must be able to pass variables to views. After modification, our WelcomeEmail class looks like below.

class WelcomeEmail extends Mailable{
    use Queueable, SerializesModels;
    protected $email_data;

    public function __construct($data)
    {
        $this->email_data = $data;
    }

    public function build()
    {
        return $this->from('abc@gmail.com', "From name")
                ->subject("Welcome your registration is successfully completed.")
                ->view('emails.welcome-email-template')->with($this->email_data);
    }
}

Variables passed through constructor are assigned to $this->email_data which are in turn passed to email view through the with() method.

Creating a view for mailable class

Views will be sent are email. It is just a design part where necessary data is displayed.
For creating a view file goto laravel_email/resources/views/emails/welcome-email-template.blade.php.

 
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Welcome Email</title>
        <style>
                .logo{
                    padding: 10px;
                    background-color: #f8f8f4;
                    display: flex;
                }
                .logo p{
                    font-family: sans-serif;
                    font-size: 20px;
                }

                .content{
                    padding: 10px;
                }

                .make_strong{
                    font-weight: bold;
                }
            </style>
    </head>
    <body>
        <table cellpadding="0" cellspacing="0" align="center" bgcolor="#ffffff" width="100%" style="max-width:670px;border:1px solid #e8e8e8">
            <tbody>

                <tr>
                    <td class="logo">
                        <div style="float:left;width:100px;" >
                            <img src="{{url('assets/codelearner-logo.png')}}" alt="" style="width:100%;" border="0" class="">
                        </div>
                        <div style="padding-left: 15px;" >
                            <p>{{$company_name}}</p>
                        </div>
                        <div style="clear:both"></div>
                    </td>
                </tr>

                <tr> 
                    <td>
                        <div class="content" >
                            <p class="make_strong" >Hi {{$user['name']}},</p>
                            <p>Greetings from <span class="make_strong" >{{$company_name}}.</span></p>
                            <p>You'r account has been successfully registered.</p>
                            <a href="#" target="_blank" >Click to Login</a>
                        </div>
                    </td>
                </tr>

                <tr>
                    <td bgcolor="#E0E0E0" valign="center" align="center" height="50" style="color:#000000;font:600 13px/18px Segoe UI,Arial">
                        Copyright © {{$company_name}}, All rights reserved.
                    </td>
                </tr>
            </tbody>
        </table>
    </body>
</html>

Caution

Path and view name of email class must be the same as specified in build() method of WelcomeEmail class else InvalidArgumentException : View not found. an exception will be thrown.

Create Controller

php artisan make:controller HomeController

Define Route

Route::get('email/preview', 'HomeController@previewEmail');

Preview email before sending

previewEmail method take $data as a parameter which consists of information which will be used in views file.

<?php

namespace App\Http\Controllers;

use App\Mail\WelcomeEmail;
use Illuminate\Http\Request;
use Mail;
class HomeController extends Controller
{
    public function previewEmail(Request $request){
        $data = [
            "company_name" => "The Code Learners",
            "user" => [
                "name" => "Pavan Kumar"
            ],
        ];
        return new WelcomeEmail($data);
    }
}   

If just want to see how end-user sees then just return new WelcomeEmail($data) object and respective view for this particular email class will be displayed into the browser.

Caution

The keyword new is used to create a new object of the class. Return object to preview email not the class.

Laravel preview email before sending

Sending email synchronously

Create a route for sending email synchronously.

Route::get('email/send', 'HomeController@sendEmailSynchronously');

For sending emails in synchronous manner use send() method which is provided by Mail facades. You must use mail facade before sending email.
In laravel_email/app/Http/Controllers/HomeController.php

public function sendEmailSynchronously(Request $request){
    $data = [
        "to" => "to-email@example.com",
        "company_name" => "The Code Learners",
        "user" => [
            "name" => "Pavan Kumar"
        ],
    ];
    return Mail::to($data['to'])->cc([])->bcc([])->send(new WelcomeEmail($data));
}

Note

cc() and bcc() methods are optional.

Below will also work and will send an email directly specified as a parameter in to() method.

Mail::to($data['to'])->send(new WelcomeEmail($data));

Udemy Laravel Course for Beginners
Udemy Laravel Course for Beginners

Sending email as queued job

Create a route for sending email as a queued job.

Route::get('email/send-via-queued', 'HomeController@sendEmailQueued');

For sending mails through background process use the queue() method provided by facade Mail insisted of send() method.
What this does is that insisted of sending an email immediately it queues it into a particular connection which must be manually configured.

public function sendEmailQueued(Request $request){
    $data = [
        "to" => "to-email@example.com",
        "company_name" => "The Code Learners",
        "user" => [
            "name" => "Pavan Kumar"
        ],
    ];
    return Mail::to($data['to'])->queue(new WelcomeEmail($data));
}

Using queue() method is faster and robust than using send() during production.

For queueing emails additional configuration must be done manually for more information on the queue you can read our Laravel Jobs and Queues – Configuring, Sending Mail, Dispacting Jobs post.
For official documentation, you can visit Laravel Mails.

Conclusion

You have come to end of Laravel Sending Emails | The easiest and simple way post. Support us by sharing this post which will help us grow and comment if you have any doubts we will reach you soon.

Reference Post