Clerk Tanstack Patterns
ClerkOfficialCreated by clerk
- Skill
- Tool integration
- Software development
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides patterns for implementing authentication in TanStack React Start applications using the Clerk SDK. It covers the necessary server-side setup, including request middleware configuration, and demonstrates how to secure routes using beforeLoad guards and createServerFn. It also explains how to pass authenticated user context into loaders and provides a mental model for how auth flows between the server and router layers.
What it does
- Configures Clerk request middleware within the TanStack Start instance.
- Implements route-level protection using beforeLoad guards.
- Secures server functions with auth() checks.
- Passes authenticated user or organization context to route loaders.
- Wraps applications with the ClerkProvider for client-side auth state.
- Provides troubleshooting steps for common auth integration pitfalls.
When to use it
- When building a new TanStack React Start application that requires user authentication.
- When you need to protect specific routes or layouts from unauthenticated access.
- When you need to access authenticated user data within server functions or loaders.
- When configuring the initial authentication middleware for a TanStack project.
Advantages
- Seamless integration with TanStack Start's server-side architecture.
- Enforces security at the server layer before route rendering.
- Provides a clear pattern for passing auth context to data loaders.
- Reduces boilerplate for common auth-related redirects and checks.
Usage examples
- “How do I protect a dashboard route in TanStack Start using Clerk?”
- The agent provides a pattern using a createServerFn that calls auth() and throws a redirect if the user is unauthenticated, which is then invoked in the route's beforeLoad.
- “How can I access the user ID in my TanStack loader?”
- The agent demonstrates how to return the userId from a beforeLoad guard, which then becomes available in the loader's context object.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/clerk/clerk-tanstack-patterns/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip clerk-tanstack-patterns.zip -d .agents/skills
Documentation by clerk
TanStack React Start Patterns
What Do You Need?
| Task | Reference |
|---|---|
| Protect routes with beforeLoad | references/router-guards.md |
| Auth in createServerFn | references/server-functions.md |
| Pass auth to loaders | references/loaders.md |
| Configure Vite + Clerk middleware | references/server-setup.md |
References
| Reference | Description |
|---|---|
references/router-guards.md | beforeLoad auth redirect |
references/server-functions.md | createServerFn with auth() |
references/loaders.md | Auth context in loaders |
references/server-setup.md | Vite and request middleware setup |
Setup
npm install @clerk/tanstack-react-start.env:
VITE_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...src/start.ts (request middleware):
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'
import { createCsrfMiddleware, createStart } from '@tanstack/react-start'
const csrfMiddleware = createCsrfMiddleware({
filter: (ctx) => ctx.handlerType === 'serverFn',
})
export const startInstance = createStart(() => {
return {
requestMiddleware: [csrfMiddleware, clerkMiddleware()],
}
})src/routes/__root.tsx — wrap with <ClerkProvider>:
import { ClerkProvider } from '@clerk/tanstack-react-start'
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ClerkProvider>
{children}
</ClerkProvider>
</body>
</html>
)
}Mental Model
TanStack Start uses the tanstackStart() Vite plugin. Register CSRF protection before Clerk request middleware in src/start.ts; auth then flows through two layers:
Server layer —
createServerFn+auth()from@clerk/tanstack-react-start/serverRouter layer —
beforeLoadon route definitions, throwsredirectfor unauthenticated
Both layers are server-executed. Client hooks (useAuth, useUser) are React hooks for the browser side.
Minimal Pattern
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'
const authStateFn = createServerFn().handler(async () => {
const { isAuthenticated, userId } = await auth()
if (!isAuthenticated) {
throw redirect({ to: '/sign-in' })
}
return { userId }
})
export const Route = createFileRoute('/dashboard')({
beforeLoad: async () => await authStateFn(),
})Common Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
auth() throws "without configuring the middleware" | Missing clerkMiddleware in start.ts | Add it after CSRF middleware in requestMiddleware |
redirect not thrown | Using return instead of throw | throw redirect(...) in TanStack |
Wrong import for auth | Mixing client/server imports | Server: @clerk/tanstack-react-start/server |
| Loader context missing userId | Not passing from beforeLoad | Return from beforeLoad, access via context |
ClerkProvider missing | Forgot root wrapping | Add to __root.tsx shell component |
See Also
clerk-setup- Initial Clerk installclerk-custom-ui- Custom flows & appearanceclerk-orgs- B2B organizations
Docs
Files
- ATTRIBUTION.mdAdded by AutoGineer863 B
- SKILL.md3.7 KiB
- evals/evals.json5.1 KiB
- references/loaders.md1.8 KiB
- references/router-guards.md2.0 KiB
- references/server-functions.md2.1 KiB
- references/server-setup.md2.6 KiB
- templates/tanstack-basic-auth/package.json513 B
- templates/tanstack-basic-auth/src/router.tsxScript488 B
- templates/tanstack-basic-auth/src/routes/__root.tsxScript808 B
- templates/tanstack-basic-auth/src/routes/index.tsxScript496 B
- templates/tanstack-basic-auth/src/start.tsScript372 B
- templates/tanstack-basic-auth/tsconfig.json531 B
- templates/tanstack-basic-auth/vite.config.tsScript383 B
evals/evals.json
{
"skill_name": "clerk-tanstack-patterns",
"evals": [
{
"id": 1,
"prompt": "i have a tanstack react start app and want to protect the /dashboard route. unauthenticated users should be redirected to /sign-in. how do i add an auth guard to the route?",
"expected_output": "Uses beforeLoad with createServerFn that calls auth() and throws redirect for unauthenticated users",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Creates a createServerFn that calls auth() from @clerk/tanstack-react-start/server",
"Throws redirect({ to: '/sign-in' }) when isAuthenticated is false",
"Calls the server function in the route's beforeLoad",
"Imports are from the correct package paths",
"Does NOT use client-only hooks for the auth check"
]
},
{
"id": 2,
"prompt": "i need a server function that fetches the current user's orders from my database. it should only work for authenticated users and return the userId alongside the orders.",
"expected_output": "Creates a createServerFn that uses auth() to get userId, fetches data, throws if not authenticated",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Uses createServerFn from @tanstack/react-start",
"Calls auth() from @clerk/tanstack-react-start/server inside the handler",
"Checks isAuthenticated and throws an error or redirect if false",
"Returns userId with the data payload",
"Server function is called from a route loader or component"
]
},
{
"id": 3,
"prompt": "i want a layout route that wraps all /app/* routes and protects them. the layout should check auth once and all child routes inherit the protection without repeating the check.",
"expected_output": "Creates a layout route file with beforeLoad auth check that child routes inherit via route context",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Creates a layout route (e.g. src/routes/app.tsx or _layout.tsx pattern)",
"Uses beforeLoad at the layout level with auth() check",
"Passes userId or auth data through route context for child routes to access",
"Child routes can access the auth context without re-fetching",
"Throws redirect to /sign-in for unauthenticated access"
]
},
{
"id": 4,
"prompt": "my app needs to show org-specific data. when a user has an active org, load org projects in the route loader. if no org is selected, show a message to select one.",
"expected_output": "Route loader uses auth() to get orgId, conditionally fetches org data, handles missing org case",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Uses auth() in a createServerFn or loader to get orgId",
"Handles null orgId case by returning empty state or redirecting",
"Fetches org-scoped data using orgId",
"Component handles both states: org selected and no org selected",
"Shows OrganizationSwitcher or prompt when no org is active"
]
},
{
"id": 5,
"prompt": "i want to build a custom sign-in page using clerk's useSignIn hook instead of the prebuilt component. create a page with email/password fields.",
"expected_output": "Creates a sign-in page using useSignIn hook with signIn.create() for email/password authentication",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Uses useSignIn hook from @clerk/tanstack-react-start",
"Calls signIn.create({ identifier, password }) to initiate sign-in",
"Handles the complete() or firstFactorVerification result",
"Shows loading state during sign-in",
"Handles errors from the sign-in attempt"
]
},
{
"id": 6,
"prompt": "i have a tanstack start API route that needs to verify the user is authenticated before processing a mutation. show me how to protect it.",
"expected_output": "Server route built with createFileRoute and server.handlers checks auth() and returns 401 for unauthenticated requests",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Uses createFileRoute from @tanstack/react-router with server.handlers",
"Exports the route as Route from a file under src/routes/api/",
"Uses auth() from @clerk/tanstack-react-start/server in the handler",
"Returns a 401 response for unauthenticated requests",
"Extracts userId or sessionId from the auth result",
"Does NOT use createAPIFileRoute or createServerFileRoute"
]
},
{
"id": 7,
"prompt": "I am adding Clerk to a TanStack Start app. Show the complete src/start.ts configuration that keeps server functions protected against CSRF.",
"expected_output": "Registers filtered CSRF middleware before clerkMiddleware in the createStart requestMiddleware array",
"scaffold": "tanstack-basic-auth",
"expectations": [
"Imports createCsrfMiddleware and createStart from @tanstack/react-start",
"Creates CSRF middleware filtered to handlerType === 'serverFn'",
"Registers CSRF middleware before clerkMiddleware() in requestMiddleware"
]
}
]
}
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools, Needs Node.js
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- clerk
- Publisher
- Clerk (Official)
- Source
- clerk/skills · skills/clerk-tanstack-patterns · commit c5d2c0d
- Licence
- MIT License (redistribution allowed)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by clerk.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download clerk-tanstack-patterns.zip