Internal DocumentationArchived DocumentationDo dev legacyArchiveClerk migration

Clerk Waitlist Implementation

This document describes the hybrid implementation of Clerk's official waitlist component integrated with our existing custom waitlist system.

Overview

We've implemented a hybrid approach that combines Clerk's polished waitlist UI components with our existing custom role-based system. This provides the best user experience while preserving all our existing functionality and user data.

Architecture

Hybrid System Design

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   New Users     │    │  Existing Users  │    │ OAuth Users     │
│                 │    │                  │    │                 │
│ Clerk Waitlist  │    │ Custom Waitlist  │    │ Direct Access   │
│       ↓         │    │       ↓          │    │       ↓         │
│ Clerk Approval  │    │ Admin Approval   │    │ "user" role     │
│       ↓         │    │       ↓          │    │                 │
│"waitlist-       │    │"waitlist-        │    │                 │
│ approved" role  │    │ approved" role   │    │                 │
└─────────────────┘    └──────────────────┘    └─────────────────┘

                        ┌──────────────────┐
                        │   Onboarding     │
                        │       ↓          │
                        │   "user" role    │
                        └──────────────────┘

User Journey Flows

New Users (Clerk Waitlist)

  1. Visit Homepage → See Clerk <Waitlist /> component
  2. Submit Email → Joins Clerk's waitlist system
  3. Admin Approval → Admin approves via Clerk Dashboard
  4. Webhook Triggersuser.updated event detected
  5. Role Assignment → System grants "waitlist-approved" role
  6. Access Granted → User can sign in and complete onboarding

Existing Users (Custom System)

  1. Existing Flow → Continue using custom waitlist system
  2. Admin Approval → Via existing admin dashboard
  3. Role Assignment"waitlist-approved" role granted
  4. Access Granted → User proceeds to onboarding

Implementation Details

1. ClerkProvider Configuration

// apps/dodev/components/app-providers.tsx
<ClerkProvider
  publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
  signInUrl="/sign-in"
  signUpUrl="/sign-up"
  waitlistUrl="/"  // 👈 Points to homepage for waitlist
  allowedRedirectOrigins={[...]}
>

2. Waitlist Component Integration

Homepage Integration

// apps/dodev/components/hero-section.tsx
{!isAuthenticated && (
  <ClerkWaitlistSection 
    title="Get Early Access"
    description="Join our waitlist to be the first to experience our AI-powered development platform."
    showDecorative={false}
  />
)}

Dedicated Waitlist Page

  • Route: /waitlist
  • Features:
    • Unauthenticated: Shows Clerk waitlist signup
    • Waitlisted: Shows status with progress indicators
    • Approved: Welcome message with dashboard access

3. Webhook Integration

The existing Clerk webhook (/api/webhooks/clerk/route.ts) has been enhanced to detect and handle Clerk waitlist approvals:

if (eventType === "user.updated") {
  // Detect Clerk waitlist approval
  const hasBasicAccess = evt.data.email_addresses?.length > 0
  const hasNoCustomRoles = !currentRoles.includes("waitlist-approved") && 
                           !currentRoles.includes("user") &&
                           currentRoles.length <= 1
  
  const wasApprovedFromClerkWaitlist = hasBasicAccess && hasNoCustomRoles && 
    currentRoles.includes("waitlist")
  
  if (wasApprovedFromClerkWaitlist) {
    // Grant waitlist-approved role (matches existing flow)
    const updatedRoles = [...currentRoles.filter(role => role !== "waitlist"), "waitlist-approved"]
    
    await client.users.updateUser(id, {
      publicMetadata: {
        ...public_metadata,
        roles: updatedRoles,
        waitlistApprovedAt: Date.now(),
        approvedBy: "clerk-waitlist",
        source: "clerk-waitlist",
      },
    })
  }
}

User Management

Clerk Dashboard Management

  1. Navigate to: Clerk Dashboard → Waitlist
  2. Approve Users: Click menu (⋯) → "Invite" to approve access
  3. Deny Users: Click menu (⋯) → "Deny" to reject access

Existing Admin Dashboard

  • Custom waitlist users continue to be managed via existing admin interface
  • All functionality preserved: Bulk approval, rejection reasons, analytics

Role System Integration

Role Hierarchy (Unchanged)

"waitlist" → "waitlist-approved" → "user" → "staff" → "admin" → "super_admin"

Role Sources

  • "clerk-waitlist": Users approved via Clerk Dashboard
  • "admin": Users approved via custom admin dashboard
  • "organic": Default source for new signups

Configuration Requirements

1. Clerk Dashboard Setup

  • Waitlist Mode Enabled: User Authentication → Restrictions → Waitlist
  • Webhook Configured: Points to /api/webhooks/clerk
  • Events Subscribed: user.created, user.updated, user.deleted

2. Environment Variables

# Required for Clerk integration
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...
CLERK_SECRET_KEY=sk_live_...
CLERK_WEBHOOK_SECRET=whsec_...

# Required for Convex sync
NEXT_PUBLIC_CONVEX_URL=https://...

Pages and Components

New Components

  1. ClerkWaitlistSection - Reusable waitlist component with Clerk integration
  2. /waitlist page - Dedicated waitlist page with status handling

Updated Components

  1. Homepage - Integrated Clerk waitlist for unauthenticated users
  2. Hero Section - Shows waitlist instead of "Get Started" button
  3. ClerkProvider - Added waitlistUrl configuration

Benefits of Hybrid Approach

✅ Advantages

  • Zero Risk: Existing users and functionality unaffected
  • Enhanced UX: New users get Clerk's polished waitlist interface
  • Preserved Investment: All custom admin tools and analytics maintained
  • Seamless Integration: Both systems feed into same role hierarchy
  • Future Flexibility: Can gradually migrate existing users if desired

⚠️ Considerations

  • Dual Management: Admins need to check both Clerk Dashboard and custom admin
  • Training Required: Team needs to understand both approval flows
  • Monitoring: Need to track both systems for waitlist analytics

Testing Checklist

New User Flow (Clerk Waitlist)

  • Homepage shows Clerk waitlist component for unauthenticated users
  • Email submission works via Clerk waitlist
  • User appears in Clerk Dashboard waitlist
  • Admin approval via Clerk Dashboard works
  • Webhook grants "waitlist-approved" role correctly
  • User can sign in after approval
  • Onboarding flow works normally

Existing User Flow (Custom System)

  • Existing admin dashboard continues to work
  • Custom waitlist approval still grants "waitlist-approved" role
  • All existing functionality preserved
  • Analytics and reporting continue to work

Integration Points

  • Role transitions work correctly for both systems
  • Convex sync works for both approval methods
  • User metadata includes correct source information
  • No conflicts between the two systems

Migration Strategy for Existing Users

  • Keep existing users in custom system
  • Use Clerk waitlist only for new signups
  • Maintain both systems indefinitely

Option B: Gradual Migration

  • Create admin tool to migrate existing waitlist users to Clerk
  • Notify users about the transition
  • Migrate in batches with rollback capability

Option C: Full Migration

  • Export all waitlist users from custom system
  • Import into Clerk waitlist (if API available)
  • Sunset custom waitlist system

Troubleshooting

Common Issues

Webhook Not Triggering

  • Check webhook URL in Clerk Dashboard
  • Verify CLERK_WEBHOOK_SECRET environment variable
  • Check webhook endpoint is publicly accessible

Role Assignment Not Working

  • Verify webhook logic for detecting Clerk approvals
  • Check Convex sync is working correctly
  • Ensure user has correct roles in Clerk publicMetadata

Waitlist Component Not Showing

  • Verify waitlistUrl="/" in ClerkProvider
  • Check Clerk waitlist mode is enabled in dashboard
  • Ensure component is properly imported

Debugging Tools

  • Clerk Dashboard: Check webhook delivery status
  • Server Logs: Monitor webhook processing
  • Admin Dashboard: Verify role assignments
  • Browser DevTools: Check component rendering

Future Enhancements

Potential Improvements

  1. Unified Admin Interface: Single dashboard for both systems
  2. Advanced Analytics: Combined reporting across both waitlist systems
  3. Automated Migration Tool: Tool to move users between systems
  4. Email Templates: Custom email notifications for approvals
  5. Position Tracking: Integrate Clerk waitlist position with existing tracking

API Integrations

  • Clerk Management API: Programmatic waitlist management
  • Notification Services: Automated approval notifications
  • Analytics Integration: Track conversion rates and user flows

Support and Documentation

Resources

Contact

  • Technical Issues: Development team
  • User Management: Admin dashboard
  • Clerk-specific Issues: Clerk Dashboard → Support

On this page