< BACK TO THE BLOG

How to override default validation messages in Laravel

Published March 10, 2022

Laravel's validation is one of the most straight forward examples of a validation system, it's feature-rich, has a lot of default rules and they contain clear validation messages for each one of those rules.

However there will always be cases where those messages won't suffice, and it can be beneficial to our UX to write clearer and more concise messages, and therefore we'd have to override the defaults.

Overriding the default message

One way is to change the validation message template across the entire system, this can make sense for email rules for example, as these are generic and are theoritically consistent.

To do that, navigate to your laravel project, and open the file /resources/lang/en/validation.php, this file contains ALL validation messages in the framework, you'll notice these templates use :variable in them, so if you want to use these in your validation you'd have to keep them.

Let's take an example, I want to modify the required_if validation message, by default it looks like this

[
    'required_if' => 'The :attribute field is required when :other is :value.'
]

To modify it I can just replace the value, and I can omit some of the variables or all of them and it will be fine, here's an example

[
    'required_if' => ':attribute must be set when :other is equal to :value.'
]

as a result, all required_if rules will use this template when the validation fails.

Overriding messages for a specific request

There are cases when we want to override the message for a specific rule, but we want to keep the default messages as is.

To do that, we have a few options:

When using a form request class

This is the easiest, when we're using a form request for the validations, we can override the messages method, and in the method we return an associative array where the key represents the rule, and the value represents the message

As an example:

<?php


namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateUserRequest extends FormRequest {
{
    public function rules(): array
    {
        return [
            'email' => ['required', 'email'],
        ];
    }

    public function messages()
    {
        return [
            'email' => 'This must be a valid email!'
        ];
    }
}

Here when the validation fails for any email rule, the overridden message will be used.

When using a validator

In this case, we'll be using the same array that we created in the previous example, but we'll directly use it in the Validator::make() method.

So to cover the same example as above:

<?php

$rules = [
    'email' => ['required', 'email'];
];

$messages = [
    'email' => 'This must be a valid email!'
];

$validator = Validator::make(request()->all(), $rules, $messages);

if ($validator->fails()) {
    return $validator->errors();
}

When using $request->validate() or $this->validate()

The same rules apply for this method as the Validator method, so we'll be creating $rules and $messages arrays and passing them to the validate() method.

So to recreate the same example:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UsersController extends Controller
{
    public function store(Request $request)
    {
        $rules = [
            'email' => ['required', 'email'];
        ];

        $messages = [
            'email' => 'This must be a valid email!'
        ];

        // or $this->validate($request, $rules, $messages);
        $request->validate($rules, $messages);
    }
}