npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

payload-clerk-plugin

v0.1.1

Published

Payload CMS plugin for Clerk authentication integration

Readme

Payload Clerk Plugin

npm version License: MIT TypeScript Payload CMS

A comprehensive Payload CMS plugin that integrates Clerk authentication, providing seamless user management, role-based access control, and modern authentication flows.

✨ Features

🔐 Authentication & User Management

  • Clerk Authentication Strategy: Replace Payload's default auth with Clerk's secure authentication
  • Real-time User Sync: Automatic webhook-based synchronization of user data between Clerk and Payload
  • Role-Based Access Control: Flexible RBAC system with customizable admin and user roles
  • User Collection Enhancement: Automatically extends your user collection with Clerk-specific fields

🎛️ Admin Dashboard Integration

  • Custom Admin Views: Dedicated Clerk Users management interface within Payload admin
  • Role Management: Admin interface for updating user roles and permissions
  • Dashboard Components: Welcome panel with development tools and navigation enhancements
  • Smart Navigation: Conditional admin panel access based on user roles

🔧 Developer Experience

  • Webhook Handlers: Pre-built endpoints for Clerk webhook events
  • Utility Functions: Access control helpers and role checking utilities
  • TypeScript Support: Full type safety with comprehensive TypeScript definitions
  • Development Tools: Seeding endpoints and data refresh utilities

🚀 Installation

npm install payload-clerk-plugin
# or
pnpm add payload-clerk-plugin
# or
yarn add payload-clerk-plugin

📋 Prerequisites

  • Payload CMS v3.x
  • Next.js 15+
  • React 19+
  • Clerk account with a configured application

⚙️ Configuration

1. Configure Payload

Add the plugin to your payload.config.ts:

import { buildConfig } from 'payload'
import { clerkPlugin } from 'payload-clerk-plugin'

export default buildConfig({
  // ... your existing config
  plugins: [
    clerkPlugin({
      // Required: Roles configuration
      adminRoles: ['admin', 'super-admin'],
      allRoles: ['admin', 'editor', 'super-admin'],
      
      // Optional: Collection and endpoint configuration
      userCollection: 'users', // default: 'users'
      enabled: true, // default: true
      
      // Optional: Custom endpoint paths
      clerkConfig: {
        adminBaseUrl: '/admin', // default: '/admin'
        webhookPath: '/api/clerk/webhooks', // default: '/api/clerk/webhooks'
        refreshPath: '/api/refresh-clerk-data', // default: '/api/refresh-clerk-data'
        updateRolesPath: '/api/update-user-roles', // default: '/api/update-user-roles'
        seedPath: '/api/seed', // default: '/api/seed' (dev only)
      }
    })
  ],
})

2. Environment Variables

Create or update your .env.local:

# Payload
PAYLOAD_SECRET=your-payload-secret

# Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_WEBHOOK_SECRET=whsec_...

# Database
DATABASE_URI=mongodb://localhost:27017/your-db
# or for SQLite:
# DATABASE_URI=file:./database.db

3. Set Up Next.js Layouts and Components

Root Layout (app/layout.tsx)

import { ClerkProvider } from '@clerk/nextjs'
import { ClerkUserButton } from 'payload-clerk-plugin/client'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <ClerkProvider>
      <html>
        <body>
          <header>
            <nav>
              {/* Your navigation */}
              <ClerkUserButton 
                adminAccessRoles={['admin', 'super-admin']}
                adminBaseUrl="/admin"
              />
            </nav>
          </header>
          {children}
        </body>
      </html>
    </ClerkProvider>
  )
}

Authentication Pages

Create authentication pages using Clerk's pre-built components:

Sign In (app/login/[[...sign-in]]/page.tsx):

import { SignIn } from '@clerk/nextjs'

export default function Page() {
  return <SignIn />
}

Sign Up (app/register/[[...sign-up]]/page.tsx):

import { SignUp } from '@clerk/nextjs'

export default function Page() {
  return <SignUp />
}

User Profile (app/profile/[[...user-profile]]/page.tsx):

import { UserProfile } from '@clerk/nextjs'

export default function Page() {
  return <UserProfile />
}

Middleware (middleware.ts)

import { authMiddleware } from '@clerk/nextjs'

export default authMiddleware({
  publicRoutes: ['/'],
  // Protect admin routes
  ignoredRoutes: ['/api/clerk/webhooks']
})

export const config = {
  matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
}

🔧 Clerk Dashboard Setup

1. Create Clerk Application

  1. Go to Clerk Dashboard
  2. Create a new application
  3. Choose your preferred social providers
  4. Copy your API keys to .env.local

2. Configure Webhooks

  1. In your Clerk Dashboard, go to Webhooks
  2. Create a new webhook endpoint: https://yourdomain.com/api/clerk/webhooks
  3. Subscribe to these events:
    • user.created
    • user.updated
    • user.deleted
  4. Copy the webhook secret to CLERK_WEBHOOK_SECRET in your .env.local

3. Set Up User Metadata

Configure custom metadata fields in Clerk:

  1. Go to User & AuthenticationMetadata
  2. Add public metadata field: roles (array of strings)
  3. This allows the plugin to manage user roles

4. Authentication Settings

Configure redirect URLs in Paths:

  • Sign-in: /login
  • Sign-up: /register
  • User Profile: /profile
  • Home: /

🎯 Usage Examples

Access Control in Collections

// collections/Posts.ts
import { isAdminRoles } from 'payload-clerk-plugin/access'

export const Posts = {
  slug: 'posts',
  access: {
    read: () => true,
    create: isAdminRoles(['admin', 'editor']),
    update: isAdminRoles(['admin', 'editor']),
    delete: isAdminRoles(['admin'])
  },
  fields: [
    // ... your fields
  ]
}

Using Utility Functions

import { checkRoles } from 'payload-clerk-plugin/utilities'
import { currentUser } from '@clerk/nextjs/server'

export async function GET() {
  const user = await currentUser()
  
  if (!user || !checkRoles(['admin'], user.publicMetadata.roles)) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }
  
  // Admin-only logic here
  return Response.json({ message: 'Success' })
}

Custom Hooks Integration

// hooks/requireAuth.ts
import { setCreatedByOnCreate } from 'payload-clerk-plugin/hooks'

export const MyCollection = {
  slug: 'my-collection',
  hooks: {
    beforeChange: [setCreatedByOnCreate]
  },
  fields: [
    // ... your fields
  ]
}

🏗️ Implementation Status

✅ Implemented Features

  • Core Clerk Integration

    • User authentication strategy
    • Webhook-based user synchronization
    • Real-time data updates between Clerk and Payload
  • Role-Based Access Control

    • Configurable admin and user roles
    • Access control utilities and helpers
    • Collection-level permission management
  • Admin Dashboard

    • Custom Clerk Users management view
    • Role management interface
    • Enhanced navigation with conditional access
    • Development tools and seeding utilities
  • Developer Tools

    • TypeScript definitions and type safety
    • Utility functions for access control
    • Pre-built hooks for common patterns
    • Comprehensive testing suite

🗺️ Roadmap

🔄 In Progress

  • Enhanced Documentation: Comprehensive guides and examples
  • Testing Coverage: Extended test suite and E2E testing
  • Performance Optimizations: Caching and sync improvements

🎯 Planned Features

Multi-Tenancy Support

  • Clerk Organizations Integration: Full organization-based multi-tenancy
  • Tenant-Scoped Collections: Automatic data isolation per organization
  • Organization Role Management: Advanced RBAC with organization context
  • Tenant-Specific Admin Views: Organization-aware admin interface

Billing & Payments

  • Clerk Billing Integration: Seamless subscription management
  • Usage-Based Billing: Track and bill for resource usage
  • Payment Webhooks: Automated subscription lifecycle handling
  • Billing Dashboard: Admin interface for subscription management

Advanced Authentication

  • Custom Scopes & Permissions: Request custom API scopes (Google Drive, Calendar, etc.)
  • Access Token Management: Secure token storage and refresh handling
  • OAuth Provider Extensions: Additional third-party authentication options
  • Session Management: Advanced session controls and security policies

Internationalization

  • i18n Support: Multi-language admin interface
  • Localized Authentication: Region-specific auth flows
  • Custom Translations: Plugin-specific translation keys
  • RTL Language Support: Right-to-left language compatibility

📖 API Reference

Plugin Configuration

interface ClerkPluginConfig {
  adminRoles?: string[]           // Roles with admin access
  allRoles?: string[]            // All available system roles  
  userCollection?: string        // Target user collection slug
  enabled?: boolean              // Enable/disable plugin
  clerkConfig?: {
    adminBaseUrl?: string        // Admin panel base URL
    webhookPath?: string         // Clerk webhook endpoint
    refreshPath?: string         // Data refresh endpoint  
    updateRolesPath?: string     // Role update endpoint
    seedPath?: string           // Seeding endpoint (dev only)
  }
}

Exported Utilities

// Access control functions
import { 
  isAdminRoles,
  isAllowedRoles,
  checkRoles 
} from 'payload-clerk-plugin/access'

// Collection hooks
import { 
  setCreatedByOnCreate 
} from 'payload-clerk-plugin/hooks'

// Field generators  
import { 
  getCreatedByField 
} from 'payload-clerk-plugin/fields'

// UI components
import { 
  ClerkUserButton,
  AuthProvider 
} from 'payload-clerk-plugin/client'

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository
  2. Install dependencies: pnpm install
  3. Start development: pnpm dev
  4. Run tests: pnpm test

📄 License

MIT License - see LICENSE for details.

🆘 Support

🙏 Acknowledgments

Built with ❤️ for the Payload CMS and Clerk communities.

Special thanks to the Payload team for their excellent plugin architecture and documentation.