Creating a contact form in your Laravel application is fundamental for engaging with your users. On a website, a good contact form is like a friendly door to have those important conversations. Communication lies at the heart of any successful web presence. Also, you can send an email in Laravel for that contact form. Laravel Mail offers a clean and simple API for sending emails in your web applications. This feature is often used to send user notifications, password reset links, and other transactional emails. Sending an email in Laravel using Gmail makes your experience both efficient and effective. Therefore, in this guide, we’ll explore how Laravel Mail allows easy integration with Gmail.
Let’s quickly take a recap of the result that we are going to build in this tutorial. So, we will build a contact to send an email in Laravel with attachment.
The contact form will have a basic validation and after successful validation, the email will be sent.
Also, the contact form details will be saved to the database.
As soon as the form is submitted, the email will be sent out. As shown in the below screenshot, the email is received with an attachment.
The attachment can be opened as shown below.
Now, let’s implement this functionality in Laravel.
Prerequisites
Before moving ahead with the Laravel Mail setup for a contact form in Laravel 10, you will have to follow the below prerequisites.
- PHP >=8.1
- Composer
- Apache/Nginx Server
- VS Code Editor (Optional)
- MySQL (version > 5)
Step 1 – Project Setup For Laravel Mail
In the very first step, you will have to do the Laravel project setup if you don’t have one. So, for that simply do that using the below command in the terminal.
composer create-project --prefer-dist laravel/laravel laravel-app
Once the Laravel latest version is installed, let’s move to the Database configuration.
Secondly, you will have to create a database and connect that with the Laravel application. So, create that in MySQL and navigate to the project folder. Then inside the .env file, under the DB section, add the database credentials.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_relation
DB_USERNAME=root
DB_PASSWORD=root
Recommended: Efficient Data Retrieval With hasOneThrough Relation in Laravel
Step 2 – Design a Contact Form in Laravel to Send Mail
Next, you will have to design a contact form. Hence, simply create a blade file inside the views folder. So, I’ve created a blade file with the name contact-form.blade.php.
After creating this view, add the below snippet to have a basic contact form.
<!doctype html>
<html lang="en">
<head>
<title>Contact Form | Send Email in Laravel 10</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS v5.3.2 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">Programming Fields</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" aria-current="page" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link {{str_contains(request()->url(), 'contact') ? 'active': ''}}" href="{{route('contact.index')}}">Contacts</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main class="container py-5">
<div class="row">
<div class="col-xl-6 m-auto">
<form action="{{route('contact.store')}}" method="POST">
@csrf
<div class="card shadow">
<div class="card-header">
<h5 class="card-title">Contact Us</h5>
</div>
<div class="card-body">
{{-- Your name --}}
<div class="form-group mb-2">
<label for="userName">Your Name <span class="text-danger">*</span></label>
<input type="text" name="userName" id="userName" class="form-control" value="{{old('userName')}}" />
@error('userName')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
{{-- Your subject --}}
<div class="form-group mb-2">
<label for="subject"> Subject <span class="text-danger">*</span></label>
<input type="text" name="subject" id="subject" class="form-control" value="{{old('subject')}}" />
@error('subject')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
{{-- Your email --}}
<div class="form-group mb-2">
<label for="userEmail">Your Email <span class="text-danger">*</span></label>
<input type="text" name="userEmail" id="userEmail" class="form-control" value="{{old('userEmail')}}" />
@error('userEmail')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
{{-- Your message --}}
<div class="form-group mb-2">
<label for="userMessage">Your Message <span class="text-danger">*</span></label>
<textarea name="userMessage" id="userMessage" class="form-control">{{old('userMessage')}}</textarea>
@error('userMessage')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
{{-- Attachment if any --}}
<div class="form-group mb-2">
<label for="userMessage">Attachment (If any) </label>
<input type="file" name="attachment" id="attachment" class="form-control" />
</div>
</div>
<div class="card-footer">
<div class="form-group mb-2">
<button type="submit" class="btn btn-primary">Send </button>
</div>
</div>
</div>
</form>
</div>
</div>
</main>
<!-- Bootstrap JavaScript Libraries -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous">
</script>
</body>
</html>
In the next step, you’ll have to create a model and migration.
Step 3 – Create a Model, Migration, and a Controller
Open the terminal and hit the below command. This will create a model, a respective migration, and a controller.
php artisan make:model ContactForm -mc
After having these files, let’s add the below schema in migration first.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('contact_forms', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('subject')->nullable();
$table->string('email')->nullable();
$table->text('message')->nullable();
$table->string('attachment')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('contact_forms');
}
};
Thereafter, you will have to add fillable data to the ContactForm model. We are going to store contact form details in the database. Hence, you required a model fillable data as shown below.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ContactForm extends Model
{
use HasFactory;
protected $fillable = [
'name',
'subject',
'email',
'message',
'attachment'
];
}
After that, let’s migrate the above schema using the migrate command.
php artisan migrate
Now, you have the table ready. So, let’s move to the contact form rendering and functionality implementation to send mail in Laravel.
Step 4 – Create a Mail Class in Laravel to Send Mail with Attachment
Laravel provides a mail class to send mail. Therefore, you can create it using the below command.
php artisan make:mail ContactMail
After having the Mail class, let’s add the below functionality.
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Queue\SerializesModels;
class ContactMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public $contact;
public function __construct($contact)
{
$this->contact = $contact;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
from: new Address('fromaddress@mail.com', 'Programming Fields'),
replyTo: [
new Address('replyaddress@mail.com', 'Admin | Programming Fields'),
],
subject: 'Contact Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.contact-template'
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
$attachments = [];
if ($this->contact->attachment) {
$attachments = [
Attachment::fromPath(public_path('/attachments/'.$this->contact->attachment))
];
}
return $attachments;
}
}
In the above Mail class, you will have to add from mail address and replyTo mail address. Also, we have included a mail template to send customized email layouts.
So, let’s create a mail template.
Step 5 – Create an Email Template in Laravel
Inside the views folder, let’s create a new folder named mail and inside this, you will have to create a blade file. Give a name as contact-template.blade.php to the blade file.
After having the contact template blade, you will need to add the below snippet.
<!doctype html>
<html lang="en">
<head>
<title>Contact Form | Email</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div class="container">
<p>Welcome Admin,</p>
<p>You have received an email from- </p>
<p>Name: {{$contact['name']}} </p>
<p>Subject: {{$contact['subject']}} </p>
<p>Email: {{$contact['email']}} </p>
<p>Message: {{$contact['message']}} </p>
<p>Attachment: <a href="{{asset('/attachments/'.$contact['attachment'])}}"> View Attachment </a></p>
</div>
</body>
</html>
We have the email template and mail class ready. Hence, in the next step, you will have to implement the functionality to submit the contact form details. Also, will upload the attachment in the storage folder and that attachment will be attached to the email as well.
Therefore, let’s move ahead to implement this functionality.
Step 6 – Add Functionality to Send Mail in Laravel
Navigate to the controller file, and add the below snippet.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ContactForm;
use Exception;
use App\Mail\ContactMail;
use Illuminate\Support\Facades\Mail;
class ContactFormController extends Controller
{
public function index() {
return view('contact-form');
}
/**
* Function : Store Contact Form
* @param request
* @return response
*/
public function store(Request $request) {
$this->validate($request, [
'userName' => 'required|min:3|string|max:40',
'subject' => 'required|min:3|string|max:100',
'userEmail' => 'required|email',
'userMessage' => 'required|min:20|max:500|string',
'attachment' => 'nullable|mimes:pdf,csv,xls,xlsx,doc,docx|max:2048'
]);
if ($request->hasFile('attachment')) {
$fileName = time().'.'.$request->attachment->extension();
$request->attachment->move('attachments', $fileName);
}
try {
$contact = ContactForm::create([
'name' => $request->userName,
'subject' => $request->subject,
'email' => $request->userEmail,
'message' => $request->userMessage,
'attachment' => $fileName ?? null
]);
if ($this->sendEmail($contact)) {
return back()->with('success', 'Success! your request has been submitted');
}
return back()->with('failed', 'Failed! your request has been submitted');
}
catch (Exception $e) {
\Log::error('Error while storing contact form : ' . $e->getMessage());
}
}
/**
* Function : Send Email
* @param request
* @return true
*/
public function sendEmail($contact) {
try {
return Mail::to($contact->email)->send(new ContactMail($contact));
}
catch (Exception $e) {
\Log::error('Error while sending email : ' . $e->getMessage());
}
}
}
In the next step, you will have to add the route.
Step 7 – Add Web Route to Send Mail in Laravel
So, navigate to the web.php file and add the below routes.
<?php
use App\Http\Controllers\ContactFormController;
use Illuminate\Support\Facades\Route;
Route::controller(ContactFormController::class)->group(function() {
Route::get('contact', 'index')->name('contact.index');
Route::post('contact', 'store')->name('contact.store');
});
After having the routes, you will be able to run the application. But, wait, we are not done yet.
Still, we have to configure the Email Credentials to send the Email in Laravel. So, let’s do that.
Step 8 – Configure Email Setting in Laravel
Look at the .env file and add the credentials as shown below. Here, you will have to replace your username, password, and sender email.
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME={{yourmail@gmail.com}}
MAIL_PASSWORD={{YOUR_PASSWORD}}
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="{{MAILFROMADDRESS}}"
MAIL_FROM_NAME="${APP_NAME}"
That’s it for the functionality. Now, you can run the application to see the result and send the email with the attachment in Laravel.
Conclusion
Finally, we have implemented a functionality to send an email in Laravel 10 with an attachment. We have designed a contact form and through that, we can send an email with an attachment. I hope this tutorial will be helpful to you.
Leave a Reply