Agent skill
Clerk Authentication
Guidelines for integrating Clerk authentication into the RFP Discovery application with Convex
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/clerk-auth-atemndobs-nebula-rfp-2
SKILL.md
Clerk Authentication Skill
This skill provides guidance for integrating Clerk as the authentication provider for the RFP Discovery application.
Installation
npm install @clerk/clerk-react
Environment Setup
Create environment variables:
VITE_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx
Provider Setup
Wrap your app in the Clerk provider (index.tsx):
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ClerkProvider } from '@clerk/clerk-react';
import App from './App';
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
if (!PUBLISHABLE_KEY) {
throw new Error("Missing Publishable Key");
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
<App />
</ClerkProvider>
</React.StrictMode>
);
Integration with Convex
When using both Clerk and Convex, set up providers together:
import { ClerkProvider, useAuth } from '@clerk/clerk-react';
import { ConvexProviderWithClerk } from 'convex/react-clerk';
import { ConvexReactClient } from 'convex/react';
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
function App() {
return (
<ClerkProvider publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}>
<ConvexProviderWithClerk client={convex} useAuth={useAuth}>
<MainApp />
</ConvexProviderWithClerk>
</ClerkProvider>
);
}
Authentication Components
Sign In/Sign Up Buttons
import { SignInButton, SignUpButton, SignedIn, SignedOut, UserButton } from '@clerk/clerk-react';
function Header() {
return (
<header>
<SignedOut>
<SignInButton mode="modal" />
<SignUpButton mode="modal" />
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
</header>
);
}
Protected Content
import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react';
function ProtectedPage() {
return (
<>
<SignedIn>
<AdminView />
</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</>
);
}
User Hooks
Get Current User
import { useUser, useAuth } from '@clerk/clerk-react';
function UserProfile() {
const { user, isLoaded, isSignedIn } = useUser();
const { userId, getToken } = useAuth();
if (!isLoaded) return <div>Loading...</div>;
if (!isSignedIn) return <div>Not signed in</div>;
return (
<div>
<p>Welcome, {user.firstName}!</p>
<p>Email: {user.primaryEmailAddress?.emailAddress}</p>
</div>
);
}
Protected Routes Pattern
For this single-page app, protect specific views rather than routes:
function App() {
const [view, setView] = useState<'home' | 'rawData' | 'admin'>('home');
const { isSignedIn, isLoaded } = useUser();
// Redirect to sign-in for admin view if not authenticated
if (view === 'admin' && isLoaded && !isSignedIn) {
return <RedirectToSignIn />;
}
return (
<>
<ViewSwitcher currentView={view} onSwitchView={setView} />
{view === 'home' && <HomeView />}
{view === 'rawData' && <RawDataView />}
{view === 'admin' && <AdminView />}
</>
);
}
Access Control Patterns
Admin-Only Features
import { useUser } from '@clerk/clerk-react';
function AdminFeature() {
const { user } = useUser();
// Check for admin role (configure in Clerk Dashboard)
const isAdmin = user?.publicMetadata?.role === 'admin';
if (!isAdmin) {
return <p>You don't have permission to access this feature.</p>;
}
return <AdminPanel />;
}
Organization-Based Access
For multi-tenant scenarios (future consideration):
import { useOrganization } from '@clerk/clerk-react';
function TeamDashboard() {
const { organization } = useOrganization();
if (!organization) {
return <p>Please select a team.</p>;
}
return <Dashboard orgId={organization.id} />;
}
Session Token for API Calls
When calling the FastAPI backend with auth:
import { useAuth } from '@clerk/clerk-react';
function useAuthenticatedFetch() {
const { getToken } = useAuth();
const fetchWithAuth = async (url: string, options?: RequestInit) => {
const token = await getToken();
return fetch(url, {
...options,
headers: {
...options?.headers,
Authorization: `Bearer ${token}`,
},
});
};
return fetchWithAuth;
}
Migration Strategy
Phase 1: Add Clerk (Optional Auth)
- Install Clerk packages
- Add ClerkProvider wrapper
- Add SignIn/SignUp buttons to header
- Show UserButton when signed in
- Continue allowing unauthenticated access to main features
Phase 2: Protect Admin Features
- Require authentication for Admin view
- Store user preferences in Convex tied to userId
- Add user-specific evaluation history
Phase 3: Full Authentication
- Require authentication for all features
- Migrate localStorage settings to Convex per-user
- Add organization/team support for shared access
Styling Integration
Clerk components can be customized via the appearance prop:
<ClerkProvider
publishableKey={PUBLISHABLE_KEY}
appearance={{
elements: {
formButtonPrimary: {
backgroundColor: '#6366f1',
'&:hover': { backgroundColor: '#4f46e5' },
},
},
variables: {
colorPrimary: '#6366f1',
},
}}
>
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?