General
Authentication

User and Session

Learn how to access the user and session in your application.

Accessing the user and session

You can access the user and session in your application using the useSession hook on the client or getSession function on the server.

Client-side

components/user-profile.tsx
'use client';

import { authClient } from '@/lib/auth/client';

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

  if (isPending) return <div>Loading...</div>;
  if (!session) return <div>Not authenticated</div>;

  return (
    <div>
      <p>Hello, {session.user.name}!</p>
      <p>Email: {session.user.email}</p>
    </div>
  );
}

Both user and session can be null if the user is not authenticated, but if you use the hook inside a /dashboard/... route, they should always be defined.

The user object contains the information of the authenticated user and the session object contains the session data.

types.ts
type Session = {
  id: string;
  userId: string;
  createdAt: Date;
  updatedAt: Date;
  expiresAt: Date;
  token: string;
  ipAddress?: string | null;
  userAgent?: string | null;
  impersonatedBy?: string | null;
};

type User = {
  id: string;
  createdAt: Date;
  updatedAt: Date;
  email: string;
  emailVerified: boolean;
  name: string;
  image?: string | null;
  role: 'admin' | 'user';
  onboardingComplete: boolean;
};

Wait until the session has been loaded

In some cases you might want to wait until the session has been loaded before accessing the user and session. For this there is an isPending property that you can use.

components/loading-example.tsx
'use client';

import { authClient } from '@/lib/auth/client';

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

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

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

  return <div>Hello, {session.user.name}!</div>;
}

Reload session

If for some reason you need to reload the session, for example when you changed some property of the user like its name or role, you can use the refetch function.

components/reload-session.tsx
'use client';

import { authClient } from '@/lib/auth/client';

export function MyComponent() {
  const { data: session, refetch } = authClient.useSession();

  const handleReload = async () => {
    await refetch();
  };

  return (
    <div>
      <p>Hello, {session?.user.name}!</p>
      <button onClick={handleReload}>Reload Session</button>
    </div>
  );
}

Get session on server

To use the session on the server, e.g. in a React Server Component, you can use the getSession function.

app/dashboard/page.tsx
import { redirect } from 'next/navigation';

import { getSession } from '@/lib/auth/server';

export default async function DashboardPage() {
  const session = await getSession();

  if (!session) {
    redirect('/auth/sign-in');
  }

  return <div>User name: {session.user.name}</div>;
}

Via tRPC context

In tRPC procedures, the session is automatically available in the context:

trpc/routers/example.ts
import { createTRPCRouter, protectedProcedure } from '@/trpc/init';

export const exampleRouter = createTRPCRouter({
  getProfile: protectedProcedure.query(async ({ ctx }) => {
    // Session is available in ctx.session, user is in ctx.user
    const user = ctx.user;
    return user;
  })
});

Session strategy

User sessions are securely stored in the database. This allows active sessions to be managed in the security settings (i.e. you can log out all devices) and changes take effect immediately.