Authentication is a critical part of any web applicationβand with tools like NextAuth.js, adding secure, flexible, and production-ready authentication to your React app has never been easier.
In this post, youβll learn how to set up NextAuth.js with a Next.js React project, allowing users to sign in with providers like GitHub or Google, or even with custom credentials. By the end, youβll have a fully functional auth system in placeβready to go live.
π§ What is NextAuth.js?
NextAuth.js is a complete open-source authentication solution for Next.js applications. It handles:
- OAuth logins (Google, GitHub, etc.)
- JWT/session management
- Database adapters (PostgreSQL, MongoDB, Prisma, etc.)
- Custom credential logins
βοΈ What Youβll Need
- Basic React and Next.js knowledge
- Node.js + npm installed
- A GitHub or Google OAuth app (optional)
- A new or existing Next.js project
π Step 1: Create a New Next.js Project
npx create-next-app@latest my-nextauth-app
cd my-nextauth-app
Install required packages:
npm install next-auth
ποΈ Step 2: Create the API Route
Create a file at:
/pages/api/auth/[...nextauth].ts
(or .js
if youβre not using TypeScript)
Paste this code to add GitHub as a provider:
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';
export default NextAuth({
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID || '',
clientSecret: process.env.GITHUB_SECRET || '',
}),
],
secret: process.env.NEXTAUTH_SECRET,
});
Make sure to create a .env.local
file in the root:
GITHUB_ID=your_github_client_id
GITHUB_SECRET=your_github_client_secret
NEXTAUTH_SECRET=some-long-random-string
Use GenerateSecret to get a secure secret string.
π§ͺ Step 3: Add the Auth Provider in _app.tsx
Open your /pages/_app.tsx
file and wrap your app with SessionProvider
:
import { SessionProvider } from 'next-auth/react';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<SessionProvider session={pageProps.session}>
<Component {...pageProps} />
</SessionProvider>
);
}
π€ Step 4: Add Sign In / Sign Out Buttons
Create a simple component in pages/index.tsx
:
import { signIn, signOut, useSession } from 'next-auth/react';
export default function Home() {
const { data: session } = useSession();
if (session) {
return (
<div>
<h1>Welcome, {session.user?.name}</h1>
<p>{session.user?.email}</p>
<button onClick={() => signOut()}>Sign Out</button>
</div>
);
}
return (
<div>
<h1>Please sign in</h1>
<button onClick={() => signIn('github')}>Sign In with GitHub</button>
</div>
);
}
π Step 5: Protect Routes (Optional)
To protect a page, check for a session:
import { getSession } from 'next-auth/react';
export async function getServerSideProps(context) {
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: '/api/auth/signin',
permanent: false,
},
};
}
return {
props: { session },
};
}
π Optional: Use Custom Credentials
Add this to your [...nextauth].ts
config:
import CredentialsProvider from 'next-auth/providers/credentials';
CredentialsProvider({
name: 'Credentials',
credentials: {
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
if (credentials?.username === 'admin' && credentials?.password === 'admin') {
return { id: 1, name: "Admin", email: "[email protected]" };
}
return null;
}
})
Then call signIn('credentials')
with custom inputs.
π¦ Bonus Tips
- β Add more providers (Google, Facebook, etc.) in the same way
- π οΈ Use a database adapter (Prisma, MongoDB) to persist sessions and users
- π
Style the default sign-in page with a custom
signIn
callback or override the UI - π Use environment variables for secretsβnever hard-code them
π― Conclusion
NextAuth.js is one of the easiest ways to implement full-featured authentication in your Next.js + React app. With just a few lines of code, you get OAuth, session handling, and extensibility built in.
Whether youβre building a portfolio project or launching a SaaS app, NextAuth.js can scale with you.