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.