Read session and user data in your React Router app with Clerk
Clerk provides a set of hooks and helpers
Server-side
To access active session and user data on the server-side, use the getAuth()
Server data loading
The getAuth()userId can be used to protect your API routes.
In some cases, you may need the full Backend UserclerkClient() helper returns an instance of the JavaScript Backend SDKBackend 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.
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 get the user's ID
const { userId } = await getAuth(args)
// Protect the route by checking if the user is signed in
if (!userId) {
return redirect('/sign-in?redirect_url=' + args.request.url)
}
// Instantiate 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 {
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 get the user's ID
const { userId } = await getAuth(args)
// Protect the route by checking if the user is signed in
if (!userId) {
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 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 active session and user data on the client-side, 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 active 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 UserisLoaded and isSignedIn properties are used to handle the loading state and to check if the user is signed in, respectively.
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
Last updated on