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.

referencesloaders.md

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

Loaders (HIGH)

Auth in Loaders

Loaders receive context from beforeLoad. Pass userId or orgId through context:

export const Route = createFileRoute('/dashboard')({
  beforeLoad: async () => {
    const { userId } = await requireAuth()
    return { userId }
  },
  loader: async ({ context }) => {
    const projects = await db.projects.findMany({
      where: { ownerId: context.userId },
    })
    return { projects }
  },
  component: function Dashboard() {
    const { projects } = Route.useLoaderData()
    return (
      <ul>
        {projects.map(p => <li key={p.id}>{p.name}</li>)}
      </ul>
    )
  },
})

Org-Aware Loader

const getOrgContext = createServerFn().handler(async () => {
  const { isAuthenticated, userId, orgId } = await auth()
  if (!isAuthenticated) throw redirect({ to: '/sign-in' })
  return { userId, orgId }
})

export const Route = createFileRoute('/app/projects')({
  beforeLoad: async () => await getOrgContext(),
  loader: async ({ context }) => {
    if (!context.orgId) {
      return { projects: [], requiresOrg: true }
    }

    const projects = await db.projects.findMany({
      where: { orgId: context.orgId },
    })
    return { projects, requiresOrg: false }
  },
})

useLoaderData

Access loader data in the route component:

function Projects() {
  const { projects, requiresOrg } = Route.useLoaderData()

  if (requiresOrg) {
    return <OrganizationSwitcher />
  }

  return <ProjectList projects={projects} />
}

Server vs Client Data

Loaders run on the server during SSR and on the client during navigation. auth() works in both because it reads from the Clerk middleware context.

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.