Choorai
Lv.2 React

Clerk Auth Guide

Clerk is the easiest way to add authentication to a React app. You can complete login/signup features in just 10 minutes.

Why Clerk?

  • React-optimized components and hooks
  • Social login (Google, GitHub, etc.) built-in
  • Free tier: 10,000 MAU per month
  • Customizable UI components

1Clerk Project Setup

  1. Create a free account at clerk.com
  2. Click Create application
  3. Enter app name (e.g., My React App)
  4. Select login methods (Email, Google, GitHub, etc.)
  5. Copy Publishable key from API Keys

2React App Integration

Install Package

Terminal
npm install @clerk/clerk-react

Environment 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 in
  • SignedOut - Displayed only when signed out
  • UserButton - Profile dropdown menu
  • SignInButton - Sign in button/modal
  • SignUpButton - 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?

Clerk Recommended

  • React/Next.js projects
  • Need quick auth implementation
  • Social login needed
  • UI customization is important

Consider Alternatives

  • Next.js only → NextAuth
  • Using Supabase → Supabase Auth
  • Enterprise requirements → Auth0

Next Steps

Last updated: February 22, 2026 · Version: v0.0.1

Send Feedback

Opens a new issue page with your message.

Open GitHub Issue