superapp
ClientAuth

Session Management

How sessions, tokens, and automatic refresh work in the client SDK.

The auth client manages JWT sessions automatically — storing tokens, refreshing them before expiry, and clearing them on sign out.

import { useSession } from '@superapp/auth'

export function Dashboard() {
  const { data: session, isPending } = useSession()

  if (isPending) return <div>Loading...</div>
  if (!session) return <div>Please sign in</div>

  return <div>Welcome, {session.user.name}</div>
}

How Sessions Work

  1. The user signs in through AuthCard or the auth client API.
  2. The server returns a JWT and a refresh token.
  3. The auth client stores the tokens and provides them via useSession.
  4. When you create a db client with createDb(session.token), the JWT is sent with every query.
  5. The server validates the JWT, extracts the user identity, and applies permissions.

Token Lifecycle

EventWhat Happens
Sign inJWT + refresh token stored
QueryJWT sent in Authorization header
Token expiry approachingAuth client refreshes automatically
Refresh token expiredSession cleared, user must sign in again
Sign outBoth tokens cleared

Accessing the Session

In React Components

Use the useSession hook inside an AuthProvider.

import { useSession } from '@superapp/auth'

export function UserGreeting() {
  const { data: session, isPending } = useSession()

  if (isPending) return <span>Loading...</span>
  if (!session) return <span>Guest</span>

  return <span>Hello, {session.user.name}</span>
}

For Database Queries

Use the useDb hook to get a typed client that is automatically null when no session exists.

import { useDb } from '@/hooks/use-db'

export function OrdersList() {
  const db = useDb()

  async function loadOrders() {
    if (!db) return // Not authenticated
    const orders = await db.main.orders.findMany({
      select: ['id', 'amount', 'status'],
    })
    // orders: { id: string; amount: number; status: string }[]
  }
}

Reacting to Session Changes

Use the onSessionChange callback on AuthProvider to run side effects when the session changes (sign in, sign out, token refresh).

import { AuthProvider } from '@superapp/auth/components'
import { authClient } from '@/lib/superapp'
import { useRouter } from 'next/navigation'

export function Providers({ children }: { children: React.ReactNode }) {
  const router = useRouter()

  return (
    <AuthProvider
      authClient={authClient}
      navigate={router.push}
      replace={router.replace}
      onSessionChange={() => router.refresh()}
    >
      {children}
    </AuthProvider>
  )
}

Protected Routes

Check the session to gate access to authenticated pages.

import { useSession } from '@superapp/auth'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export function ProtectedPage({ children }: { children: React.ReactNode }) {
  const { data: session, isPending } = useSession()
  const router = useRouter()

  useEffect(() => {
    if (!isPending && !session) {
      router.replace('/sign-in')
    }
  }, [session, isPending, router])

  if (isPending) return <div>Loading...</div>
  if (!session) return null

  return <>{children}</>
}

On this page