Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Translating Validation Messages

Premium
6 min read

In Laravel, majority of validation error messages are good enough:

However, if you change the label, the validation message does not match the label:

Let's see how we can fix this.


Label and Field Name Mismatch - Translated Form Attributes

As the application grows, you'll have cases where the field name and label do not match. For example, I have a field called Order Date on the UI but the form has an ordered_at name:

Blade form

<div class="mt-4">
<x-input-label for="ordered_at" :value="__('Order date')"/>
 
<x-text-input id="ordered_at" class="block mt-1 w-full" type="date" name="ordered_at"
:value="old('ordered_at')"/>
 
<x-input-error :messages="$errors->get('ordered_at')" class="mt-2"/>
</div>

This will result in the following validation message:

The ordered at field is required.

It is not that user-friendly as our name is Order date. Let's fix this by adding the attributes method to our Form Request class:

Form Request Class

use Illuminate\Foundation\Http\FormRequest;
 
class StoreOrderRequest extends FormRequest
{
public function rules(): array
{
return [
'ordered_at' => ['required', 'date'],
// ...
];
}
 
// ...
 
public function attributes(): array
{
return [
'ordered_at' => 'order date',
];
}
}

With this, we've told that once we have a field named ordered_at - its visual representation should be order date. This will result in the following validation message:

The order date field is required.

To go even further, we can use a translation here:

Form Request Class

// ...
public function attributes(): array
{
return [
'ordered_at' => __('Order date'),
];
}

This will result in: The Order date field is required. - matching the label.


Validating Array of Fields

This one is tricky. You might see something like...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

VA
Vilior Alex ✓ Link copied!

Hi Laravel Daily team,

I have been a bit stuck for the past week as i am trying to add multi-language in my laravel, inertia and react app. I have managed to set the locale in my backend and pass all the validation error messages in my front end. i have created a context in my react app and i can translate any static text. I have also been able to translate any validation messages but i need to pass the key. function useBackendTranslations() { function __(key, replacements = {}) { let translation = window._translations[key] || key;

    Object.keys(replacements).forEach((r) => {
        translation = translation.replace(`:${r}`, replacements[r]);
    });
    console.log(window._translations);
    return translation;
}
return { __ };

}

export default useBackendTranslations; wherever i want to use it i import it and cont {} = useBackendTranslations(); in order to get the validation error messages i have to do <p className="text-sm text-red-600 dark:text-red-400 "> {("required", { attribute: "email",})}

and it will display that the email is required depending on the language. Where i struggle is if an input has three validation rules, max:50, min:15, required. Do i need to do the above for each of the validation rules? It does not seem like a good solution to me. Do you guys have any recommendation?

Thank you in advance, Vilior

M
Modestas ✓ Link copied!

Hi, this is a little bit too much to explain but something like this might help:

https://stackoverflow.com/a/55525163/21185594

Or in other words, you are just displaying the attribute: "email" while you should do a for loop there and for each element display an error.

Hope that helps!

VA
Vilior Alex ✓ Link copied!

Thank youfor your response!

PR
Paul Rijke ✓ Link copied!

Excellent stuff here. The one thing that is missing (for me) is how to use translations for a custom rule in the array. Let's say we have a ProductNamesMustNotHaveQInName rule (weird, but just for the sake of it.

In the custom rule, you woul have somthing line if (Str::contains($value, 'Q')) { $fail('The :attribute has a Q in its name'); return; }

How would we translate this then for the array?

M
Modestas ✓ Link copied!

You can set the attribute name inside of your custom rule