Create & Validate Laravel 8 Contact Form with Send Email

How to Create, Validate a Contact form in Laravel 8 and send an email to admin on successful form submission. Also, store the contact form values in the database.

Contact us form is a vital component of almost every web application; it helps your users communicate directly with you. As soon as they land on the contact page, they see a basic form with the following values: name, email, phone number, subject, & message and fill it and send it across. It enhances the user experience and gets you a business lead, helps solve user queries, or gives you feedback about your product or site.

In this tutorial, you will learn how to create a new laravel app, contact form UI using Bootstrap CSS framework, validating a contact form, sending email to the admin with contact form values using mailtrap app, integrating a mail in a controller class further creating mail view. All these will be covered under one roof.

Laravel Contact Form Example

Here are the step-by-step procedures that will help you create a user-friendly contact form in the Laravel 8 project.

Install Laravel 8 App

The first step begins with creating a new Laravel application, FYI this tutorial focuses on version 8 nonetheless you can use it for previous and future versions:

composer create-project laravel/laravel --prefer-dist laravel-contact-us-example

Adding Database Details in ENV

Once the project has been arranged, on the other hand head over to .env file by the same token add your database name, user name and password:

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=db
DB_USERNAME=root
DB_PASSWORD=

Organize Model and Migrations

Now that you have to generate a database table pour some column values for invoking contact us form:

php artisan make:model ContactUs -m

Go to the given path migrations/create_contact_us_table.php, next put the code within migration file to create contact_us table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateContactUsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('contact_us', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name'); 
            $table->string('email'); 
            $table->string('phone')->nullable(); 
            $table->string('subject')->nullable();
            $table->text('message');            
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('contact_us');
    }
}

Create the $fillable array, put the ContactUs table value inside app/Models/ContactUs.php modal file:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ContactUs extends Model
{
    use HasFactory;
    public $fillable = [
        'name', 
        'email', 
        'phone', 
        'subject', 
        'message'
    ];
}

Run migration with below command:

php artisan migrate

Generating & Organizing Controller

Create a controller where all the logic of showing, storing and validating contact form goes.

From console run the given command to create a new contact controller file:

php artisan make:controller ContactController

Put all the below code in app/Http/Controller/ContactController.php file:

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ContactUs;
use Mail;

class ContactController extends Controller
{

  public function showForm(Request $request) {
    return view('welcome');
  }

  public function storeForm(Request $request) {
      $this->validate($request, [
        'name' => 'required',
        'email' => 'required|email',
        'phone' => 'required',
        'subject'=>'required',
        'message' => 'required'
     ]);

     ContactUs::create($request->all());

    \Mail::send('email', array(
        'name' => $request->get('name'),
        'email' => $request->get('email'),
        'phone' => $request->get('phone'),
        'subject' => $request->get('subject'),
        'form_message' => $request->get('message'),
    ), function($message) use ($request){
        $message->from($request->email);
        $message->to('[email protected]', 'Hello Admin')->subject($request->get('subject'));
    });

    return back()->with('success', 'Thanks for contacting us.');
  }

}

Start with importing ContactUs model, define two functions…

The showForm() function shows the contact us form in view; its view code will go into the welcome blade file.

In the same way, storeForm() handles the contact form validation in laravel not only but also saves the data into the database.

Build Contact Form Email Blade View

You have to create a new resources/views/email.blade.php file; this file decides the structure of mail template particularly for the main inbox:

<h2>Hello User,</h2>
Email received from: {{ $name }}

User information:

Name: {{ $name }}
Email: {{ $email }}
Phone: {{ $phone }}
Subject: {{ $subject }}
Message: {{ $message }}

Thank you

Setting Up Email Server

Email server configuration is required to send emails related to contact form, so register an account at mailtrap.io.

Get your mailtrap username and password additionally put them into the .env configuration file:

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=Mailtrap username
MAIL_PASSWORD=Mailtrap password
MAIL_ENCRYPTION=tls

Laravel Sending Email to Admin

Now that email server, as well as SMTP server configurations, have been put at its place, next you have to update ContactController class. Place the below code, which holds the logic to send email to admin once the contact us form has been successfully submitted.

Update the below code in app/Http/Controller/ContactController.php file:

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ContactUs;
use Mail;

class ContactController extends Controller
{

  public function showForm(Request $request) {
    return view('welcome');
  }

  public function storeForm(Request $request) {
      $this->validate($request, [
          'name' => 'required',
          'email' => 'required|email',
          'phone' => 'required',
          'subject'=>'required',
          'message' => 'required'
       ]);

      Contact::create($request->all());

      \Mail::send('mail', array(
            'name' => $request->get('name'),
            'email' => $request->get('email'),
            'phone' => $request->get('phone'),
            'subject' => $request->get('subject'),
            'message' => $request->get('message'),
        ), function($message) use ($request){
            $message->from($request->email);
            $message->to('[email protected]', 'Hello Admin')->subject($request->get('subject'));
        });      

      return back()->with('success', 'Thanks for contacting!');
  }

}

Fabricate Routes

Now, open routes/web.php config file, import the controller on top, define routes with GET and POST methods.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ContactController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/contact-form', [ContactController::class, 'showForm']);

Route::post('/contact-form', [ContactController::class, 'storeForm'])->name('contact.save');

First routes call the method to display the contact form while other one stores and validates the contact form.

<h2>Hello User,</h2>
Email received from: {{ $name }}

User information:

Name: {{ $name }}
Email: {{ $email }}
Phone: {{ $phone }}
Subject: {{ $subject }}
Message: {{ $form_message }}

Thank you

Create & Validate Laravel 8 Contact Form

This segment comprises of two steps, first one is for creating a form in blade view with Bootstrap 4. Whereas, second one focuses on validating a contact form and displaying errors in blade view.

So, go ahead put the given below code in views/welcome.blade.php file:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel Contact Form Example</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>

<body>
    <div class="container pt-5" style="max-width: 500px">

        <!-- Alert User -->
        @if(Session::has('success'))
            <div class="alert alert-success">
                {{Session::get('success')}}
            </div>
        @endif

        <form action="" method="post" action="{{ route('contact.save') }}">
            @csrf

            <div class="form-group">
                <label>Name</label>
                <input type="text" class="form-control" name="name" id="name">

                <!-- Show error -->
                @if ($errors->has('name'))
                    <div class="alert alert-danger">
                        {{ $errors->first('name') }}
                    </div>
                @endif
            </div>

            <div class="form-group">
                <label>Email</label>
                <input type="email" class="form-control" name="email" id="email">

                <!-- Show error -->
                @if ($errors->has('email'))
                    <div class="alert alert-danger">
                        {{ $errors->first('email') }}
                    </div>
                @endif                
            </div>

            <div class="form-group">
                <label>Phone</label>
                <input type="text" class="form-control" name="phone" id="phone">

                <!-- Show error -->
                @if ($errors->has('phone'))
                    <div class="alert alert-danger">
                        {{ $errors->first('phone') }}
                    </div>
                @endif                                
            </div>

            <div class="form-group">
                <label>Subject</label>
                <input type="text" class="form-control" name="subject" id="subject">

                <!-- Show error -->
                @if ($errors->has('subject'))
                    <div class="alert alert-danger">
                        {{ $errors->first('subject') }}
                    </div>
                @endif                 
            </div>

            <div class="form-group">
                <label>Message</label>
                <textarea class="form-control" name="message" id="message" rows="5"></textarea>

                <!-- Show error -->
                @if ($errors->has('message'))
                    <div class="alert alert-danger">
                        {{ $errors->first('message') }}
                    </div>
                @endif                    
            </div>

            <input type="submit" name="send" value="Send" class="btn btn-dark btn-block">
        </form>
    </div>
</body>

</html>

Run the project with given command:

php artisan serve

Check the links to view, submit, send mail and store the contact form data:

http://127.0.0.1:8000/contact-form

Summary

Thats all, folks. Now you can start the project and your local server to test the contact form; it will send mail to admin on successful form submission.

Download code: https://github.com/remotestack377/laravel-contact-us-example