Skip to main content
Docs

Read session and user data in your Next.js app with Clerk

Clerk provides a set of hooks and helpers that you can use to access the active session and user data in your Next.js application. Here are examples of how to use these helpers in both the client and server-side to get you started.

Server-side

App Router

auth() and currentUser() are App Router-specific helpers that you can use inside of your Route Handlers, Middleware, Server Components, and Server Actions.

  • The auth() helper will return the Auth object of the currently active user.
  • The currentUser() helper will return the Backend User object of the currently active user. This is helpful if you want to render information, like their first and last name, directly from the server. Under the hood, currentUser() uses the clerkClient wrapper to make a call to the Backend API. This does count towards the Backend API request rate limit. This also uses fetch() so it is automatically deduped per request.

The following example uses the auth() helper to validate an authenticated user and the currentUser() helper to access the Backend User object for the authenticated user.

Note

Any requests from a Client Component to a Route Handler will read the session from cookies and will not need the token sent as a Bearer token.

app/page.tsx
import { auth, currentUser } from '@clerk/nextjs/server'

export default async function Page() {
  // Get the userId from auth() -- if null, the user is not signed in
  const { userId } = await auth()

  // Protect the route by checking if the user is signed in
  if (!userId) {
    return <div>Sign in to view this page</div>
  }

  // Get the Backend API User object when you need access to the user's information
  const user = await currentUser()

  // Use `user` to render user details or create UI elements
  return <div>Welcome, {user.firstName}!</div>
}
app/api/user/route.ts
import { NextResponse } from 'next/server'
import { currentUser, auth } from '@clerk/nextjs/server'

export async function GET() {
  // Use `auth()` to get the user's ID
  const { userId } = await auth()

  // Protect the route by checking if the user is signed in
  if (!userId) {
    return new NextResponse('Unauthorized', { status: 401 })
  }

  // Use `currentUser()` to get the Backend API User object
  const user = await currentUser()

  // Add your Route Handler's logic with the returned `user` object

  return NextResponse.json({ user: user }, { status: 200 })
}

Pages Router

For Next.js applications using the Pages Router, the getAuth() helper will return the Auth object of the currently active user, which contains important information like the current user's session ID, user ID, and organization ID. The userId can be used to protect your API routes.

In some cases, you may need the full Backend User object of the currently active user. This is helpful if you want to render information, like their first and last name, directly from the server.

The clerkClient() helper returns an instance of the JavaScript Backend SDK, which exposes Clerk's Backend API resources through methods such as the getUser() method. This method returns the full Backend User object.

In the following example, the userId is passed to the Backend SDK's getUser() method to get the user's full Backend User object.

pages/api/auth.ts
import { getAuth, clerkClient } from '@clerk/nextjs/server'
import type { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  // Use `getAuth()` to get the user's ID
  const { userId } = getAuth(req)

  // Protect the route by checking if the user is signed in
  if (!userId) {
    return res.status(401).json({ error: 'Unauthorized' })
  }

  // Initialize the Backend SDK
  const client = await clerkClient()

  // Get the user's full `Backend User` object
  const user = await client.users.getUser(userId)

  return res.status(200).json({ user })
}

Note

buildClerkProps informs client-side features, like useAuth(), <SignedIn>, and <SignedOut>, of the authentication state during server-side rendering.

pages/example.tsx
import { getAuth, buildClerkProps } from '@clerk/nextjs/server'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  // Use `getAuth()` to get the user's ID
  const { userId } = getAuth(ctx.req)

  // Protect the route by checking if the user is signed in
  if (!userId) {
    // Handle when the user is not signed in
  }

  // Initialize the Backend SDK
  const client = await clerkClient()

  // Get the user's full `Backend User` object
  const user = userId ? await client.users.getUser(userId) : undefined

  return { props: { ...buildClerkProps(ctx.req, { user }) } }
}

The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current active session. The hook returns userId, which can be used to protect your routes.

example.tsx
export default function Example() {
  const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth()

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

  if (!isSignedIn) {
    // You could also add a redirect to the sign-in page here
    return <div>Sign in to view this page</div>
  }

  return (
    <div>
      Hello, {userId}! Your current active session is {sessionId}.
    </div>
  )
}

The following example uses the useUser() hook to access the User object, which contains the current user's data such as their full name. The isLoaded and isSignedIn properties are used to handle the loading state and to check if the user is signed in, respectively.

src/Example.tsx
export default function Example() {
  const { isSignedIn, user, isLoaded } = useUser()

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

  if (!isSignedIn) {
    return <div>Sign in to view this page</div>
  }

  return <div>Hello {user.firstName}!</div>
}

Feedback

What did you think of this content?

Last updated on