Use the NextAuthOptions type imported from 'next-auth': export const authOptions: NextAuthOptions = { ... }
NextAuth.js FAQ & Answers
100 expert NextAuth.js answers researched from official documentation. Every answer cites authoritative sources you can verify.
Jump to section:
Next.js App Router Integration > Server Components
5 questionsThe auth() function returns null when there is no authenticated session.
Check the session returned from auth() and use Next.js redirect(): if (!session) { return redirect('/api/auth/signin') }
Database adapters should be installed from the @auth/-adapter scope instead of @next-auth/-adapter. Example: @auth/prisma-adapter
No, you don't need to pass any parameters when calling await auth() in Server Components.
Security > Production Checklist
4 questionsThe Credentials provider can only be used if JSON Web Tokens are enabled for sessions because users authenticated this way are not persisted in the database.
No, if you are using the Essential Next.js Build Plugin within your project, you do not need to set the NEXTAUTH_URL environment variable as it is set automatically as part of the build process. However, you will want to make sure you add your NEXTAUTH_SECRET environment variable in the project settings.
The functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
NEXTAUTH_SECRET (or AUTH_SECRET in newer versions) is required in production. Not providing any secret or NEXTAUTH_SECRET will throw an error in production.
Next.js App Router Integration > Middleware Protection
4 questionsgetToken() supports options including: secret (for token encryption), cookieName (to specify custom session token cookie name), secureCookie (boolean for secure prefixed cookie names), and raw (to get raw token without decrypting).
The withAuth function augments the Request with req.nextauth.token, which contains the user's decoded JWT token.
You can customize signIn, signOut, error, verifyRequest, and newUser pages. For example: pages: { signIn: "/login", error: "/error" }
Following the process to remove Edge Runtime errors in middleware results in no database access in the middleware, resulting in no ability to protect resources at the middleware level. This requires using JWT for storing the session and limits the middleware to just checking data stored in the JWT.
OAuth Providers > Google Provider
4 questionsYes, Google will reject the OAuth request if the redirect URI isn't an exact match. Even small differences like trailing slashes or query params will cause failure.
"openid email profile" (which maps to https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email)
profile.sub (the unique identifier from Google's OAuth provider)
API and Client Methods > signIn Method
4 questionsYes, the signIn() method ensures the user ends back on the page they started on after completing a sign in flow, by defaulting the callbackUrl to the page URL the sign-in is initiated from.
Yes, the Email provider requires a database and cannot be used without one. It is not possible to enable email sign in without using a database.
In v5, signIn is exported from the main NextAuth configuration along with auth, handlers, and signOut. It can be used in Server Actions with 'use server' directive and supports both server-side and client-side usage. The configuration is now in a file named auth.ts in the root of your repository.
Yes, the signIn() method will handle CSRF Tokens automatically when signing in with email.
API and Client Methods > signOut Method
3 questionsNextAuth's signOut endpoint requires the POST HTTP method. This is a security measure to prevent malicious links from triggering sign out without consent through simple GET requests.
In NextAuth v4, import signOut from 'next-auth/react': import { signOut } from "next-auth/react"
You can pass a callbackUrl parameter: signOut({ callbackUrl: 'http://localhost:3000/foo' })
OAuth Providers > GitHub Provider
3 questionsYou must add the "user" scope to your configuration. The default scope only provides read-only access ("read:user user:email"), so if you need write access, you have to explicitly configure it.
For Next.js, the callback URL format is [origin]/api/auth/callback/github. For example: http://localhost:3000/api/auth/callback/github for local development or https://example.com/api/auth/callback/github for production.
OAuth Providers > Microsoft/Azure AD
3 questionsNo, access_token and refresh_token are not persisted by default and must be manually saved in the jwt callback.
The offline_access scope is used to request a Refresh Token but is never returned as a scope because it cannot be part of the access token itself.
Next.js App Router Integration > Client Components
3 questionsuseSession accepts a required parameter (boolean) and an onUnauthenticated callback function. When required: true, it ensures a valid session, and onUnauthenticated() is called when the user is not authenticated (default behavior redirects to sign-in page).
No, the
By default, only URLs on the same origin as the site are allowed. The default redirect callback allows relative URLs starting with '/', and allows callback URLs where the URL's origin equals the baseUrl. Otherwise, it redirects to baseUrl.
Configuration Options > Core Options
3 questionsWhen useSecureCookies is true, the cookie prefix is set to "__Secure-" for most cookies, and "__Host-" for the CSRF token cookie.
useSecureCookies defaults to true for URLs that start with https://, and defaults to false for URLs that start with http:// (e.g. http://localhost:3000).
No, if you are using the Essential Next.js Build Plugin within your project, you do not need to set the NEXTAUTH_URL environment variable as it is set automatically as part of the build process.
Email Authentication > Verification Tokens
3 questionsThe createVerificationToken method receives a VerificationToken object with three fields: identifier (string), expires (Date), and token (string). The token provided is already hashed, so it just needs to be written to the database.
By default, NextAuth normalizes email addresses by converting them to lowercase and trimming whitespace. It treats values as case-insensitive (which is technically not RFC 2821 compliant, but in practice causes fewer problems when looking up users by email from databases). The default implementation uses identifier.toLowerCase().trim().split('@'), and also removes comma-separated secondary addresses from the domain part.
The NEXTAUTH_SECRET (or AUTH_SECRET in newer versions) environment variable is used to hash email verification tokens. This same secret is also used to encrypt NextAuth.js JWTs.
Email Authentication > Email Services
3 questionsThe default maximum rate limit is 2 requests per second. After that, you'll hit the rate limit and receive a 429 response error code. This number can be increased for trusted senders upon request.
The sendVerificationRequest function receives: identifier (email address), url (verification link), provider (containing server and from properties), theme (UI theme options), token (verification token), and expires (expiration date).
API and Client Methods > getSession / auth
3 questionsWhen refetchOnWindowFocus is set to true (the default) tabs/windows will be updated and initialize the components' state when they gain or lose focus.
In contrast to useSession, getServerSession only returns a session object when a user has logged in (only when authenticated cookies are present), otherwise it returns null.
The auth function in NextAuth v5 returns Promise<null | Session>, meaning it can return either a valid Session object or null.
TypeScript
2 questionsThe useSession hook returns SessionContextValue
Credentials Authentication > Limitations
2 questionsThe functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
You must explicitly set session strategy to 'jwt' in your configuration. When an adapter is present, NextAuth defaults to database sessions, but the Credentials provider requires JWT sessions, so you need to override this with: session: { strategy: 'jwt' }
Account Linking
2 questionsSet allowDangerousEmailAccountLinking: true for both providers, but inside the signIn callback check if the account parameter is the provider you don't fully trust, and based on the profile parameter check if email is verified, then return true/false accordingly.
Events are asynchronous functions that do not return a response. They are useful for audit logging. The execution of your authentication API will be blocked by an await on your event handler.
Security > CSRF Protection
2 questionsgetCsrfToken() from 'next-auth/react' returns the current CSRF token required to make POST requests. It can be called without parameters on the client.
The __Host- prefix requires the cookie to have secure: true (HTTPS only), path: '/', and no Domain attribute (host-only cookie), making it stricter than __Secure-.
Next.js App Router Integration > Route Handler Setup
2 questions[...nextauth] is a catch-all dynamic route segment. The square brackets indicate a dynamic segment, and the three dots (...) make it catch-all, matching /api/auth/* and all subsequent segments (e.g., /api/auth/signin, /api/auth/callback/google, etc.).
No. In Next.js App Router, you cannot have both a route.ts file and a page.ts file at the same route segment level. They are mutually exclusive - use route.ts for API endpoints and page.ts for UI pages.
WebAuthn and Passkeys
2 questionsTo register a new passkey: signIn("passkey", { action: "register" }). To authenticate: signIn("passkey").
The counter field (INTEGER) tracks the number of times the authenticator has been used.
Custom Pages > Sign In Page
2 questionsPass it as part of the options object (second parameter). Example: signIn('provider', { callbackUrl: '/dashboard' })
next-auth/react. Example: import { getProviders, getCsrfToken, signIn } from 'next-auth/react'
OAuth Authentication > Token Handling
2 questionsThe update() method triggers a jwt callback with the trigger: 'update' option. You can use this to update the session object on the server.
Error Handling
2 questionssignIn (on successful sign in), signOut (on signout), createUser (user created), updateUser (user updated), linkAccount (account linked to a user), and session (session is active).
It will throw an error. NextAuth.js requires NEXTAUTH_SECRET in production to encrypt JWTs and hash email verification tokens.
OAuth Providers > Apple Provider
2 questionsConfiguration Options > Debug and Logging
2 questionsEnabling the debug option in production can lead to sensitive information being saved in your logs. This includes potentially exposing identity provider secrets, user data, and other confidential authentication details.
The recommended pattern is to set debug: process.env.NODE_ENV !== "production", which automatically enables debug mode in development and disables it in production. This can be safely committed to version control without needing environment-specific changes.
Testing
2 questionsCheck if process.env.NODE_ENV === "development" and only include the Credentials provider in the providers array when in development mode. You must be extremely careful not to leave insecure authentication methods available in production.
Yes, AUTH_SECRET is a required environment variable in production. If not set, NextAuth.js will throw an error.
Custom Pages > Sign Out Page
2 questionstheme.colorScheme, theme.logo, theme.brandColor, and theme.buttonText are all correctly applied on the default signout page (though brandColor and buttonText have known issues on the signin page).
The specified custom page will override the corresponding built-in page. You must ensure the page actually exists at that path.
API and Client Methods > getCsrfToken
2 questionsYou must pass a csrfToken from /api/auth/csrf in a POST request to /api/auth/callback/credentials along with your credential fields.
Migration v4 to v5
2 questionsAuth.js v5 now builds on @auth/core with stricter OAuth/OIDC spec-compliance, which might break some existing OAuth providers that don't fully conform to the specifications.
Set trustHost: true (or AUTH_TRUST_HOST=true environment variable) in Docker environments or when running Auth.js behind a proxy. This allows Auth.js to trust the X-Forwarded-Host and X-Forwarded-Proto headers to auto-detect the host URL.
Database Adapters > Custom Adapters
2 questionsAdapters must return null when a record is not found (e.g., getUser, getUserByAccount, getAuthenticator). Adapters must throw an error when an operation fails (e.g., updateAuthenticatorCounter fails, createAuthenticator fails).
linkAccount accepts an account parameter containing the account information to be linked to a user. In modern versions, it accepts an object instead of multiple individual parameters.
Credentials Authentication > Credentials Provider Setup
2 questionsimport CredentialsProvider from "next-auth/providers/credentials"
- 'credentials' - the user-submitted credentials (username, password, etc.), and 2) 'req' - the request object (which can be used to gather additional parameters like the request IP address).
API and Client Methods > useSession Hook
2 questionstrue. By default, session polling will keep trying even when the device has no internet access.
No. The update() method does not sync between tabs as the refetchInterval and refetchOnWindowFocus options do.
OAuth Providers > Discord Provider
1 questionNextAuth v5 (Auth.js) uses AUTH_DISCORD_ID and AUTH_DISCORD_SECRET. The general format is AUTH_
Session Management > Database Sessions
1 questionWhen using "database" strategy, the session cookie only contains a sessionToken value, which is used to look up the session in the database.
Credentials Authentication > Custom Validation
1 questionYes, you should check if credentials exist before proceeding. Best practice is: if (!credentials?.email || !credentials?.password) { return null; }. This prevents 'Cannot read properties of undefined' errors. It's recommended to validate inputs using tools like Zod before they reach the authorize callback.
Database Adapters > MongoDB Adapter
1 questionTo preserve the value across module reloads caused by HMR (Hot Module Replacement) and prevent creating multiple connections during development
Session Management > Session Configuration
1 questionWhen an adapter is configured, the default session strategy automatically changes to "database" instead of "jwt".
Callbacks > redirect Callback
1 questionThe redirect callback returns Awaitable<string>, meaning it can return either a string directly or a Promise that resolves to a string representing the URL to redirect to.
Callbacks > signIn Callback
1 questionThe isNewUser parameter is mentioned in documentation as being passed to callbacks, but current NextAuth v4 signIn callback signature does not include isNewUser - it is primarily available in the jwt callback.
OAuth Authentication > Provider Configuration
1 question"oauth" - This requires manual configuration of authorization, token, and userinfo endpoints.
Database Adapters > Prisma Adapter
1 question@default(cuid()) - All models (User, Account, Session, VerificationToken) use CUID by default, though UUID can be used as an alternative.
OAuth Authentication > Profile Mapping
1 questionIf you use uncommon fields like GitHub's refresh_token_expires_in, make sure to return it via the new account() callback in v5.
Database Adapters > Drizzle Adapter
1 questionuserId (not null, references users.id), type (not null), provider (not null), providerAccountId (not null), plus optional fields: refresh_token, access_token, expires_at, token_type, scope, id_token, session_state
OAuth Providers > Custom OAuth Provider
1 questionThe default scope for Google provider is "openid email profile".
OAuth Authentication > OAuth Flow
1 questionThe checks parameter can include "pkce", "state", and "nonce". For example: checks: ["pkce", "state"]. These parameters are stored in httpOnly cookies for security during the OAuth flow.
Callbacks > jwt Callback
1 questionThe default session strategy is 'jwt'. However, if you use an adapter, NextAuth.js defaults it to 'database' instead.
Custom Pages > Error Page
1 questionConfiguration and AccessDenied are the primary error codes passed to the error page. Configuration indicates a server configuration problem, and AccessDenied occurs when access is restricted through the signIn or redirect callback.