āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/clerk/clerk-docs/guides/users/reading.react-router ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
Clerk provides a set of hooks and helpers that you can use to protect content and read 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.
To access active session and user data on the server-side, use the getAuth() helper.
The getAuth() helper returns the Auth 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 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 JS Backend SDK, which exposes Clerk's Backend API resources through methods such as the getUser(){{ target: '_blank' }} 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 { clerkClient, getAuth } from '@clerk/react-router/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)
}
// Get the user's full `Backend User` object
const user = await clerkClient(args).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>
)
}
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 { clerkClient, getAuth } from '@clerk/react-router/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()
// Get the user's full `Backend User` object
const user = await clerkClient(args).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>
)
}
To access session and user data on the client-side, you can use the useAuth() and useUser() hooks.
useAuth()useUser()ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā