Skip to content

NextAuth.js (Auth.js)

NextAuth.js, now developed under the name Auth.js, is the most widely used authentication library in the Next.js ecosystem. This lesson covers a basic App Router setup with a credentials or OAuth provider.

Setting Up Auth.js in the App Router

Auth.js centers around a configuration object where you define one or more "providers" (Google, GitHub, email/password credentials, and many others), plus optional callbacks for customizing session and token behavior. A single Route Handler at app/api/auth/[...nextauth]/route.ts (or the newer auth.ts config file pattern) wires everything together.

Once configured, Auth.js exposes helper functions — auth() for reading the current session in Server Components, and signIn()/signOut() for triggering authentication flows from Client Components.

// auth.ts (project root)
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [GitHub],
});

// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth";
export const { GET, POST } = handlers;

This minimal setup enables "Sign in with GitHub" across the app, with auth, signIn, and signOut available wherever needed.

Reading the Session

// In a Server Component
import { auth } from "@/auth";

export default async function ProfilePage() {
  const session = await auth();
  if (!session) return <p>Not signed in.</p>;
  return <p>Signed in as {session.user?.email}</p>;
}
  • auth() is callable directly inside Server Components, Route Handlers, and middleware.
  • signIn(providerId) and signOut() are typically called from Client Components in response to a button click.
  • Provider configuration (client IDs/secrets) belongs in environment variables, never hardcoded.
  • Sessions can be JWT-based (default, stateless) or database-backed, depending on your configuration.

Auth.js Cheat Sheet

Core exports and where to use them.

Export Used In
auth() Server Components, Route Handlers, middleware
signIn(provider) Client Components (button click handlers)
signOut() Client Components
handlers (GET/POST) The catch-all auth Route Handler
providers Configuration array of enabled auth methods

A Sign-In Button

Triggering a provider's sign-in flow from the UI is a small Client Component calling signIn(), typically with the specific provider's ID as an argument.

"use client";
import { signIn } from "@/auth";

export default function SignInButton() {
  return <button onClick={() => signIn("github")}>Sign in with GitHub</button>;
}

Combining with Middleware

Auth.js exports an auth helper usable directly inside middleware.ts, letting you redirect unauthenticated visitors away from protected sections in one central place, in addition to (not instead of) checks inside the routes themselves.

// middleware.ts
export { auth as middleware } from "@/auth";

export const config = {
  matcher: ["/dashboard/:path*"],
};

Common Mistakes

  • Hardcoding OAuth client secrets directly in source code instead of environment variables.
  • Forgetting to configure the OAuth provider's callback URL to match your app's actual domain.
  • Relying only on middleware for protection, without an authoritative check inside protected routes.
  • Not setting AUTH_SECRET (or the equivalent), which is required for signing sessions securely.

Key Takeaways

  • Auth.js (NextAuth.js) provides a complete, provider-based authentication solution for Next.js.
  • auth(), signIn(), and signOut() are the primary functions you'll use throughout an app.
  • A single catch-all Route Handler wires up all configured providers.
  • Auth.js integrates with middleware for centralized route protection.
  • Provider secrets belong in environment variables, never committed to source control.

Pro Tip

Read Auth.js's official documentation for your specific framework version before starting — its configuration API has evolved across major versions (including the rename from NextAuth.js to Auth.js), and following an outdated tutorial is a common source of confusing setup errors.