Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Halim's avatar

Laravel Breeze Password Reset Request Returns Full Page Instead of JSON

Im using laravel Brezze, but Im using ajax request when click on submit button: here how it looks like the forgot password controller looks like: public function store(Request $request): RedirectResponse { $request->validate([ 'email' => ['required', 'email'], ]);

    // We will send the password reset link to this user. Once we have attempted
    // to send the link, we will examine the response then see the message we
    // need to show to the user. Finally, we'll send out a proper response.
    $status = Password::sendResetLink(
        $request->only('email')
    );
    
    return $status == Password::RESET_LINK_SENT
                ? back()->with('status', __($status))
                : back()->withInput($request->only('email'))
                    ->withErrors(['email' => __($status)]);
}

When I enter an email and submit, the response always comes back with status 200, but it returns the full HTML page instead of a proper AJAX response.

Do I need to change something in my PHP controller to handle this correctly for AJAX?

Here is my js code:

$(document).on('submit', '#forgotPasswordForm', function (e) { e.preventDefault(); const $form = $(this); const $submitBtn = $form.find('button[type="submit"]'); $.ajax({ type: 'post', url: $form.attr('action'), data: $form.serialize(), dataType: 'json', headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), 'Accept': 'application/json', // Essential for Laravel to return JSON }, beforeSend: function() { setButtonLoading($submitBtn); clearValidationErrors($form); } }).done(function(response) { console.log('response: ', response);

}).fail(function(xhr) {
    handleAjaxError(xhr, $form);
}).always(function() {
    clearButtonLoading($submitBtn);
});

});

0 likes
1 reply
LaryAI's avatar
Level 58

Certainly! The issue is that your controller always returns a redirect/HTML response, even if the request comes from AJAX and expects JSON. Laravel determines whether to return JSON or HTML mainly by checking two things in the request:

  • The Accept header (application/json)
  • If the request is AJAX (checks XMLHttpRequest, e.g. X-Requested-With)

Since your JS does send the right headers, you need to modify your controller action to return JSON if the request wants it.

Here’s how you can do it:



Key Points:

  • if ($request->expectsJson()) lets Laravel determine if the request is AJAX/JSON and tailors the response accordingly.
  • For errors, return 422 Unprocessable Entity so your JS .fail() handler catches it.
  • No changes are needed to your JS; your code correctly sets the Accept: application/json header.

Summary:
Update your controller to use JSON responses for AJAX. This way, Laravel Breeze’s password reset endpoint will work seamlessly both via web and AJAX/API.

1 like

Please or to participate in this conversation.