Protect content and access user data
Clerk provides a set of hooks and helpers that you can use to access the session and user data in your React Router application. This guide demonstrates how to use these helpers in both the client and server-side to get you started.
Server-side
To access active session and user data on the server-side, use the getAuth()
helper.
Server data loading
The helper returns the object of the currently active user, which contains important information like the current user's session ID, user ID, and organization ID, and the isAuthenticated
property, which can be used to protect your API routes.
In some cases, you may need the full 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 , which exposes Clerk's Backend API resources through methods such as the method. This method returns the full Backend User
object.
In the following example, the userId
is passed to the JS Backend SDK's getUser()
method to get the user's full Backend User
object.
import { redirect } from 'react-router' import { getAuth } from '@clerk/react-router/ssr.server' import { createClerkClient } from '@clerk/react-router/api.server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { // 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) } // Instantiate the JS 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 { user: JSON.stringify(user), } } export default function Profile({ loaderData }: Route.ComponentProps) { return ( <div> <h1>Profile Data</h1> <pre> <code>{JSON.stringify(loaderData, null, 2)}</code> </pre> </div> ) }
Server action
Unlike the previous example that loads data when the page loads, the following example uses getAuth()
to only fetch user data after submitting the form. The helper runs on form submission, authenticates the user, and processes the form data.
import { redirect, Form } from 'react-router' import { getAuth } from '@clerk/react-router/ssr.server' import { createClerkClient } from '@clerk/react-router/api.server' import type { Route } from './+types/profile-form' export async function action(args: Route.ActionArgs) { // 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) } // Get the form data const formData = await args.request.formData() const name = formData.get('name')?.toString() // Instantiate the JS 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 { name, user: JSON.stringify(user), } } export default function ProfileForm({ actionData }: Route.ComponentProps) { return ( <div> <h1>Profile Data</h1> <Form method="post"> <label htmlFor="name">Name</label> <input type="text" name="name" id="name" /> <button type="submit">Submit</button> </Form> {actionData ? ( <pre> <code>{JSON.stringify(actionData, null, 2)}</code> </pre> ) : null} </div> ) }
Client-side
To access session and user data on the client-side, you can use the useAuth()
and useUser()
hooks.
useAuth()
The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current session.
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 following example demonstrates how to use useUser()
to check if the user is signed in and display their first name.
export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return <div>Loading...</div> } // Use `isSignedIn` to protect the content if (!isSignedIn) { return <div>Sign in to view this page</div> } // Use `user` to access the current user's data return <div>Hello {user.firstName}!</div> }
Feedback
Last updated on