All skills
clerk avatar

/clerk-tanstack-patterns

@ca5e365 official
by clerkclerk/skills83 stars
5

TanStack React Start auth patterns with @clerk/tanstack-react-start - createServerFn, beforeLoad guards, loaders, Vinxi server. Triggers on: TanStack auth, createServerFn clerk, beforeLoad protection, TanStack Start middleware.

Use this Skill: https://skilld.dev/gh/clerk/skills/clerk-tanstack-patterns

This session only. Nothing lands on disk.

referencesserver-functions.md

≈538 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Server Functions (CRITICAL)

createServerFn with auth()

createServerFn runs on the server. Use auth() from @clerk/tanstack-react-start/server inside handlers:

import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'

export const getAuthenticatedUser = createServerFn().handler(async () => {
  const { isAuthenticated, userId } = await auth()

  if (!isAuthenticated) {
    throw new Error('Unauthorized')
  }

  return { userId }
})

Import Path

// Server-side auth: always import from /server subpath
import { auth } from '@clerk/tanstack-react-start/server'

// Client-side hooks: import from package root
import { useAuth, useUser } from '@clerk/tanstack-react-start'

Mixing these causes runtime errors.

Redirect Pattern

import { createServerFn } from '@tanstack/react-start'
import { redirect } from '@tanstack/react-router'
import { auth } from '@clerk/tanstack-react-start/server'

export const requireAuth = createServerFn().handler(async () => {
  const { isAuthenticated, userId } = await auth()

  if (!isAuthenticated) {
    throw redirect({ to: '/sign-in' })
  }

  return { userId }
})

redirect must be thrown, not returned.

Org-Scoped Server Function

export const getOrgData = createServerFn().handler(async () => {
  const { isAuthenticated, userId, orgId } = await auth()

  if (!isAuthenticated) {
    throw redirect({ to: '/sign-in' })
  }

  if (!orgId) {
    throw redirect({ to: '/select-org' })
  }

  const data = await db.items.findMany({ where: { orgId } })
  return { data, orgId }
})

Calling from Components

Server functions can be called in beforeLoad, loaders, or directly in components:

// In a component (client-side trigger)
import { getOrgData } from '~/server/functions'

function Page() {
  async function handleClick() {
    const result = await getOrgData()
    console.log(result.data)
  }

  return <button onClick={handleClick}>Load</button>
}

Docs

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides instructional patterns for integrating Clerk authentication with TanStack React Start apps. All configurations, package dependencies, environment variables, and code implementations follow standardized practices for the Clerk platform without any security anomalies or risks.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at ca5e365. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 6 months ago
What it can do
Network
metadata
{
  "author": "clerk",
  "version": "1.0.0"
}
All 1 allowed tools
WebFetch
  • TypeScript
  • clerk
  • tanstack
  • react-start
  • authentication
  • server-functions
  • route-guards
  • vinxi

README badge

README badge for clerk/skills/clerk-tanstack-patterns

Implements Clerk authentication patterns for TanStack React Start using createServerFn, beforeLoad route guards, and Vinxi server middleware. Covers server-side auth checks, redirects for unauthenticated users, and passing auth context through loaders.

Generated from the current SKILL.md.

Does this skill work with TanStack Router without React Start?
No. This skill is specific to TanStack React Start, which runs on Vinxi. It uses createServerFn and clerkMiddleware in a Vinxi-based setup.
How do I protect routes from unauthenticated access?
Use beforeLoad on a route definition with a createServerFn that calls auth() and throws redirect() if not authenticated. The skill provides a minimal pattern example.
What should I import auth() from?
Always import from @clerk/tanstack-react-start/server on the server side. Mixing client and server imports is a common mistake.
Where do I add clerkMiddleware?
Add it to the requestMiddleware array in your Vinxi start.ts entry file. If auth() returns empty, clerkMiddleware is likely missing.
Can I use client-side hooks like useAuth?
Yes, useAuth and useUser are React hooks available on the client side after you wrap your root with ClerkProvider.

Generated from the current SKILL.md. These answers refresh after source changes.