Read session and user data in your TanStack Start 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 TanStack Start application. Here are examples of how to use these helpers in both the client and server-side to get you started.
Server-side
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. 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.
import { createFileRoute, useRouter, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/start'
import { getAuth } from '@clerk/tanstack-start/server'
import { getWebRequest } from 'vinxi/http'
const authStateFn = createServerFn({ method: 'GET' }).handler(async () => {
// Use `getAuth()` to retrieve the user's ID
const { userId } = await getAuth(getWebRequest())
// Protect the server function by checking if the user is signed in
if (!userId) {
// This might error if you're redirecting to a path that doesn't exist yet
// You can create a sign-in route to handle this
throw redirect({
to: '/sign-in/$',
})
}
// Instantiate the Backend SDK
const clerkClient = createClerkClient({
secretKey: import.meta.env.CLERK_SECRET_KEY,
})
// Get the user's full `Backend User` object
const user = userId ? await clerkClient.users.getUser(userId) : null
return { user }
})
export const Route = createFileRoute('/')({
component: Home,
beforeLoad: () => authStateFn(),
loader: async ({ context }) => {
return { userId: context.userId, user: context.user }
},
})
function Home() {
const state = Route.useLoaderData()
return (
<div>
<h1>Welcome, {state.user?.firstName}!</h1>
<p>Your ID is {state.userId}</p>
</div>
)
}
import { getAuth } from '@clerk/tanstack-start/server'
import { json } from '@tanstack/start'
import { createAPIFileRoute } from '@tanstack/start/api'
export const Route = createAPIFileRoute('/api/example')({
GET: async ({ request, params }) => {
// Use `getAuth()` to retrieve the user's ID
const { userId } = await getAuth(request)
// Protect the API route by checking if the user is signed in
if (!userId) {
return json({ error: 'Unauthorized' }, { status: 401 })
}
// Instantiate the Backend SDK
const clerkClient = createClerkClient({
secretKey: import.meta.env.CLERK_SECRET_KEY,
})
// Get the user's full `Backend User` object
const user = userId ? await clerkClient.users.getUser(userId) : null
return json({ user })
},
})
Client-side
To access active session and user data on the client-side, use Clerk's useAuth()
and useUser()
hooks.
useAuth()
The useAuth()
hook provides information about 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, as shown in the following example:
import { useAuth } from '@clerk/tanstack-start'
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/example')({
component: Example,
})
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>
)
}
useUser()
The useUser()
hook enables you to access the User
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:
import { useUser } from '@clerk/tanstack-start'
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/example')({
component: Example,
})
function Example() {
const { isLoaded, isSignedIn, user } = useUser()
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, {user.firstName}!</div>
}
Feedback
Last updated on