How to Customize Password Reset Error Message in a Laravel Application

Sometimes the default error messages provided by the Laravel framework aren’t sufficiently descriptive, or the application’s content lacks continuity. Here, I will describe how to set up a Laravel application with a custom error copy, or how to make use of the app’s localization features in order to make your messages readable to non-English speakers. Although this article is targeting the Laravel Password Reset functionality, it can easily be applied to other aspects of the application where you have form submission.

Prerequisites: This article presumes that you already know how to create and set up a Laravel application, and that your application has a password reset feature. If this doesn’t apply to you, head to Laravel’s official Documentation pages, where you’ll be guided through the aforementioned processes.

Creating a Custom Validation Message

The password reset form works by submitting the user form input to a route, which is responsible for handling the password reset submission. The form itself contains an email input field, password and confirm password field, and a hidden token field. This passes on the secret token generated by the system and in the password reset link. You must pass this token back along with the user’s input, or the password reset process will not work.

If you look at your applications folder structure, you’ll find that within the “Http/Controllers,” folder there is an “Auth” folder, which holds a ResetPasswordController. If this controller does not exist, you should create it.

The route should accept POST requests to your controller, so add the following snippet to your routes:

Route::post('reset_user_password', 'ResetPasswordController@resetUserPassword');

Next, you will need to point your reset password form’s submit action property to the “reset_user_password” route we created.

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

The next step will give us the ability to create our custom validation message by writing out the following logic inside of the ResetPasswordController’s resetUserPassword method. Your method should accept and use Illuminate/Http/Request; modify the resetUserPassword to look like this:

 public function resetUserPassword(Request $request) {
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
....
}

You could change the validation rules to your heart’s desire, of course. Have a look at the Laravel doc’s validation chapter to see the full extent of what you can do. Our goal here is to just make the validation messages differ from the default copy provided by Laravel.

To achieve this, update the code in your resetUserPassword method once again and give the validate logic an array as a second parameter. This array should be structured according to the validation rules you have set. In our case, we have a presence requirement on the token, the email, and the password. We also make sure that the email format is correct, the password is a minimum of eight characters long, and the user took the time to use the password confirmation field. For each of the rules we could specify a custom message by using the requirement name. Here is what this code looks like:

 $customValidationMessages = [
'token.required' => 'No token no honey!',
'email.required' => 'Who goes there?! Please ensure you provide an email address.',
... 
]

And your resetUserPassword will now look like this:

public function resetUserPassword(Request $request) {
$customValidationMessages = [
'token.required' => 'No token no honey!',
'email.required' => 'Who goes there?! Please ensure you provide an email address.',
'email.email' => 'The :attribute value :input is not a valid email. Make it right and try again!', //notice here we are using dynamic values provided by the form submission.
'password.required' => 'We thought you wanted to change your password. Please provide a new password.',
'password.min' => 'Please provide a password at least 8 characters long. Your account will be safer this way!',
'password.confirm' => 'Nope! You did not confirm you want to use that password. Please confirm your password.'
];

$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
], customValidationMessages);

....
}

That’s it for the custom messages.

What About Localization?

Laravel is great and, as expected, gives us an easy way to retrieve strings in various languages. We just need to set them up. Let’s say you don’t want a custom message for your password reset validation, but you’d rather have the usual message in the supported locale of your user. Inside your resources folder, create (if not already there), a “lang” folder. Within the “lang” folder, create a folder with the name of the language you would like to use.

The language files should return an array of strings defined similarly to how we defined our custom error messages above. Here is what the validation.php file looks like inside:(some code is truncated for brevity). For other languages just follow the same structure and use the desired language.

 <?php

return [
...
'confirmed' => 'The :attribute confirmation does not match.',
'email' => 'The :attribute must be a valid email address.',
...
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
....

Customizing Error Messages

Although I don’t recommend this, you could use the locale to directly customize your error messages. You must be very careful though. Keep in mind that a “min.string” message, for example, modified here for specificity, will be passed back to the user from anywhere in your app where the minimum string size validation rule is used. Do not end up with a, “Your password is too short,” when the user is submitting their mom’s dog’s maiden name. 😉

That’s all, folks! Happy coding!

About Curious Minds
We are a web development firm in New York and Chicago, providing development resources and consulting for websites and mobile apps since 2004.