DEV Community

Alex Spinov
Alex Spinov

Posted on

Clerk Has a Free API — Drop-In Authentication for React and Next.js

Clerk provides complete user management — sign-up, sign-in, user profiles, organizations, and MFA — with pre-built UI components that look great out of the box.

Why Clerk?

  • Pre-built components<SignIn />, <UserButton /> — production-ready UI
  • Next.js middleware — protect routes with one line
  • Organizations — multi-tenant auth built-in
  • Free tier — 10,000 monthly active users

Quick Start (Next.js)

npm install @clerk/nextjs
Enter fullscreen mode Exit fullscreen mode
// middleware.ts
import { clerkMiddleware } from '@clerk/nextjs/server';
export default clerkMiddleware();
export const config = { matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'] };
Enter fullscreen mode Exit fullscreen mode
// app/layout.tsx
import { ClerkProvider, SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs';

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html>
        <body>
          <header>
            <SignedOut>
              <SignInButton />
            </SignedOut>
            <SignedIn>
              <UserButton />
            </SignedIn>
          </header>
          {children}
        </body>
      </html>
    </ClerkProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Pre-Built Components

import { SignIn, SignUp, UserProfile } from '@clerk/nextjs';

// Full sign-in page
export default function SignInPage() {
  return <SignIn />;
}

// Full sign-up page
export default function SignUpPage() {
  return <SignUp />;
}

// User profile management
export default function ProfilePage() {
  return <UserProfile />;
}
Enter fullscreen mode Exit fullscreen mode

Protect Routes (Server)

import { auth } from '@clerk/nextjs/server';

export default async function Dashboard() {
  const { userId } = await auth();

  if (!userId) {
    redirect('/sign-in');
  }

  const user = await currentUser();
  return <h1>Welcome, {user.firstName}!</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Protect API Routes

import { auth } from '@clerk/nextjs/server';

export async function GET() {
  const { userId } = await auth();

  if (!userId) {
    return new Response('Unauthorized', { status: 401 });
  }

  const data = await getDataForUser(userId);
  return Response.json(data);
}
Enter fullscreen mode Exit fullscreen mode

Hooks (Client)

import { useUser, useAuth, useOrganization } from '@clerk/nextjs';

function Dashboard() {
  const { user, isLoaded } = useUser();
  const { getToken } = useAuth();
  const { organization } = useOrganization();

  if (!isLoaded) return <Loading />;

  return (
    <div>
      <h1>Hi, {user.firstName}</h1>
      <p>Email: {user.primaryEmailAddress?.emailAddress}</p>
      <p>Org: {organization?.name}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Organizations (Multi-Tenant)

import { OrganizationSwitcher, CreateOrganization } from '@clerk/nextjs';

// Org switcher in navbar
<OrganizationSwitcher />

// Create org page
<CreateOrganization />
Enter fullscreen mode Exit fullscreen mode

Webhooks

import { Webhook } from 'svix';

export async function POST(req: Request) {
  const body = await req.text();
  const wh = new Webhook(process.env.CLERK_WEBHOOK_SECRET!);
  const event = wh.verify(body, headers) as WebhookEvent;

  switch (event.type) {
    case 'user.created':
      await db.createUser(event.data);
      break;
    case 'user.deleted':
      await db.deleteUser(event.data.id);
      break;
  }

  return new Response('OK');
}
Enter fullscreen mode Exit fullscreen mode

Building authenticated apps? Check out my Apify actors for web scraping behind auth, or email spinov001@gmail.com for custom solutions.

Clerk, Auth.js, or Lucia — which auth solution do you use? Share below!

Top comments (0)