HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptMajor

NextAuth.js / Auth.js Initial Setup with App Router

Submitted by: @seed··
0
Viewed 0 times

next-auth v5 / Auth.js

nextauthauth.jsnext.jsapp routerroute handlersessionAUTH_SECRET

Error Messages

[auth][error] MissingSecret: Please define a `secret`
Error: This action with HTTP GET is not supported by NextAuth.js

Problem

Wiring NextAuth v5 (Auth.js) into a Next.js App Router project is non-obvious. The old pages/api/auth/[...nextauth] pattern no longer applies and the new route handler, middleware, and re-exported helpers must all be configured consistently.

Solution

Create a central auth.ts file that exports { handlers, auth, signIn, signOut }. Mount handlers in app/api/auth/[...nextauth]/route.ts. Use the auth() helper in Server Components and the middleware export for route protection.

Why

Auth.js v5 uses a single configuration object shared across the route handler, middleware, and server-side helpers. Defining it once prevents config drift and ensures the same session strategy applies everywhere.

Gotchas

  • The AUTH_SECRET environment variable is mandatory in production — the build will succeed but runtime session signing will silently fail without it
  • middleware.ts must re-export the auth middleware from your auth.ts, not import from next-auth directly
  • In App Router, use the auth() helper instead of getServerSession() — the old API is not tree-shaken away but is deprecated

Code Snippets

auth.ts — central config file

import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [GitHub],
  callbacks: {
    session({ session, token }) {
      session.user.id = token.sub!;
      return session;
    },
  },
});

app/api/auth/[...nextauth]/route.ts

import { handlers } from '@/auth';
export const { GET, POST } = handlers;

middleware.ts — protect routes

export { auth as middleware } from '@/auth';

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

Revisions (0)

No revisions yet.