Skip to main content

Overview

The authClient is a Better Auth React client instance that provides methods for authentication and session management. It’s configured with JWT support via the jwtClient plugin.

Configuration

import { jwtClient } from "better-auth/client/plugins"
import { createAuthClient } from "better-auth/react"

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL || "http://localhost:3000",
  plugins: [jwtClient()],
})
baseURL
string
required
The base URL where your Better Auth server is running. Set via NEXT_PUBLIC_BETTER_AUTH_URL environment variable.
plugins
array
Array of Better Auth plugins. This boilerplate includes jwtClient() for JWT token support.

Methods

signIn.email()

Authenticate a user with email and password.
const result = await authClient.signIn.email({ email, password })
if (result.error) {
  console.error(result.error.message)
} else {
  // User is signed in
}
email
string
required
User’s email address
password
string
required
User’s password
data
object
Session data including user information when successful
error
object
Error object with message field when authentication fails

Example Usage

import { authClient } from "@/lib/auth-client"

const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault()
  setLoading(true)
  setError("")

  try {
    const result = await authClient.signIn.email({ email, password })
    if (result.error) {
      setError(result.error.message || "Invalid email or password")
      return
    }
    router.push("/")
  } catch {
    setError("An unexpected error occurred")
  } finally {
    setLoading(false)
  }
}

signIn.social()

Authenticate a user with a social provider (e.g., Google).
const result = await authClient.signIn.social({ provider: "google" })
if (result.error) {
  console.error(result.error.message)
}
provider
string
required
The social provider to use. Supported values: "google" (others can be configured in auth.ts)
error
object
Error object with message field when authentication fails

Example Usage

const handleGoogleSignIn = async () => {
  setError("")
  try {
    const result = await authClient.signIn.social({ provider: "google" })
    if (result.error) {
      setError(result.error.message || "Google sign in failed")
    }
  } catch {
    setError("An unexpected error occurred")
  }
}

signUp.email()

Register a new user with email and password.
const result = await authClient.signUp.email({ email, password, name })
if (result.error) {
  console.error(result.error.message)
} else {
  // Account created successfully
}
email
string
required
User’s email address
password
string
required
User’s password
name
string
User’s full name
data
object
User account data when registration is successful
error
object
Error object with message field when registration fails

Example Usage

import { authClient } from "@/lib/auth-client"

const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault()
  setLoading(true)
  setError("")

  try {
    const result = await authClient.signUp.email({ email, password, name })
    if (result.error) {
      setError(result.error.message || "Failed to create account")
      return
    }
    window.location.href = "/login"
  } catch {
    setError("An unexpected error occurred")
  } finally {
    setLoading(false)
  }
}

signOut()

Sign out the current user and invalidate their session.
await authClient.signOut()

Example Usage

import { authClient } from "@/lib/auth-client"

const handleSignOut = async () => {
  await authClient.signOut()
  window.location.reload()
}

useSession()

A React hook that returns the current session state.
const { data: session, isPending } = authClient.useSession()
data
Session | null
The current session object containing user information, or null if not authenticated
isPending
boolean
true while the session is being loaded, false once loaded

Session Object

When authenticated, the session object contains:
user.id
string
Unique user identifier
user.email
string
User’s email address
user.name
string
User’s full name

Example Usage

import { authClient } from "@/lib/auth-client"

export function AuthStatus() {
  const { data: session, isPending } = authClient.useSession()

  if (isPending) {
    return <div>Loading...</div>
  }

  if (!session) {
    return <div>Not authenticated</div>
  }

  return (
    <div>
      <p>Welcome, {session.user.name}</p>
      <p>Email: {session.user.email}</p>
      <p>ID: {session.user.id}</p>
    </div>
  )
}

token()

Obtain a JWT token for the current session. Used for backend API authentication.
const result = await authClient.token()
const jwt = result.data?.token
data.token
string
The JWT token string that can be sent to backend services in the Authorization header

Example Usage

The token() method is typically used by API clients to inject JWT tokens into requests:
import authClient from "./auth-client"
import { decodeJwt } from "jose"

class ApiClient {
  private cachedToken: string | null = null

  private async getToken(): Promise<string | null> {
    // Request a new JWT from better-auth
    const token = await authClient.token().then(x => x.data?.token) || null
    this.cachedToken = token
    return token
  }

  async request(endpoint: string, options: RequestInit = {}) {
    const token = await this.getToken()
    
    const response = await fetch(endpoint, {
      ...options,
      headers: {
        ...options.headers,
        "Authorization": `Bearer ${token}`,
      },
    })
    
    return response.json()
  }
}

JWT Client Plugin

The jwtClient() plugin adds JWT token support to the auth client. This enables:
  • Token generation via authClient.token()
  • Automatic token management
  • Integration with backend services using JWKS verification

Token Format

JWT tokens issued by Better Auth include the following claims:
{
  "sub": "user-id",
  "email": "[email protected]",
  "name": "User Name",
  "iss": "http://localhost:3000",
  "aud": "http://localhost:3000",
  "exp": 1234567890,
  "iat": 1234567890
}

Backend Verification

Backend services should verify JWT tokens using the JWKS endpoint at /api/auth/jwks:
import { createRemoteJWKSet, jwtVerify } from "jose"

const JWKS = createRemoteJWKSet(
  new URL("http://localhost:3000/api/auth/jwks")
)

const { payload } = await jwtVerify(token, JWKS, {
  issuer: "http://localhost:3000",
  audience: "http://localhost:3000",
})
See Auth Server for backend configuration details.

TypeScript Types

interface SignInEmailParams {
  email: string
  password: string
}

interface SignUpEmailParams {
  email: string
  password: string
  name?: string
}

interface SignInSocialParams {
  provider: "google" | string
}

interface Session {
  user: {
    id: string
    email: string
    name: string
  }
}

interface AuthResult<T = unknown> {
  data?: T
  error?: {
    message: string
  }
}

Build docs developers (and LLMs) love