1Clerk Project Setup
- Create a free account at clerk.com
- Click Create application
- Enter app name (e.g., My React App)
- Select login methods (Email, Google, GitHub, etc.)
- Copy
Publishable keyfrom API Keys
2React App Integration
Install Package
Terminal
npm install @clerk/clerk-reactEnvironment Variables
.env.local
# .env.local
VITE_CLERK_PUBLISHABLE_KEY=pk_test_xxx...ClerkProvider Setup
main.tsx
// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ClerkProvider } from '@clerk/clerk-react';
import App from './App';
import './index.css';
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>
);Environment Variable Note
When using Vite, environment variable names must start with VITE_.
Next.js uses NEXT_PUBLIC_.
3Auth UI Components
Clerk provides ready-to-use UI components.
components/AuthButtons.tsx
// components/AuthButtons.tsx
import {
SignedIn,
SignedOut,
SignInButton,
SignUpButton,
UserButton,
} from '@clerk/clerk-react';
export function AuthButtons() {
return (
<div className="flex items-center gap-4">
<SignedOut>
<SignInButton mode="modal">
<button className="px-4 py-2 bg-blue-600 text-white rounded-lg">
Sign In
</button>
</SignInButton>
<SignUpButton mode="modal">
<button className="px-4 py-2 border border-gray-300 rounded-lg">
Sign Up
</button>
</SignUpButton>
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
</div>
);
}Key Components
SignedIn- Displayed only when signed inSignedOut- Displayed only when signed outUserButton- Profile dropdown menuSignInButton- Sign in button/modalSignUpButton- Sign up button/modal
4Protected Route Implementation
To protect pages that require login, create a ProtectedRoute component.
components/ProtectedRoute.tsx
// components/ProtectedRoute.tsx
import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react';
interface ProtectedRouteProps {
children: React.ReactNode;
}
export function ProtectedRoute({ children }: ProtectedRouteProps) {
return (
<>
<SignedIn>{children}</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</>
);
}5Accessing User Info
Use the useUser hook to access the currently signed-in user's information.
components/UserProfile.tsx
// components/UserProfile.tsx
import { useUser } from '@clerk/clerk-react';
export function UserProfile() {
const { isLoaded, isSignedIn, user } = useUser();
if (!isLoaded) {
return <div>Loading...</div>;
}
if (!isSignedIn) {
return <div>Sign in required</div>;
}
return (
<div className="p-4 bg-white rounded-lg shadow">
<img
src={user.imageUrl}
alt={user.fullName || 'Profile'}
className="w-16 h-16 rounded-full"
/>
<h2 className="mt-2 text-lg font-bold">{user.fullName}</h2>
<p className="text-gray-600">{user.primaryEmailAddress?.emailAddress}</p>
</div>
);
}6Backend API Integration (Optional)
To include an auth token when calling backend APIs, use the useAuth hook.
hooks/useAuthenticatedFetch.ts
// hooks/useAuthenticatedFetch.ts
import { useAuth } from '@clerk/clerk-react';
export function useAuthenticatedFetch() {
const { getToken } = useAuth();
return async (url: string, options: RequestInit = {}) => {
const token = await getToken();
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
};
}
// Usage example
// const authFetch = useAuthenticatedFetch();
// const data = await authFetch('/api/projects');Token Verification on Backend
server.js
// Backend (Node.js/Express example)
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node';
// Verify token with middleware
app.get('/api/protected',
ClerkExpressRequireAuth(),
(req, res) => {
// Access user ID via req.auth.userId
res.json({ userId: req.auth.userId });
}
);When Should You Choose Clerk?
Next Steps
- UI Customization - Customize styles to match your brand
- Organizations - Add team/organization features
- Supabase Integration - Use with a database