Using NextAuth with App Router in Next.js 14 (GitHub OAuth)
Set env vars.
NEXTAUTH_URL=http://localhost:3000
AUTH_SECRET=# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32
# https://next-auth.js.org/providers/github
OAUTH_CLIENT_KEY=
OAUTH_CLIENT_SECRET=
Install next-auth package.
bun add next-auth@5.0.0-beta.3
Create a new file src/app/auth.tsx
and add the following code.
touch src/app/auth.tsx
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
export const {
handlers: { GET, POST },
auth
} = NextAuth({
providers: [
GitHub({
clientId: process.env.OAUTH_CLIENT_KEY as string,
clientSecret: process.env.OAUTH_CLIENT_SECRET as string
})
]
});
Create a new file src/app/api/auth/[...nextauth]/route.ts
and add the following code.
mkdir -p src/app/api/auth/[...nextauth]
touch src/app/api/auth/[...nextauth]/route.ts
// src/app/api/auth/[...nextauth]/route.ts
export { GET, POST } from '@/app/auth';
export const runtime = 'edge';
Create Login component.
touch src/app/components/Login.tsx
// src/app/components/login.tsx
'use client';
import {signOut, signIn} from "next-auth/react";
export function LoginButton({ user }: { user: any }) {
return (
<>
{user ? (
<button onClick={() => signOut()}>Sign out</button>
) : (
<button onClick={() => signIn('github')}>Sign in with github</button>
)}
<div>
{user ? (
<div>
<p>Signed in as {user.email}</p>
<img src={user.image} alt={user.name} />
</div>
) : null}
</div>
</>
);
}
Create Header component.
mkdir src/app/components
touch src/app/components/header.tsx
// src/app/components/header.tsx
import { auth } from '@/app/auth';
import {LoginButton} from "@/app/components/login";
export default async function Header() {
const session = await auth();
return (
<header>
<Login user={session?.user} />
</header>
);
}
Add Header component to layout.
// src/app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "@/app/components/header";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Next Auth Sandbox",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<Header />
{children}
</body>
</html>
);
}
Start the dev server and open http://localhost:3000 to see the app.
bun dev
open http://localhost:3000