Halim liked a comment+100 XP
2mos ago
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
Acceptheader (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:
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Password;
public function store(Request $request)
{
$request->validate([
'email' => ['required', 'email'],
]);
$status = Password::sendResetLink(
$request->only('email')
);
// Check if the request expects JSON
if ($request->expectsJson()) {
if ($status == Password::RESET_LINK_SENT) {
return response()->json([
'status' => __($status),
'message' => 'Password reset link sent!'
]);
} else {
// Use a 422 status for validation-style errors
return response()->json([
'errors' => ['email' => [__($status)]],
'message' => __($status),
], 422);
}
}
// Default (non-AJAX): fallback to previous redirect logic
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()
->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
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/jsonheader.
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.
Halim started a new conversation+100 XP
2mos ago
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);
});
});
Halim started a new conversation+100 XP
2mos ago
I checked the Breeze GitHub repository, and it seems it’s no longer has a doc. They now suggest using the new starter kits, which require you to use either Vue, React, or Livewire.
However, for my app, I only want to use plain PHP (Blade) and possibly install Bootstrap 5 later and vanilla JS, no Tailwind or other frontend frameworks.
In previous Laravel versions, I usually installed Breeze, then removed the Tailwind code and converted everything to Bootstrap.