Sign In with Credentials
The field names passed to signIn("credentials", ...) must match the configured provider fields. With redirect: false, handle the returned result and show a generic error. The actual password verification occurs server-side in authorize.
Credentials form
import { useState } from "react";
import { signIn } from "next-auth/react";
export default function CredentialsForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [busy, setBusy] = useState(false);
async function submit(event) {
event.preventDefault();
setError("");
setBusy(true);
try {
const result = await signIn("credentials", {
email, password, redirect: false, callbackUrl: "/dashboard",
});
if (result?.error) setError("Invalid email or password.");
else if (result?.url) window.location.assign(result.url);
} catch {
setError("Unable to sign in. Please try again.");
} finally {
setBusy(false);
}
}
return <form onSubmit={submit}>
<label>Email <input type="email" autoComplete="email" required value={email} onChange={e => setEmail(e.target.value)} /></label>
<label>Password <input type="password" autoComplete="current-password" required value={password} onChange={e => setPassword(e.target.value)} /></label>
<button disabled={busy}>{busy ? "Signing in…" : "Sign in"}</button>
{error && <p role="alert">{error}</p>}
</form>;
}💡 Do not log the form values. This example uses a generic error message and a loading state.