TanStack Start Quickstart (beta)
You will learn the following:
- Install
@clerk/tanstack-start
- Set your Clerk API keys
- Add
createClerkHandler()
- Add
<ClerkProvider>
- Protect your pages
Install @clerk/tanstack-start
The Clerk TanStack Start SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier.
Run the following command to install the SDK:
npm install @clerk/tanstack-start
yarn add @clerk/tanstack-start
pnpm add @clerk/tanstack-start
bun add @clerk/tanstack-start
Add the following keys to your .env
file. These keys can always be retrieved from the API keys page in the Clerk Dashboard.
- In the Clerk Dashboard, navigate to the API keys page.
- In the Quick Copy section, copy your Clerk Publishable and Secret Keys.
- Paste your keys into your
.env
file.
The final result should resemble the following:
VITE_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY
Add createClerkHandler()
TanStack's createStartHandler()
creates a server-side handler that determines which routes and loaders need to be executed when the user hits a given route.
Clerk's createClerkHandler()
configures Clerk to handle authentication state for TanStack routes, allowing you to easily access user session information within your app.
Update your app's SSR entrypoint by wrapping createStartHandler()
in createClerkHandler()
, as shown in the following example:
import { createStartHandler, defaultStreamHandler } from '@tanstack/start/server'
import { getRouterManifest } from '@tanstack/start/router-manifest'
import { createRouter } from './router'
import { createClerkHandler } from '@clerk/tanstack-start/server'
export default createClerkHandler(
createStartHandler({
createRouter,
getRouterManifest,
}),
)(defaultStreamHandler)
The <ClerkProvider>
component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider>
to make authentication globally accessible. See the reference docs for other configuration options.
Add the <ClerkProvider>
component to your app's root route, as shown in the following example:
import { Outlet, createRootRoute } from '@tanstack/react-router'
import { Meta, Scripts } from '@tanstack/start'
import * as React from 'react'
import { ClerkProvider } from '@clerk/tanstack-start'
export const Route = createRootRoute({
component: () => {
return (
<RootDocument>
<Outlet />
</RootDocument>
)
},
})
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html>
<head>
<Meta />
</head>
<body>
{children}
<Scripts />
</body>
</html>
</ClerkProvider>
)
}
Protect your pages
Client-side
To protect your pages on the client-side, you can use Clerk's prebuilt control components that control the visibility of content based on the user's authentication state.
The following example uses the following components:
<SignedIn>
: Children of this component can only be seen while signed in.<SignedOut>
: Children of this component can only be seen while signed out.<UserButton />
: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options.<SignInButton />
: An unstyled component that links to the sign-in page. In this example, since no props or environment variables are set for the sign-in URL, this component links to the Account Portal sign-in page.
import {
SignedIn,
UserButton,
SignOutButton,
SignedOut,
SignInButton,
SignUpButton,
} from '@clerk/tanstack-start'
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
component: Home,
})
function Home() {
return (
<div>
<h1>Index Route</h1>
<SignedIn>
<p>You are signed in</p>
<UserButton />
</SignedIn>
<SignedOut>
<p>You are signed out</p>
<SignInButton />
</SignedOut>
</div>
)
}
Server-side
To protect your routes, create a server function that checks the user's authentication state via the getAuth()
method. If the user is not authenticated, they are redirected to a sign-in page. If authenticated, the user's userId
is passed to the route, allowing access to the <Home />
component, which welcomes the user and displays their userId
. The beforeLoad()
method ensures authentication is checked before loading the page, and the loader()
method returns the user data for use in the component.
import { createFileRoute, 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 () => {
const { userId } = await getAuth(getWebRequest())
if (!userId) {
// This will error because 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/$',
})
}
return { userId }
})
export const Route = createFileRoute('/')({
component: Home,
beforeLoad: async () => await authStateFn(),
loader: async ({ context }) => {
return { userId: context.userId }
},
})
function Home() {
const state = Route.useLoaderData()
return <h1>Welcome! Your ID is {state.userId}!</h1>
}
Create your first user
Run your project with the following command:
npm run dev
yarn dev
pnpm dev
bun dev
Visit your app's homepage at http://localhost:3000. Sign up to create your first user.
Create a custom sign-in-or-up page
Learn how add custom sign-in-or-up page with Clerk components.
Read user and session data
Learn how to use Clerk's hooks and helpers to access the active session and user data in your TanStack Start app.
Customization & localization
Learn how to customize and localize the Clerk components.
Clerk components
Learn more about Clerk's prebuilt components.
Feedback
Last updated on