Use the confirmed validation rule:
protected function validator(array $data)
{
// dd($data);
return Validator::make($data, [
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'], // changed here
// 'confirm_password' => ['required', 'string', 'min:8'], // can even remove this
]);
}
But the confirmation field should be named password_confirmation as such:
<div class="form-group">
<label for="password">Password</label>
<input class="form-control @error('password') is-invalid @enderror" name="password" type="password"
required autocomplete="new-password" placeholder="Enter your password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="form-group">
<label for="password-confirm">Confirm password</label>
<input class="form-control" name="password_confirmation" type="password"
required id="password-confirm" autocomplete="new-password" placeholder="Confirm your password">
</div>
Note that I just set the name attribute to password_confirmation as that is what is sent to the server. You can change the id to match it if you want.
Reference: https://laravel.com/docs/8.x/validation#rule-confirmed