Skip to main content
handleAuth creates a route handler function that processes OAuth callback requests from WorkOS AuthKit. It exchanges authorization codes for user sessions and manages session cookies.

Usage

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth();

Signature

function handleAuth(options?: HandleAuthOptions): (request: NextRequest) => Promise<Response>

Parameters

options
object
Configuration options for the authentication callback handler.

Returns

Returns a route handler function that accepts a NextRequest and returns a Promise<Response>.

Examples

Basic callback route

// app/auth/callback/route.ts
import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth();

Custom redirect path

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth({
  returnPathname: '/dashboard',
});

Persisting OAuth tokens

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth({
  onSuccess: async ({ user, oauthTokens, authenticationMethod, organizationId }) => {
    // Save OAuth tokens from upstream provider
    if (oauthTokens) {
      await database.saveTokens(user.id, oauthTokens);
    }
    
    // Track authentication method
    if (authenticationMethod) {
      await analytics.track('user_authenticated', {
        userId: user.id,
        method: authenticationMethod,
        organizationId,
      });
    }
  },
});

Handling custom state

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth({
  onSuccess: async ({ user, state }) => {
    // Parse custom state passed through the auth flow
    const customData = state ? JSON.parse(state) : null;
    
    if (customData?.teamId) {
      await addUserToTeam(user.id, customData.teamId);
    }
    
    if (customData?.referrer) {
      await analytics.track('sign_in_completed', {
        userId: user.id,
        referrer: customData.referrer,
      });
    }
  },
});

Docker deployments

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth({
  baseURL: 'https://app.example.com',
});

Custom error handling

import { handleAuth } from '@workos-inc/authkit-nextjs';
import { NextResponse } from 'next/server';

export const GET = handleAuth({
  onError: async ({ error, request }) => {
    console.error('Authentication error:', error);
    
    // Log to monitoring service
    await monitoring.logError('auth_callback_failed', {
      error,
      url: request.url,
    });
    
    // Return custom error response
    return NextResponse.redirect(
      new URL('/auth/error', request.url)
    );
  },
});

Notes

  • The callback route URL must match the redirect URI configured in your WorkOS dashboard
  • The callback route URL must also match the WORKOS_REDIRECT_URI environment variable
  • authenticationMethod is only available during the initial authentication callback, not on session refreshes
  • When using custom state, remember to serialize complex data with JSON.stringify() when creating auth URLs
  • The baseURL option is particularly useful for preview deployments and containerized environments

Build docs developers (and LLMs) love