Skip to content

DanailMinchev/payload-clerk-example

Repository files navigation

Payload and Clerk example

This is an example for Payload CMS and Clerk integration.

YouTube videos:

PART 1

Payload and Clerk example

https://www.youtube.com/watch?v=7PNGNqqFlu0

Source code in the part-1 branch: https://github.com/DanailMinchev/payload-clerk-example/tree/feat/part-1

Getting Started

Install dependencies:

npm ci
  1. Create a new Clerk application and configure:

Enable Email as Sign in option.

The setup is described in details in the videos above, but here are the settings for reference:

  1. Copy the env.example file into .env.local file.

  2. Set Clerk environment variables documentation:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY

Your Clerk app's Publishable Key, which you can find in the Clerk Dashboard. It will be prefixed with pktest in development instances and pklive in production instances.

CLERK_SECRET_KEY

Your Clerk app's Secret Key, which you can find in the Clerk Dashboard. It will be prefixed with sktest in development instances and sklive in production instances. Do not expose this on the frontend with a public environment variable.

SIGNING_SECRET

In case you are going to use Webhooks, you will need to set Signing Secret.

  1. Set Payload environment variables documentation

PAYLOAD_SECRET

This environmental variable acts as your secret key. It's paramount that you ensure its value is both secure and strong, as it's integral to the encryption and decryption process.

DATABASE_URI

This is the database connection string. Uncomment DATABASE_URI for SQLite or PostgreSQL.

  1. If you selected the PostgreSQL you can use Docker:
docker compose up

and edit the src/payload.config.ts file:

Uncomment:

import { postgresAdapter } from "@payloadcms/db-postgres";

Comment / delete:

import { sqliteAdapter } from "@payloadcms/db-sqlite";

Uncomment:

  // PostgreSQL
db: postgresAdapter({
  pool: {
    connectionString: process.env.DATABASE_URI || "",
  },
}),

Comment / delete:

  // SQLite
db: sqliteAdapter({
  client: {
    url: process.env.DATABASE_URI || "",
  },
}),
  1. For testing and local development purposes following users are being used:

Please set the environment variables accordingly with their passwords in your .env.local file:

E2E_CLERK_ALL_ROLES_USER_EMAIL=[email protected]
E2E_CLERK_ALL_ROLES_USER_PASSWORD=
E2E_CLERK_ALL_ROLES_USER_PHONE=+19735550101

E2E_CLERK_SUPER_ADMIN_USER_EMAIL=[email protected]
E2E_CLERK_SUPER_ADMIN_USER_PASSWORD=
E2E_CLERK_SUPER_ADMIN_USER_PHONE=+19735550102

E2E_CLERK_ADMIN_USER_EMAIL=[email protected]
E2E_CLERK_ADMIN_USER_PASSWORD=
E2E_CLERK_ADMIN_USER_PHONE=+19735550103

E2E_CLERK_EDITOR_USER_EMAIL=[email protected]
E2E_CLERK_EDITOR_USER_PASSWORD=
E2E_CLERK_EDITOR_USER_PHONE=+19735550104

E2E_CLERK_AUTHENTICATED_USER_EMAIL=[email protected]
E2E_CLERK_AUTHENTICATED_USER_PASSWORD=
E2E_CLERK_AUTHENTICATED_USER_PHONE=+19735550105

The above users are using test emails and test phone numbers as described in Test emails and phones.

If you want to use phone numbers, you need to enable "Phone number" in the Clerk's dashboard, otherwise seed endpoint will not work.

Phone number

Otherwise, leave the E2E_CLERK_*_USER_PHONE environment variables empty.

  1. Register the E2E users.

You can register the E2E users from the above point manually or automatically using the GET /api/app/seed endpoint.

Run the application: npm run dev

Registering automatically

Invoke / navigate to http://localhost:3000/api/app/seed endpoint.

Observe the console for logs.

WARNING: the endpoint will delete your existing data

Registering manually

You should register your [email protected] user in Clerk manually and set the super-admin role.

The [email protected] user should have following public metadata:

{
  "roles": ["super-admin"]
}

and you should set the rest of the user roles via the admin dashboard as follows:

  1. Run the development server (if not running already):
npm run dev

Open http://localhost:3000 with your browser to see the result.

Webhooks

Please refer to the official documentation - Sync Clerk data to your app with webhooks.

The app exposes POST /api/clerk/webhooks endpoint which can be configured in the Clerk Dashboard.

Environment variables:

Currently, the webhooks endpoint is listening on the following events:

  • user.created
  • user.updated
  • user.deleted

Testing webhooks with ngrok

Please follow the official documentation - Setup & Installation

To run ngrok in Docker (macOS):

docker run -it -e NGROK_AUTHTOKEN={NGROK_AUTHTOKEN} ngrok/ngrok:latest http host.docker.internal:3000 --url={NGROK_DOMAIN}

To run ngrok in Docker (other OS):

docker run -it -e NGROK_AUTHTOKEN={NGROK_AUTHTOKEN} ngrok/ngrok:latest http 3000 --url={NGROK_DOMAIN}

To run ngrok using native binary:

ngrok http 3000 --url={NGROK_DOMAIN}

Replace {NGROK_AUTHTOKEN} with your authtoken.

Replace {NGROK_DOMAIN} with your free static domain, for example: your-static-domain-here.ngrok-free.app.

E2E Testing

There are E2E tests implemented using Playwright.

They are devided into two categories

  • api-tests Used to verify the access control.
  • app-tests Used to verify the app pages, including those behind authentication.

Before running the tests, you should install dependencies by executing:

npx playwright install
npx playwright install-deps

Then you can use following scripts:

  • For UI mode:

    npm run playwright:test:ui
  • For command line mode with debugging:

    npm run playwright:test:debug
  • For command line mode (used for CI):

    npm run playwright:test