display Laravel validation errors with AJAX
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Display Laravel Validation Errors with AJAX: A Complete Guide
When building modern web applications, especially those utilizing Single Page Application (SPA) principles or highly interactive forms, handling form validation errors dynamically is crucial. If you are using Laravel for your backend logic and AJAX for form submissions, itâs common to encounter the challenge of displaying validation messages without a full page reload. While the submission itself might succeed, failing to render those error messages leaves the user confused about why their submission failed or what needs correction.
This guide will walk you through the process of correctly capturing Laravel validation errors returned via AJAX and dynamically rendering them in your HTML using JavaScript and jQuery. This approach ensures a smooth, user-friendly experience, adhering to best practices in modern web development.
## The Challenge with AJAX Error Handling
As many developers have experienced, when an AJAX request fails due to server-side validation (e.g., a `422 Unprocessable Entity` response), the error details are often in JSON format on the server side. Your frontend needs to intercept this data and map those specific errors back to the corresponding input fields so the user can see exactly what went wrong.
The provided setupâwhere you log `xhr.responseJSON.errors` to the consoleâis the correct starting point. The next step is translating that raw JSON into meaningful HTML.
## Step 1: Ensuring Laravel Returns Valid Errors
Before diving into JavaScript, we must ensure your Laravel controller is correctly returning the validation errors in a structured format. When you use `validate()` or manually check request data, Laravel populates the error bag. When an AJAX request fails validation, it typically returns a JSON response detailing these errors.
If your route returns a `422` status code with a JSON body containing the validation messages, your frontend can successfully parse them. For example, if you are using Laravelâs built-in validation features (as advocated by the principles found on [laravelcompany.com](https://laravelcompany.com/docs)), ensure your controller returns an appropriate response structure that includes the errors.
## Step 2: Implementing the AJAX Response Handler (jQuery Example)
The key lies in using the `error` or `success` callback of your AJAX request to parse the JSON data and manipulate the Document Object Model (DOM). We will iterate through the received error object and target the specific fields where those errors belong.
Here is a comprehensive example demonstrating how to handle the response and display the errors inside `
- ` elements next to the input fields.
```javascript
$(document).ready(function () {
$("#submit").click(function (xhr) {
xhr.preventDefault(),
$.ajax({
type: "POST",
contentType: "charset=utf-8",
dataType: 'json',
url: "{{route('messages.store')}}",
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
},
data: {
name: $("#name").val(),
email: $("#email").val(),
phone: $("#company").val(),
subject: $("#subject").val(),
message: $("#message").val()
},
success: function (response) {
// Handle successful response
alert('Form submitted successfully!');
},
error: function (xhr, status, error) {
// Handle validation errors
if (xhr.status === 422 && xhr.responseJSON && xhr.responseJSON.errors) {
console.log("Validation Errors:", xhr.responseJSON.errors);
displayErrors(xhr.responseJSON.errors);
} else {
// Handle other network or server errors
console.error("An unexpected error occurred:", error || xhr.responseText);
}
},
"json"
});
});
});
function displayErrors(errors) {
// Clear previous error messages first
$('.error-message').remove();
// Iterate over the errors object and display them next to the corresponding field
$.each(errors, function(field, messages) {
// Assuming your input fields have IDs matching the error keys (e.g., name, email)
var fieldId = field;
// Find the corresponding input element
var $input = $(`#${fieldId}`);
if ($input.length) {
// Create a container for the errors associated with this field
var errorContainer = $('', { class: 'error-message' });
// Build the list of errors in UL/LI format
var errorList = $('
- ');
$.each(messages, function(index, message) {
errorList.append('
- ' + message + ' '); }); // Append the generated list next to the input field $input.after(errorList); } }); } ``` ## Step 3: Integrating into Your HTML Structure For this script to work, your HTML form structure needs fields with corresponding IDs and a designated place to inject the error messages. ```html