Preview Laravel Email before Sending - PHP, AJAX

Preview Laravel email before sending – PHP, AJAX

Either you are sending an email in Laravel via normal form POST request or via AJAX. This tutorial will help you add functionality where you can preview an email before sending it. If you are adding functionality to your Laravel project where you need to send an email, it is very important during the development to check the preview of mail before sending.

Normally, when you receive the email in your inbox, you can see how it will look to users. But if you haven’t set up your SMTP server for sending emails, then following this tutorial will save you a lot of time during development.

Create a new Laravel project

To create a new Laravel project, open your command prompt or Terminal and run the following command in it:

composer create-project laravel/laravel example-app

This will create a folder named “example-app”. Now, you need to enter this folder using the following command:

cd example-app

When your Terminal is inside this folder, run the following command to start the server:

php artisan serve

Typically, this starts your project at host 127.0.0.1 and port 8000. So you can access it from URL:

http://127.0.0.1:8000

Create Controller and Mailer

Create a new controller using the following command, you can also use your own controller if you want:

php artisan make:controller UserController

Now, open your “routes/web.php” file and create a new route:

// include controller
use App\Http\Controllers\UserController;

// create route
Route::get("/send-mail", [UserController::class, "send_mail"]);

Create a mailer to send mails by running the following command in your Terminal:

php artisan make:mail SendMail

Now, we need to create the following function in “App\Http\Controllers\UserController”:

use Mail;
use App\Mail\SendMail;

class UserController extends Controller
{
    // create method
    public function send_mail()
    {
        // send email
        // preview with dynamic variable data

        $data = "This is a variable.";

        // pass as a parameter
        $mailable = new SendMail($data);
        // Mail::to("recipient@gmail.com")->send($mailable);

        // preview email
        return $mailable->render();
    }
}

Following will be the content of your “App\Mail\SendMail”. You can add all the variables you want to pass in this mailer:

<?php

namespace App\Mail;

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

class SendMail extends Mailable
{
    use Queueable, SerializesModels;

    // class data member
    public $data;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    // parametrized constructor
    public function __construct($data)
    {
        // assign value
        $this->data = $data;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        // create this folder mails
        // and file test.blade.php

        // pass value in view
        return $this->view('mails/test', [
            "data" => $this->data
        ]);
    }
}

At line #40, we need to create a new file in views folder, “resources/views/mails/test.blade.php” and in this file you can write the content of your email. For the sake of understanding, I am writing simple text with variable:

<h1>This is mail:</h1>

<!-- display in mail view -->
Data = {{ $data }}

If you access your browser at “http://127.0.0.1:8000/send-mail”, you will see the content of email with all variables rendered on it.

Preview email from AJAX

If you are sending an email via an AJAX request, then it might be difficult for you during the development to check how the email will look like. You might be sending an email on each test and viewing it from your Gmail inbox to preview the email. But there is a shorter method to do that, and it will surely save your time.

First, create a new route that will render a view file.

// routes/web.php
Route::get("/send-mail-ajax", function () {
    // render view
    return view("send_mail_ajax");
});

Create a file named “send_mail_ajax.blade.php” inside “resources/views” folder and paste the following code in it:

<!-- meta tag for CSRF token -->
<meta name="_token" content="{{ csrf_token() }}">

<!-- hidden input field for base url -->
<input type="hidden" id="base_url" value="{{ url('/') }}" />

<!-- send ajax -->
<script>
    var ajax = new XMLHttpRequest();
    ajax.open("POST", document.getElementById("base_url").value + "/send-mail-ajax", true);

    // when the response is received
    ajax.onreadystatechange = function () {
        if (this.readyState == 4) {
            if (this.status == 200) {
                // display in browser
                document.write(this.responseText);
            }

            // handler error
            if (this.status == 500) {
                console.log(this.responseText);
            }
        }
    };

    var formData = new FormData();
    formData.append("_token", document.querySelector("meta[name=_token]").content);
    ajax.send(formData);
</script>

We have created a meta tag for saving CSRF token which is required for each POST request in Laravel, and a hidden input field that will save the website’s base URL. Then we are sending an AJAX request, and when the response is successfully received then we are displaying that in current web page.

Don’t worry, it will be used just during the development process. Once it is reviewed, then you can comment out that code at line #17.

Create a POST route in “routes/web.php” and it will use the same method in UserController, only the method is set to POST:

// create route
Route::post("/send-mail-ajax", [UserController::class, "send_mail"]);

Try to access the URL at “http://127.0.0.1:8000/send-mail-ajax”, you will first view an empty page then after few seconds, you will see the content of email in your web page.

Let me know if you need any help in following this tutorial.

Leave a Reply

Please disable your adblocker or whitelist this site!