Next.js
Authentication for Next.js app with Authgear
Integrate Authgear authentication into a Next.js App Router application using the @authgear/nextjs SDK. You will set up login, logout, display user info, and protect a server-side API route.
A complete example application is available at authgear/authgear-example-nextjs.
What you will build:
A home page that shows a Login button when unauthenticated, and the user's identity + Logout button when authenticated
A protected API route (
/api/me) that returns the current user's info
Setting Up Your Application in Authgear
Step 1: Create an Application in the Portal
Sign in to the Authgear Portal
Select or create a Project
Navigate to Applications in the left menu
Click ⊕ Add Application
Enter an application name and select Single Page Application as the application type
Click Save
Step 2: Configure the Application
Under OAuth 2.0, find the Authorized Redirect URIs field
Add
http://localhost:3000/api/auth/callbackNote down your Client ID and Endpoint (e.g.
https://your-project.authgear.cloud) — you will need these shortlyClick Save
Building Your Next.js Application
Step 1: Create a Next.js Project
Step 2: Install the Authgear SDK
Step 3: Configure Environment Variables
Create .env.local with the following content:
SESSION_SECRET encrypts the session cookie stored in the browser. It must be at least 32 characters. Use a random string generator to create one.
Step 4: Create the Shared Authgear Config
Create src/lib/authgear.ts. This file holds your Authgear configuration and is imported by both server-side and client-side code:
Step 5: Add the OAuth Route Handler
Create src/app/api/auth/[...authgear]/route.ts. This catch-all route handles all Authgear auth endpoints automatically:
createAuthgearHandlers registers the following routes for you:
GET
/api/auth/login
Start the OAuth login flow
GET
/api/auth/callback
Handle the OAuth callback and set the session cookie
GET
/api/auth/logout
Clear the session and revoke tokens
POST
/api/auth/refresh
Refresh an expired access token
GET
/api/auth/userinfo
Return the current user's info
GET
/api/auth/open
Open a pre-authenticated Authgear-hosted page
Step 6: Add AuthgearProvider to Your Layout
AuthgearProvider makes the user's session state available to all Client Components via React context. Because it uses browser APIs, it must be a Client Component.
Create src/app/providers.tsx:
Then wrap your root layout in src/app/layout.tsx:
On mount, AuthgearProvider fetches /api/auth/userinfo to check for an existing session. The result is available via the useAuthgear() hook.
Step 7: Implement the Home Page
Replace src/app/page.tsx. The page is a Client Component so it can use useAuthgear() to read session state and react to changes:
Key hooks and components:
useAuthgear()— returns{ isAuthenticated, user, state, isLoaded, signIn, signOut }.useris aUserInfoobject withsub,email,phoneNumber, and other profile fields.<SignInButton>— navigates to/api/auth/loginon click, starting the OAuth flow.<SignOutButton>— navigates to/api/auth/logouton click, clearing the session.
Step 8: Create a Protected API Route
Server-side route handlers can verify authentication using currentUser() from @authgear/nextjs/server. It reads the encrypted session cookie and returns the current user, or null if not authenticated.
Create src/app/api/me/route.ts:
currentUser() automatically refreshes the access token if expired before fetching user info from the Authgear userinfo endpoint.
Running the Application
Open http://localhost:3000 in your browser.
Testing the Integration
Login flow
Visit
http://localhost:3000— you should see a Login buttonClick Login — you are redirected to the Authgear hosted login page
Sign in with your credentials
You are redirected back to the home page, now showing your user ID and email/phone number
Logout flow
Click Logout — the session is cleared and you are returned to the login screen
Protected API
After logging in, click Test Protected API
The page calls
GET /api/me, which verifies your session and returns your user info:
To verify the route is protected, open an incognito window and run:
Expected response with status 401:
Project Structure
Additional Topics
Reading the Session in Server Components
Use auth() to read the raw session (state + tokens) without making a network request:
Use currentUser() when you need the full user profile — it makes an extra request to the userinfo endpoint and handles token refresh automatically.
Verifying a Bearer Token in an External API
If you have a separate API server that receives Authgear-issued access tokens (e.g. from a mobile app), use verifyAccessToken() to validate them:
verifyAccessToken validates the JWT signature and expiry locally using the Authgear JWKS endpoint — no session cookie is involved.
Checking Session State
useAuthgear() returns isLoaded to indicate whether the initial session check has completed. Use it to avoid a flash of unauthenticated UI:
Opening User Settings
The <UserSettingsButton> component opens Authgear's hosted Settings page in a new tab with the current user already authenticated — no Server Action required.
Add the button to your component:
The button must be rendered inside <AuthgearProvider>. It exchanges the user's session for a short-lived token and opens the pre-authenticated Settings URL in a new tab.
Style it like any button — <UserSettingsButton> accepts all standard HTML button props:
The default label is "Account Settings" if no children are provided.
Customising the route path
By default, <UserSettingsButton> sends requests to /api/auth/open. If your auth routes live at a different path, set openPagePath on <AuthgearProvider>:
Error behaviour
If the user is not authenticated or their session has no refresh token, the new tab will display an error rather than the Settings page. Guard the button with an authentication check to avoid this:
Controlling Single Sign-On Behaviour
By default, Authgear reuses its server-side session across sign-ins (SSO enabled). You can change this globally via isSSOEnabled in createAuthgearHandlers, or override it per sign-in call using the prompt option.
Disable SSO globally — always show the login form:
Override per sign-in call using PromptOption:
PromptOption
Effect
PromptOption.Login
Always show the login form
PromptOption.None
Never show the login form; error if not authenticated
Per-call prompt takes precedence over the global isSSOEnabled setting.
Next Steps
Last updated
Was this helpful?