Deep Dive Into Custom Validation Error Messages In Laravel

Chimezie Enyinnaya

One of the amazing thing about the Laravel framework is the way its doesn't get in your way while developing with it, despite the fact that it comes with great features out of the box. For most Laravel applications, the default features are fine. But there are times you would want your application to be unique by customizing (which Laravel does seamlessly) those features which are provided by default.

In this tutorial, I will show you how to customize validation error messages in your Laravel applications.

This tutorial assumes that you are familiar with Laravel validation and will not cover it. To get up to speed with Laravel validation, you can check out our tutorial: Laravel Form Validation documentation.

Why Custom Validation Messages

But you said the default features that Laravel provides out of the box are fine? Yeah they are, depending on the type applications. But there are times you'd want your application to have a unique feel that is slightly different from a default Laravel application. That's where custom validation messages comes in. With custom validation messages, you can display validation error messages that is personalized to your application.

Setting Up The Demo Contact Form

For the sake of this tutorial, I will be using the concept of contact form to demonstrate custom validation error messages in Laravel.

Let's create a new Laravel application, I prefer using Laravel installer, you are free to use any method that is most convienient for you.

laravel new laravel-custom-validation-error-messages

I call this demo laravel-custom-validation-error-messages (am kinda bad with names), again feel free to use whatever name you like.

Let's also create the routes for our demo contact form, add the following to your routes file:

// routes/web.php

Route::get('contact', 'ContactsController@showContactForm');
Route::post('contact', 'ContactsController@contact');

Next, let's create a controller with the respective methods to handle the routes we created.

php artisan make:controller ContactsController

Now open the ContactsController and add the code snippets below to it:

// app/Http/Controllers/ContactsController.php

/**
 * Show the contact form
 * 
 * @return Response
 */
public function showContactForm()
{
    return view('contact');
}

The showContactForm() simply load a view contact (which we'll create shortly) that will show the contact form for leaving messages.

Quickly, let's create a view named contact.blade.php inside the view directory and add the code below to it:

// resources/views/contact.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Contact Form</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <style>
        body {
            padding-top: 100px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">

                @if (session('status'))
                    <div class="alert alert-success">
                        {{ session('status') }}
                    </div>
                @endif

                <form action="{{ url('contact') }}" method="POST">

                    {{ csrf_field() }}

                    <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                        <label for="name">Name</label>
                        <input type="text" name="name" class="form-control" value="{{ old('name')}}">

                        <small class="text-danger">{{ $errors->first('name') }}</small>
                    </div>

                    <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                        <label for="email">Email Address</label>
                        <input type="email" name="email" class="form-control" value="{{ old('email')}}">

                        <small class="text-danger">{{ $errors->first('email') }}</small>
                    </div>

                    <div class="form-group{{ $errors->has('message') ? ' has-error' : '' }}">
                        <label for="message">Message</label>
                        <textarea name="message" class="form-control" rows="5">{{ old('message')}}</textarea>

                        <small class="text-danger">{{ $errors->first('message') }}</small>
                    </div>

                    <div class="form-group">
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </div>

                </form>
            </div>
        </div>
    </div>
</body>
</html>

Above is a simple contact form with name, email and message fields.

Back to the ContactsController, add the code below to it:

// app/Http/Controllers/ContactsController.php

/**
 * Handle the actual contacting
 * 
 * @param  Request $request
 * @return Response
 */
public function contact(Request $request)
{
        $rules = [
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required|min:5',
        ];

        $this->validate($request, $rules);

        // send contact details to email address

        return back()->with("status", "Your message has been received, We'll get back to you shortly.");
}

The contact() handles the actual contacting. First, we create an array of validation rules then we pass it to the validate() alongside the form request data. What the validate() does is, validates the form request data against the validation rules set. If everything checks out, execution continues from the next line of code else validation errors are thrown with the appropriate error messages.

Before doing any kind of custom error messages, let's see how the default Laravel validation error messages look like. Let's start our demo contact form:

php artisan serve

and visit http://localhost:8000/contact to see the application in action.

How Laravel Validation Error Messages Work

Like I said earlier, the default validation error messages should be fine for most Laravel applications (well, depending of the type of applications). What Laravel does by default is take the name attribute of each of the form input elements and use them to create error messages depending on the validation rules.

As you can see from the image above, Laravel took the name attributes (in our case, name, email and message) of each input elements of the contact form to create the validation error messages.

But how might we customize Laravel to display our custom validation messages? Well, that is what this tutorial is all about, which I will show you shortly.

Laravel has made customizing its defaults seamless as possible. I will show you two ways in which you can customize validation errror messages in your Laravel applications.

Using Language File

The simplest and straightforward way to customize your validation error messages is through the language file. Laravel by default ships with it, language (English) files. These files can be found in resources/lang/en directory. For this tutorial, we are only concerned with validation.php file.

Going through the language validation file, you can see that there are error messages for each of the validation rules provided by Laravel. Let's take a look at the defaut error message for the required validation rule:

'required' => 'The :attribute field is required.'

As you can see there is an :attribute placeholder that will be substituted with the name attribute of form input elements.

With this, we can easily customize the error message for the required validation rule.

// resources/lang/en/validation.php

'required' => 'The :attribute field can not be blank.'

If we try submiting the contact form now without filling the required fields, you should see our custom validation error message is now taking effect.

But what if I want much more custom messages like We need your email address also..

We can also specify custom validation messages for attributes:

// resources/lang/en/validation.php

'custom' => [
        'email' => [
            'required' => 'We need your email address also.',
        ],
]

The error message from the snippet above will only be applied to the email field as shown in the screenshot below.

If you scroll down to the very bottom the the validation.php language file, you something like:

/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/

'attributes' => []

Let's say we want the name attribute to be display as Full Name instead of name, we simply do:

// resources/lang/en/validation.php

'attributes' => [
        'name' => 'Full Name'
]

This will swap the name :attribute placeholder with Full Name.

All the above works irrespective of whether you are using Form Requests, validate method or even the Validator Facade.

Directly In Code

If what whatsoever reasons you prefer not to use the language file for custom error messages. Another way to implement custom validation error messages in your Laravel applications is to add your custom error messages directly within your codes.

There are two approaches to using this method for custom error messages depending on how you implement validation in your application (that is, whether through Form Requests or validate method/Validator Facade).

First, let's take a look at how we would tackle custom error messages when you are using either validate() or Validator::make(). Both methods accepts four arguments (form request data, validation rules, messages, and custom attributes).

With this, we can easily add custom error messages to our application by passing a third argument to the validate() or Validator:make() containing an array of our custom error messages. Update the ContactsController's contact()with the code below:

// app/Http/Controllers/ContactsController.php

/**
 * Handle the actual contacting
 * 
 * @param  Request $request
 * @return Response
 */
public function contact(Request $request)
{
    $rules = [
        'name' => 'required',
        'email' => 'required|email',
        'message' => 'required|min:5',
    ];

    $customMessages = [
        'required' => 'The :attribute field can not be blank.'
    ];

    $this->validate($request, $rules, $customMessages);

    // send contact details to email address

    return back()->with("status", "Your message has been received, We'll get back to you shortly.");
}

Your custom error messages should now take effect when you try submitting the form without filling the required fields.

We can also specify custom validation messages for specific attributes just as we saw with using language file. Update $customMessages array with the snippet below:

// app/Http/Controllers/ContactsController.php

$customMessages = [
    'name.required' => 'Yo, what should I call you?',
    'email.required' => 'We need your email address also',
    'message.required'  => 'c\'mon, you want to contact me without saying anything?',
 ];

The approach with Form Requests is slightly different. Let's create a Form Request to demonstrate this.

php artisan make:request ContactFormRequest

Let's add our validation rules, paste the code below to the newly created ContactFormRequest file:

// app/Http/Requests/ContactFormRequest.php

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name' => 'required',
        'email' => 'required|email',
        'message' => 'required|min:5',
    ];
}

We created our validation rules within the rules() just as we did in ContactsController controller.

Now let's add our custom validation messages:

// app/Http/Requests/ContactFormRequest.php

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'name.required' => 'Yo, what should I call you?',
        'email.required' => 'We need your email address also',
        'message.required'  => 'c\'mon, you want to contact me without saying anything?',
    ];
}

To implement custom error message when using Form Request, we simply add a messages() to ContactFormRequest. The message() simply returns an array containing our custom validation messages. In our case above, we set custom messages on the required validation rule of each of our input fields (name, email and message).

Now let's make use of the newly created ContactFormRequest in the ContactsController:

// app/Http/Controllers/ContactsController.php

// remember to use ContactFormRequest
use App\Http\Requests\ContactFormRequest;

/**
 * Handle the actual contacting
 * 
 * @param  Request $request
 * @return Response
 */
public function contact(ContactFormRequest $request)
{
    // send contact details to email address

    return back()->with("status", "Your message has been received, We'll get back to you shortly.");
}

You should get the same result as we saw above.

Conclusion

Amazing right? Yeah its amazing. You can see our we have been able to customize our validation error messages without breaking a sweat. I hope you found this tutorial helpful. If you encounter any problem while following along with this tutorial, let's me know through the comment section below.

Chimezie Enyinnaya

Web Developer [PHP Laravel JavaScript NodeJS VueJS|AngularJS] | movie lover | run http://openlaravel.com | blogs at http://itoocode.com