Skip to main content
Docs

Read session and user data in your Remix app with Clerk

Warning

The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the for continued development and new features.

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

Server-side

getAuth()

The getAuth() helper allows you to access the , which includes the current user's userId and the isAuthenticated property, which can be used to protect your routes.

In the following example, the userId is passed to the Backend SDK's method to get the user's full User object. For information on how to use the Backend SDK, see the .

routes/profile.tsx
import { LoaderFunction, redirect } from '@remix-run/node'
import { getAuth } from '@clerk/remix/ssr.server'
import { createClerkClient } from '@clerk/remix/api.server'

export const loader: LoaderFunction = async (args) => {
  // Use `getAuth()` to access `isAuthenticated` and the user's ID
  const { isAuthenticated, userId } = await getAuth(args)

  // Protect the route by checking if the user is signed in
  if (!isAuthenticated) {
    return redirect('/sign-in?redirect_url=' + args.request.url)
  }

  // Initialize the Backend SDK and get the user's full `Backend User` object
  const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser(
    userId,
  )

  // Return the retrieved user data
  return { serialisedUser: JSON.stringify(user) }
}
routes/profile.tsx
import { ActionFunction, redirect } from '@remix-run/node'
import { getAuth } from '@clerk/remix/ssr.server'
import { createClerkClient } from '@clerk/remix/api.server'

export const action: ActionFunction = async (args) => {
  // Use `getAuth()` to access `isAuthenticated` and the user's ID
  const { isAuthenticated, userId } = await getAuth(args)

  // Protect the route by checking if the user is signed in
  if (!isAuthenticated) {
    return redirect('/sign-in?redirect_url=' + args.request.url)
  }

  // Initialize the Backend SDK and get the user's full `Backend User` object
  const updatedUser = await createClerkClient({
    secretKey: process.env.CLERK_SECRET_KEY,
  }).users.getUser(userId)

  // Return the retrieved user data
  return { serialisedUser: JSON.stringify(updatedUser) }
}

Client Side

useAuth()

The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current active session.

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

  const fetchExternalData = async () => {
    // Use `getToken()` to get the current user's session token
    const token = await getToken()

    // Use `token` to fetch data from an external API
    const response = await fetch('https://api.example.com/data', {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })

    return response.json()
  }

  // Use `isLoaded` to check if Clerk is loaded
  if (!isLoaded) {
    return <div>Loading...</div>
  }

  // Use `isSignedIn` to check if the user is signed in
  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>
  )
}

useUser()

The following example uses the useUser() hook to access the 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