All skills
clerk avatar

/clerk-react-router-patterns

@23e7108 official
by clerkclerk/skills83 stars
5

React Router v7/v8 patterns with Clerk — rootAuthLoader, getAuth in loaders, clerkMiddleware, protected routes, SSR user data, org switching. Triggers on: react-router auth, rootAuthLoader, getAuth loader, react-router protected route, loader authentication, SSR auth react-router, useNavigate may be used only in the context of a Router.

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

This session only. Nothing lands on disk.

referencesloaders-actions.md

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

Loaders and Actions Auth

getAuth in Loaders

import { getAuth } from '@clerk/react-router/server'
import { redirect } from 'react-router'
import type { Route } from './+types/dashboard'

export async function loader(args: Route.LoaderArgs) {
  const { userId, orgId, sessionId } = await getAuth(args)
  if (!userId) throw redirect('/sign-in')
  return { data: await db.query(userId) }
}

getAuth in Actions

export async function action(args: Route.ActionArgs) {
  const { userId } = await getAuth(args)
  if (!userId) throw new Response('Unauthorized', { status: 401 })

  const fd = await args.request.formData()
  await db.insert({ userId, title: fd.get('title') })
  return redirect('/dashboard')
}

rootAuthLoader Callback Form

Pass a callback to rootAuthLoader when you need auth state in the root route:

import { rootAuthLoader } from '@clerk/react-router/server'

export async function loader(args: Route.LoaderArgs) {
  return rootAuthLoader(args, async ({ request }) => {
    const { userId } = request.auth
    if (!userId) return { user: null }
    return { user: await db.getUser(userId) }
  })
}

Available Auth Fields

Field Type Description
userId string | null Current user ID
sessionId string | null Current session ID
orgId string | null Active org ID
orgRole string | null User's role in active org
has() function Check permissions/features

CRITICAL

  • getAuth throws if clerkMiddleware is not installed
  • rootAuthLoader must be called in root.tsx loader — not just any loader
  • Import redirect from react-router, not from @remix-run/react-router

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides safe and well-documented patterns for integrating Clerk authentication with React Router v7/v8, correctly handling server-side authentication and SSR user data through official SDK methods.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

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

Last checked against GitHub yesterday.

Activeupdated 3 months ago
What it can do
Network
metadata
{
  "author": "clerk",
  "version": "1.1.0"
}
All 1 allowed tools
WebFetch
  • TypeScript
  • react-router
  • clerk
  • authentication
  • loaders
  • ssr
  • middleware
  • protected-routes

README badge

README badge for clerk/skills/clerk-react-router-patterns

Adds Clerk authentication to React Router v7 apps using rootAuthLoader, getAuth in loaders/actions, clerkMiddleware, and protected routes. Covers SSR user data, org switching, and common setup pitfalls like missing middleware or uninitialized rootAuthLoader.

Generated from the current SKILL.md.

Do I need to call rootAuthLoader in every route file?
No. rootAuthLoader must be called only in root.tsx's loader. Nested loaders use getAuth(args) instead, which reads the auth context that rootAuthLoader sets up.
Can I use getAuth in client components?
No. getAuth is a server-only function for loaders and actions. Use useAuth or useUser hooks in client components instead.
What happens if I forget to export clerkMiddleware?
The middleware won't run on requests, so auth context won't be attached and getAuth will fail or return empty values in loaders.
Does this skill support React Router v6?
No. This skill requires React Router v7.9 or later and @clerk/react-router v3+.

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