๐ Auth.js CredentialsProvider Login FlowโโโWith & Without Server Actions
โ Without Server Action
๐ Auth.js CredentialsProvider Login Flow โ With & Without Server Actions in Nextjs Application

โ Without Server Action
When you donโt use a server action, you call signIn directly inside your onSubmit function. Since this is a client component, you need to import signIn from โnext-auth/reactโ. Hereโs an example:
import { signIn } from "next-auth/react";
async function onSubmit(data) {
/** you can use formData here instead of data, or make a FormData with new FormData()
* no problem
* main concern is, you have to provide the signIn email and password somehow
**/
const response = await signIn("credentials", {
email: data.email,
password: data.password,
redirect: false,
});
if (response?.error) {
// Invalid credentials
toast.error("Credentials did not match");
} else {
// Login successful
router.push("/");
}
}
Points to be noted:
- Here, signIn does not throw an error.
- It returns a response object.
- On failure, the object looks like:
{
error: "CredentialsSignin",
code: "credentials",
ok: true,
status: 200
}
With these error, do whatever you want. The logic is upto you!!!
โ With Server Action
When you use a server action, you create a server function that calls signIn:
"use server";
import { signIn } from "@auth";
export async function loginWithCredentials(data) {
return await signIn("credentials", {
email: data.email,
password: data.password,
redirect: false,
/**
* By default, signIn() automatically redirects the user after a successful login.
* This redirect usually goes to "/" (homepage) or the URL defined in `callbackUrl` if provided.
* You can set `callbackUrl` to send the user to a specific page, for example:
* await signIn("credentials", {
* email: data.email,
* password: data.password,
* redirect: true,
* callbackUrl: "/dashboard", // user will go here after login
* });
* Setting `redirect: false` prevents automatic navigation.
* This allows you to handle the response manually in the client,
* check if login succeeded or failed, show a toast, and then redirect programmatically:
* for client component, eg: if (!response.error) router.push("/dashboard");
* for server component, eg: try{...}catch{toast('Error')}
**/
});
}
As it is a server action, you cannot import signIn from โnext-auth/reactโ like before. You should have a auth.js(or anything) file for the configs in the root directory, right? You have it there. Basically you are importing the signIn from there. Although I am assuming you know authjs, but still hereโs an example:
import { MongoDBAdapter } from "@auth/mongodb-adapter";
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import Google from "next-auth/providers/google";
import client from "./lib/db";
import { userModel } from "./models/user-model";
export const {
handlers: { GET, POST },
signIn,
signOut,
auth,
} = NextAuth({
session: {
strategy: "jwt",
},
adapter: MongoDBAdapter(client, { databaseName: "myDB" }),
providers: [
Credentials({
credentials: {
email: {},
password: {},
},
async authorize(credentials) {
if (credentials == null) return null;
const user = await userModel.findOne({ email: credentials.email });
if (user) {
const isMatch = user.password === credentials.password;
if (isMatch) {
return user;
} else {
return null;
}
} else {
return null;
}
},
})
],
});
Then in your client component:
async function onSubmit(data) {
try {
await loginWithCredentials(data);
/** Login successful
* You can do whatever you want here, I am redirecting to my homepage
**/
router.push("/");
} catch (err) {
/** Invalid credentials throw an error here
* You can do whatever you want here, I am showing a toast
**/
toast.error("Credentials did not match");
}
}
Points to be noted:
- With server actions, signIn throws a CredentialsSignin error on invalid credentials if returning null from the authorize function.
- Therefore, try/catch is required to handle failures.
Hope it helped. Thank you for your time.
๋ฉํ๋ฐ์ดํฐ
- post_id
- 6fe8ff5141be
- slug
- auth-js-credentialsprovider-login-flow-with-without-server-actions-6fe8ff5141be
- url
- https://medium.com/@15iezazul/auth-js-credentialsprovider-login-flow-with-without-server-actions-6fe8ff5141be
- canonical_url
- https://medium.com/@15iezazul/auth-js-credentialsprovider-login-flow-with-without-server-actions-6fe8ff5141be
- author_url
- https://medium.com/@15iezazul
- status
- ok
- fetched_at
- 2026-07-17 11:44:46