clerk-react-patterns — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited clerk-react-patterns (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill covers@clerk/reactfor Vite/CRA SPAs. For Next.js useclerk-nextjs-patterns. For TanStack Start useclerk-tanstack-patterns.
| Task | Reference |
|---|---|
| useAuth / useUser / useClerk hooks | references/hooks.md |
| Protected routes with React Router | references/protected-routes.md |
| Custom sign-in / sign-up forms | references/custom-flows.md |
| React Router v6/v7 integration | references/router-integration.md |
| Reference | Description |
|---|---|
references/hooks.md | useAuth, isLoaded guard |
references/protected-routes.md | ProtectedRoute pattern |
references/custom-flows.md | useSignIn, useSignUp flows |
references/router-integration.md | React Router v6/v7 setup |
npm install @clerk/react.env:
VITE_CLERK_PUBLISHABLE_KEY=pk_...src/main.tsx:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ClerkProvider } from '@clerk/react'
import App from './App.tsx'
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
<App />
</ClerkProvider>
</StrictMode>,
)@clerk/react is client-only — there is no server-side auth(). All auth state comes from hooks.
isLoaded must be true before trusting isSignedIn — always guard on isLoadeduseClerk() gives access to signOut, openSignIn, openUserProfile and other methodsgetToken() from useAuth() fetches the session JWT for API callsimport { useAuth } from '@clerk/react'
export function Dashboard() {
const { isLoaded, isSignedIn, userId } = useAuth()
if (!isLoaded) return <div>Loading...</div>
if (!isSignedIn) return <div>Please sign in</div>
return <div>Hello {userId}</div>
}import { Navigate, Outlet } from 'react-router-dom'
import { useAuth } from '@clerk/react'
export function ProtectedRoute() {
const { isLoaded, isSignedIn } = useAuth()
if (!isLoaded) return <div>Loading...</div>
if (!isSignedIn) return <Navigate to="/sign-in" replace />
return <Outlet />
}<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Route>
<Route path="/sign-in" element={<SignIn />} />
</Routes>import { useAuth } from '@clerk/react'
export function DataFetcher() {
const { getToken } = useAuth()
async function fetchData() {
const token = await getToken()
if (!token) return
const res = await fetch('/api/data', {
headers: { Authorization: `Bearer ${token}` },
})
return res.json()
}
return <button onClick={fetchData}>Load</button>
}| Symptom | Cause | Fix |
|---|---|---|
isSignedIn is undefined | isLoaded is still false | Always check isLoaded first |
ClerkProvider missing | Provider not at root | Wrap <App> in main.tsx |
| Env var undefined | Wrong Vite prefix | Use VITE_CLERK_PUBLISHABLE_KEY, access via import.meta.env |
Token is null | User not signed in | Null-check getToken() result |
| Sign-in component shows blank | No publishableKey on provider | Pass publishableKey explicitly |
clerk-setup - Initial Clerk installclerk-custom-ui - Custom flows & appearanceclerk-orgs - B2B organizations~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.