This library implements a collection protection in Payload CMS using Google reCAPTCHA v3.
npm install payload-recaptcha-v3


Payload reCAPTCHA v3 is a plugin for Payload used to protect collection operations with Google reCAPTCHA v3.
Please install the plugin version according to the Payload version. The major version of the plugin must match the major version of the Payload.
``shell`
yarn add payload-recaptcha-v3
`shell`
npm i payload-recaptcha-v3
`shell`
pnpm add payload-recaptcha-v3
In the plugins property of Payload config, call the plugin with the following options:
`ts
import { buildConfig } from 'payload';
import reCAPTCHAv3 from 'payload-recaptcha-v3';
export default buildConfig({
// ... rest of your config
plugins: [
reCAPTCHAv3({
secret: process.env.GOOGLE_RECAPTCHA_SECRET!,
}),
],
});
`
- secret: stringerrorHandler
Required. Your Google reCAPTCHA v3 secret key.
- : reCAPTCHAErrorHandlerskip
Optional. See more details
- : reCAPTCHASkipscoreThreshold
Optional. See more details
- : number
Optional. A value between 0 and 1 (default is 0.7). The received score from Google reCAPTCHA must be greater or equal than threshold.
To protect a collection's operation, you have to add in the Collection Config the property recaptcha into the custom.recaptcha
The property has to be an array of strings containing the operation name according to Available Collection operations.
`ts
import type { CollectionConfig } from 'payload';
export const Orders: CollectionConfig = {
slug: 'orders',
fields: [],
// ... rest of your config
custom: {
recaptcha: [
{
name: 'create',
action: 'submit',
},
{
name: 'update',
action: 'modify',
},
],
},
};
export default Orders;
`
Then, when you make an HTTP Request to the Payload API, include the header x-recaptcha-v3 with the token received from Google:
`js`
Optionally, you can set a errorHandler or skip as described in Plugin Options in a specific operation.
`ts
import type { CollectionConfig } from 'payload';
export const Orders: CollectionConfig = {
slug: 'orders',
fields: [],
// ... rest of your config
custom: {
recaptcha: [
{
name: 'create',
action: 'submit',
errorHandler: (args) => {
// ...
},
},
{
name: 'update',
action: 'modify',
skip: (args) => {
// ....
},
},
{
name: 'delete',
action: 'delete',
scoreThreshold: 0.9,
}
],
},
};
export default Orders;
`
This plugin uses Playwright for end-to-end testing with Google reCAPTCHA directly. However, there are some steps to test the plugin.
1. Provide DATABASE_URI, RECAPTCHA_SECRET and NEXT_PUBLIC_RECAPTCHA_SITE_KEY environment variables.pnpm build
2. Run and then pnpm dev:build.pnpm test
3. Run .
A callback function that when returns true, it will skip the Google reCAPTCHA verification (for example, when the user is an admin).
The arguments of function are the same of Before Operation Hook.
`ts`
export type reCAPTCHASkip = (
args: Parameters
) => boolean;
A callback function that is called when:
- The header x-recaptcha-v3 is not set.
- The fetch request generated an error.
- The response from Google was not a success.
- The response from Google was a success, but for another action.
When the errorHandler options property is not set, it will throw a Forbidden error by default.
`ts``
export type reCAPTCHAErrorHandler = (args: {
hookArgs: Parameters
response?: reCAPTCHAResponse;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
error?: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}) => any;
The response received from Google when verifying the token.
Properties
| Name | Description |
| :----------------------------------- | :------------------------------------------------------------------- |
| success: boolean | whether this request was a valid reCAPTCHA token for your site |
| score: number | the score for this request (0.0 - 1.0) |
| action: string | the action name for this request (important to verify) |
| challenge_ts: number | timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ) |
| hostname: string | the hostname of the site where the reCAPTCHA was solved |
| 'error-codes'?: reCAPTCHAErrorCode[] | optional |
| Error code | Description |
| :--------------------- | :------------------------------------------------------------------------------ |
| missing-input-secret | The secret parameter is missing. |
| invalid-input-secret | The secret parameter is invalid or malformed. |
| missing-input-response | The response parameter is missing. |
| invalid-input-response | The response parameter is invalid or malformed. |
| bad-request | The request is invalid or malformed. |
| timeout-or-duplicate | The response is no longer valid: either is too old or has been used previously. |
| invalid-keys | The secret key is incorrect. |