docs: improves hooks docs (#7133)
This commit is contained in:
@@ -6,43 +6,54 @@ desc: You can add hooks to any Collection, several hook types are available incl
|
||||
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Collections feature the ability to define the following hooks:
|
||||
Collection Hooks are [Hooks](./overview) that run on Documents within a specific [Collection](../configuration/collections). They allow you to execute your own logic during specific events of the Document lifecycle.
|
||||
|
||||
- [beforeOperation](#beforeoperation)
|
||||
- [beforeValidate](#beforevalidate)
|
||||
- [beforeChange](#beforechange)
|
||||
- [afterChange](#afterchange)
|
||||
- [beforeRead](#beforeread)
|
||||
- [afterRead](#afterread)
|
||||
- [beforeDelete](#beforedelete)
|
||||
- [afterDelete](#afterdelete)
|
||||
- [afterOperation](#afteroperation)
|
||||
|
||||
Additionally, `auth`-enabled collections feature the following hooks:
|
||||
|
||||
- [beforeLogin](#beforelogin)
|
||||
- [afterLogin](#afterlogin)
|
||||
- [afterLogout](#afterlogout)
|
||||
- [afterRefresh](#afterrefresh)
|
||||
- [afterMe](#afterme)
|
||||
- [afterForgotPassword](#afterforgotpassword)
|
||||
- [refresh](#refresh)
|
||||
- [me](#me)
|
||||
|
||||
## Config
|
||||
|
||||
All collection Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs.
|
||||
|
||||
`collections/exampleHooks.js`
|
||||
To add hooks to a Collection, use the `hooks` property in your [Collection Config](../configuration/collections):
|
||||
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload';
|
||||
|
||||
export const ExampleHooks: CollectionConfig = {
|
||||
slug: 'example-hooks',
|
||||
fields: [
|
||||
{ name: 'name', type: 'text'},
|
||||
],
|
||||
export const CollectionWithHooks: CollectionConfig = {
|
||||
// ...
|
||||
hooks: { // highlight-line
|
||||
// ...
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The following Collection Hooks are available:
|
||||
|
||||
- [`beforeOperation`](#beforeoperation)
|
||||
- [`beforeValidate`](#beforevalidate)
|
||||
- [`beforeChange`](#beforechange)
|
||||
- [`afterChange`](#afterchange)
|
||||
- [`beforeRead`](#beforeread)
|
||||
- [`afterRead`](#afterread)
|
||||
- [`beforeDelete`](#beforedelete)
|
||||
- [`afterDelete`](#afterdelete)
|
||||
- [`afterOperation`](#afteroperation)
|
||||
|
||||
Additionally, all [Auth-enabled Collections](../authentication/overview) feature the following auth-related Hooks:
|
||||
|
||||
- [`beforeLogin`](#beforelogin)
|
||||
- [`afterLogin`](#afterlogin)
|
||||
- [`afterLogout`](#afterlogout)
|
||||
- [`afterRefresh`](#afterrefresh)
|
||||
- [`afterMe`](#afterme)
|
||||
- [`afterForgotPassword`](#afterforgotpassword)
|
||||
- [`refresh`](#refresh)
|
||||
- [`me`](#me)
|
||||
|
||||
## Config Options
|
||||
|
||||
All Collection Hooks accept an array of [synchronous or asynchronous functions](./overview#async-vs-synchronous). Each Collection Hook receives specific arguments based on its own type, and has the ability to modify specific outputs.
|
||||
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload';
|
||||
|
||||
export const CollectionWithHooks: CollectionConfig = {
|
||||
// ...
|
||||
// highlight-start
|
||||
hooks: {
|
||||
beforeOperation: [(args) => {...}],
|
||||
beforeValidate: [(args) => {...}],
|
||||
@@ -54,7 +65,7 @@ export const ExampleHooks: CollectionConfig = {
|
||||
afterDelete: [(args) => {...}],
|
||||
afterOperation: [(args) => {...}],
|
||||
|
||||
// Auth-enabled hooks
|
||||
// Auth-enabled Hooks
|
||||
beforeLogin: [(args) => {...}],
|
||||
afterLogin: [(args) => {...}],
|
||||
afterLogout: [(args) => {...}],
|
||||
@@ -64,6 +75,7 @@ export const ExampleHooks: CollectionConfig = {
|
||||
refresh: [(args) => {...}],
|
||||
me: [(args) => {...}],
|
||||
},
|
||||
// highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
@@ -85,6 +97,15 @@ const beforeOperationHook: CollectionBeforeOperationHook = async ({
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeOperation` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between Hooks. [More details](./context). |
|
||||
| **`operation`** | The name of the operation that this hook is running within. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeValidate
|
||||
|
||||
Runs before the `create` and `update` operations. This hook allows you to add or format data before the incoming data is validated server-side.
|
||||
@@ -99,15 +120,23 @@ Please do note that this does not run before the client-side validation. If you
|
||||
import type { CollectionBeforeValidateHook } from 'payload'
|
||||
|
||||
const beforeValidateHook: CollectionBeforeValidateHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full Request object
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
originalDoc, // original document
|
||||
data,
|
||||
}) => {
|
||||
return data // Return data to either create or update a document with
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeValidate` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between Hooks. [More details](./context). |
|
||||
| **`data`** | The incoming data passed through the operation. |
|
||||
| **`operation`** | The name of the operation that this hook is running within. |
|
||||
| **`originalDoc`** | The Document before changes are applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeChange
|
||||
|
||||
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage, you can be confident that the data that will be saved to the document is valid in accordance to your field validations. You can optionally modify the shape of data to be saved.
|
||||
@@ -116,15 +145,23 @@ Immediately following validation, `beforeChange` hooks will run within `create`
|
||||
import type { CollectionBeforeChangeHook } from 'payload'
|
||||
|
||||
const beforeChangeHook: CollectionBeforeChangeHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full Request object
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
originalDoc, // original document
|
||||
data,
|
||||
}) => {
|
||||
return data // Return data to either create or update a document with
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeChange` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`data`** | The incoming data passed through the operation. |
|
||||
| **`operation`** | The name of the operation that this hook is running within. |
|
||||
| **`originalDoc`** | The Document before changes are applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterChange
|
||||
|
||||
After a document is created or updated, the `afterChange` hook runs. This hook is helpful to recalculate statistics such as total sales within a global, syncing user profile changes to a CRM, and more.
|
||||
@@ -133,15 +170,23 @@ After a document is created or updated, the `afterChange` hook runs. This hook i
|
||||
import type { CollectionAfterChangeHook } from 'payload'
|
||||
|
||||
const afterChangeHook: CollectionAfterChangeHook = async ({
|
||||
doc, // full document data
|
||||
req, // full Request object
|
||||
previousDoc, // document data before updating the collection
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
doc,
|
||||
}) => {
|
||||
return doc
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterChange` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`operation`** | The name of the operation that this hook is running within. |
|
||||
| **`previousDoc`** | The Document before changes were applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeRead
|
||||
|
||||
Runs before `find` and `findByID` operations are transformed for output by `afterRead`. This hook fires before hidden fields are removed and before localized fields are flattened into the requested locale. Using this Hook will provide you with all locales and all hidden fields via the `doc` argument.
|
||||
@@ -150,14 +195,22 @@ Runs before `find` and `findByID` operations are transformed for output by `afte
|
||||
import type { CollectionBeforeReadHook } from 'payload'
|
||||
|
||||
const beforeReadHook: CollectionBeforeReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full Request object
|
||||
query, // JSON formatted query
|
||||
doc,
|
||||
}) => {
|
||||
return doc
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeRead` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`query`** | The [Query](../queries/overview) of the request.
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterRead
|
||||
|
||||
Runs as the last step before documents are returned. Flattens locales, hides protected fields, and removes fields that users do not have access to.
|
||||
@@ -166,15 +219,22 @@ Runs as the last step before documents are returned. Flattens locales, hides pro
|
||||
import type { CollectionAfterReadHook } from 'payload'
|
||||
|
||||
const afterReadHook: CollectionAfterReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full Request object
|
||||
query, // JSON formatted query
|
||||
findMany, // boolean to denote if this hook is running against finding one, or finding many
|
||||
doc,
|
||||
}) => {
|
||||
return doc
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterRead` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`query`** | The [Query](../queries/overview) of the request.
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeDelete
|
||||
|
||||
Runs before the `delete` operation. Returned values are discarded.
|
||||
@@ -183,11 +243,20 @@ Runs before the `delete` operation. Returned values are discarded.
|
||||
import type { CollectionBeforeDeleteHook } from 'payload';
|
||||
|
||||
const beforeDeleteHook: CollectionBeforeDeleteHook = async ({
|
||||
req, // full Request object
|
||||
id, // id of document to delete
|
||||
req,
|
||||
id,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeDelete` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`id`** | The ID of the Document being deleted. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterDelete
|
||||
|
||||
Runs immediately after the `delete` operation removes records from the database. Returned values are discarded.
|
||||
@@ -196,12 +265,22 @@ Runs immediately after the `delete` operation removes records from the database.
|
||||
import type { CollectionAfterDeleteHook } from 'payload';
|
||||
|
||||
const afterDeleteHook: CollectionAfterDeleteHook = async ({
|
||||
req, // full Request object
|
||||
id, // id of document to delete
|
||||
doc, // deleted document
|
||||
req,
|
||||
id,
|
||||
doc,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterDelete` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`id`** | The ID of the Document that was deleted. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterOperation
|
||||
|
||||
The `afterOperation` hook can be used to modify the result of operations or execute side-effects that run after an operation has completed.
|
||||
@@ -212,123 +291,194 @@ Available Collection operations include `create`, `find`, `findByID`, `update`,
|
||||
import type { CollectionAfterOperationHook } from 'payload'
|
||||
|
||||
const afterOperationHook: CollectionAfterOperationHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
operation, // name of the operation
|
||||
req, // full Request object
|
||||
result, // the result of the operation, before modifications
|
||||
result,
|
||||
}) => {
|
||||
return result // return modified result as necessary
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterOperation` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`args`** | The arguments passed into the operation. |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`operation`** | The name of the operation that this hook is running within. |
|
||||
| **`result`** | The result of the operation, before modifications. |
|
||||
|
||||
### beforeLogin
|
||||
|
||||
For auth-enabled Collections, this hook runs during `login` operations where a user with the provided credentials exist, but before a token is generated and added to the response. You can optionally modify the user that is returned, or throw an error in order to deny the login operation.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs during `login` operations where a user with the provided credentials exist, but before a token is generated and added to the response. You can optionally modify the user that is returned, or throw an error in order to deny the login operation.
|
||||
|
||||
```ts
|
||||
import type { CollectionBeforeLoginHook } from 'payload'
|
||||
|
||||
const beforeLoginHook: CollectionBeforeLoginHook = async ({
|
||||
req, // full Request object
|
||||
user, // user being logged in
|
||||
user,
|
||||
}) => {
|
||||
return user
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeLogin` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`user`** | The user being logged in. |
|
||||
|
||||
### afterLogin
|
||||
|
||||
For auth-enabled Collections, this hook runs after successful `login` operations. You can optionally modify the user that is returned.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs after successful `login` operations. You can optionally modify the user that is returned.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterLoginHook } from 'payload';
|
||||
|
||||
const afterLoginHook: CollectionAfterLoginHook = async ({
|
||||
req, // full Request object
|
||||
user, // user that was logged in
|
||||
token, // user token
|
||||
user,
|
||||
token,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterLogin` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`token`** | The token generated for the user. |
|
||||
| **`user`** | The user being logged in. |
|
||||
|
||||
### afterLogout
|
||||
|
||||
For auth-enabled Collections, this hook runs after `logout` operations.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs after `logout` operations.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterLogoutHook } from 'payload';
|
||||
|
||||
const afterLogoutHook: CollectionAfterLogoutHook = async ({
|
||||
req, // full Request object
|
||||
req,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
### afterRefresh
|
||||
The following arguments are passed to the `afterLogout` hook:
|
||||
|
||||
For auth-enabled Collections, this hook runs after `refresh` operations.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterRefreshHook } from 'payload';
|
||||
|
||||
const afterRefreshHook: CollectionAfterRefreshHook = async ({
|
||||
req, // full Request object
|
||||
res, // full Response object
|
||||
token, // newly refreshed user token
|
||||
}) => {...}
|
||||
```
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterMe
|
||||
|
||||
For auth-enabled Collections, this hook runs after `me` operations.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs after `me` operations.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterMeHook } from 'payload';
|
||||
|
||||
const afterMeHook: CollectionAfterMeHook = async ({
|
||||
req, // full Request object
|
||||
response, // response to return
|
||||
req,
|
||||
response,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterMe` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`response`** | The response to return. |
|
||||
|
||||
### afterRefresh
|
||||
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs after `refresh` operations.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterRefreshHook } from 'payload';
|
||||
|
||||
const afterRefreshHook: CollectionAfterRefreshHook = async ({
|
||||
token,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterRefresh` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`exp`** | The expiration time of the token. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`token`** | The newly refreshed user token. |
|
||||
|
||||
### afterForgotPassword
|
||||
|
||||
For auth-enabled Collections, this hook runs after successful `forgotPassword` operations. Returned values are discarded.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook runs after successful `forgotPassword` operations. Returned values are discarded.
|
||||
|
||||
```ts
|
||||
import type { CollectionAfterForgotPasswordHook } from 'payload'
|
||||
|
||||
const afterForgotPasswordHook: CollectionAfterForgotPasswordHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
args,
|
||||
context,
|
||||
collection, // The collection which this hook is being run on
|
||||
collection,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterForgotPassword` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`args`** | The arguments passed into the operation. |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
|
||||
### refresh
|
||||
|
||||
For auth-enabled Collections, this hook allows you to optionally replace the default behavior of the `refresh` operation with your own. If you optionally return a value from your hook, the operation will not perform its own logic and continue.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook allows you to optionally replace the default behavior of the `refresh` operation with your own. If you optionally return a value from your hook, the operation will not perform its own logic and continue.
|
||||
|
||||
```ts
|
||||
import type { CollectionRefreshHook } from 'payload'
|
||||
|
||||
const myRefreshHook: CollectionRefreshHook = async ({
|
||||
args, // arguments passed into the `refresh` operation
|
||||
user, // the user as queried from the database
|
||||
args,
|
||||
user,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterRefresh` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`args`** | The arguments passed into the operation. |
|
||||
| **`user`** | The user being logged in. |
|
||||
|
||||
### me
|
||||
|
||||
For auth-enabled Collections, this hook allows you to optionally replace the default behavior of the `me` operation with your own. If you optionally return a value from your hook, the operation will not perform its own logic and continue.
|
||||
For [Auth-enabled Collections](../authentication/overview), this hook allows you to optionally replace the default behavior of the `me` operation with your own. If you optionally return a value from your hook, the operation will not perform its own logic and continue.
|
||||
|
||||
```ts
|
||||
import type { CollectionMeHook } from 'payload'
|
||||
|
||||
const meHook: CollectionMeHook = async ({
|
||||
args, // arguments passed into the `me` operation
|
||||
user, // the user as queried from the database
|
||||
args,
|
||||
user,
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `me` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`args`** | The arguments passed into the operation. |
|
||||
| **`user`** | The user being logged in. |
|
||||
|
||||
## TypeScript
|
||||
|
||||
Payload exports a type for each Collection hook which can be accessed as follows:
|
||||
|
||||
@@ -120,11 +120,11 @@ const MyCollection: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
## Typing context
|
||||
## TypeScript
|
||||
|
||||
The default typescript interface for `context` is `{ [key: string]: unknown }`. If you prefer a more strict typing in your project or when authoring plugins for others, you can override this using the `declare` syntax.
|
||||
The default TypeScript interface for `context` is `{ [key: string]: unknown }`. If you prefer a more strict typing in your project or when authoring plugins for others, you can override this using the `declare` syntax.
|
||||
|
||||
This is known as "type augmentation" - a TypeScript feature which allows us to add types to existing objects. Simply put this in any .ts or .d.ts file:
|
||||
This is known as "type augmentation", a TypeScript feature which allows us to add types to existing objects. Simply put this in any `.ts` or `.d.ts` file:
|
||||
|
||||
```ts
|
||||
import { RequestContext as OriginalRequestContext } from 'payload'
|
||||
|
||||
@@ -1,38 +1,49 @@
|
||||
---
|
||||
title: Field Hooks
|
||||
label: Fields
|
||||
order: 30
|
||||
order: 40
|
||||
desc: Hooks can be added to any fields, and optionally modify the return value of the field before the operation continues.
|
||||
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up
|
||||
functionalities to be easily reusable across your projects.
|
||||
Field Hooks are [Hooks](./overview) that run on Documents on a per-field basis. They allow you to execute your own logic during specific events of the Document lifecycle. Field Hooks offer incredible potential for isolating your logic from the rest of your [Collection Hooks](./collections) and [Global Hooks](./globals).
|
||||
|
||||
**Example use cases include:**
|
||||
|
||||
- Automatically add an `owner` relationship to a Document based on the `req.user.id`
|
||||
- Encrypt / decrypt a sensitive field using `beforeValidate` and `afterRead` hooks
|
||||
- Auto-generate field data using a `beforeValidate` hook
|
||||
- Format incoming data such as kebab-casing a document `slug` with `beforeValidate`
|
||||
- Restrict updating a document to only once every X hours using the `beforeChange` hook
|
||||
|
||||
**All field types provide the following hooks:**
|
||||
|
||||
- [beforeValidate](#beforevalidate)
|
||||
- [beforeChange](#beforechange)
|
||||
- beforeDuplicate(#beforeduplicate)
|
||||
- [afterChange](#afterchange)
|
||||
- [afterRead](#afterread)
|
||||
|
||||
## Config
|
||||
|
||||
Example field configuration:
|
||||
To add hooks to a Field, use the `hooks` property in your [Field Config](../fields/overview):
|
||||
|
||||
```ts
|
||||
import type { Field } from 'payload';
|
||||
|
||||
const ExampleField: Field = {
|
||||
export const FieldWithHooks: Field = {
|
||||
// ...
|
||||
hooks: { // highlight-line
|
||||
// ...
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The following Field Hooks are available:
|
||||
|
||||
- [`beforeValidate`](#beforevalidate)
|
||||
- [`beforeChange`](#beforechange)
|
||||
- [`beforeDuplicate`](#beforeduplicate)
|
||||
- [`afterChange`](#afterchange)
|
||||
- [`afterRead`](#afterread)
|
||||
|
||||
## Config Options
|
||||
|
||||
All Field Hooks accept an array of synchronous or asynchronous functions. These functions can optionally modify the return value of the field before the operation continues. All Field Hooks are formatted to accept the same arguments, although some arguments may be `undefined` based the specific hook type.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important:</strong>
|
||||
Due to GraphQL's typed nature, changing the type of data that you return from a field will produce errors in the [GraphQL API](../graphql/overview). If you need to change the shape or type of data, consider [Collection Hooks](./collections) or [Global Hooks](./hooks) instead.
|
||||
</Banner>
|
||||
|
||||
To add hooks to a Field, use the `hooks` property in your [Field Config](../fields/overview):
|
||||
|
||||
```ts
|
||||
import type { Field } from 'payload';
|
||||
|
||||
const FieldWithHooks: Field = {
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
// highlight-start
|
||||
@@ -47,64 +58,37 @@ const ExampleField: Field = {
|
||||
}
|
||||
```
|
||||
|
||||
## Arguments and return values
|
||||
|
||||
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on
|
||||
which field hook you are utilizing.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
It's a good idea to conditionally scope your logic based on which operation is executing. For
|
||||
example, if you are writing a <strong>beforeChange</strong> hook, you may want to perform
|
||||
different logic based on if the current <strong>operation</strong> is <strong>create</strong> or{' '}
|
||||
<strong>update</strong>.
|
||||
</Banner>
|
||||
|
||||
#### Arguments
|
||||
|
||||
Field Hooks receive one `args` argument that contains the following properties:
|
||||
The following arguments are available to all Field Hooks:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The data passed to update the document within `create` and `update` operations, and the full document itself in the `afterRead` hook. |
|
||||
| **`siblingData`** | The sibling data passed to a field that the hook is running against. |
|
||||
| **`collection`** | The [Collection](../configuration/collections) in which this Hook is running against. If the field belongs to a Global, this will be `null`. |
|
||||
| **`context`** | Custom context passed between Hooks. [More details](./context). |
|
||||
| **`data`** | In the `afterRead` hook this is the full Document. In the `create` and `update` operations, this is the incoming data passed through the operation. |
|
||||
| **`field`** | The [Field](../fields/overview) which the Hook is running against. |
|
||||
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many within the `afterRead` hook. |
|
||||
| **`operation`** | A string relating to which operation the field type is currently executing within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
|
||||
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
|
||||
| **`previousDoc`** | The document before changes were applied, only in `afterChange` hooks. |
|
||||
| **`previousSiblingDoc`** | The sibling data of the document before changes being applied, only in `beforeChange` and `afterChange` hook. |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It is mocked for Local API operations. |
|
||||
| **`value`** | The value of the field. |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. If the field belongs to a Collection, this will be `null`. |
|
||||
| **`operation`** | The name of the operation that this hook is running within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
|
||||
| **`originalDoc`** | In the `update` operation, this is the Document before changes were applied. In the `afterChange` hook, this is the resulting Document. |
|
||||
| **`overrideAccess`** | A boolean to denote if the current operation is overriding [Access Control](../access-control/overview). |
|
||||
| **`path`** | The path to the [Field](../fields/overview) in the schema. |
|
||||
| **`previousDoc`** | In the `afterChange` Hook, this is the Document before changes were applied. |
|
||||
| **`previousSiblingDoc`** | The sibling data of the Document before changes being applied, only in `beforeChange` and `afterChange` hook. |
|
||||
| **`previousValue`** | The previous value of the field, before changes, only in `beforeChange` and `afterChange` hooks. |
|
||||
| **`context`** | Context passed to this hook. More info can be found under [Context](/docs/hooks/context) |
|
||||
| **`field`** | The field which the hook is running against. |
|
||||
| **`collection`** | The collection which the field belongs to. If the field belongs to a global, this will be null. |
|
||||
| **`global`** | The global which the field belongs to. If the field belongs to a collection, this will be null. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
| **`schemaPath`** | The path of the [Field](../fields/overview) in the schema. |
|
||||
| **`siblingData`** | The data of sibling fields adjacent to the field that the Hook is running against. |
|
||||
| **`siblingDocWithLocales`** | The sibling data of the Document with all [Locales](../configuration/localization). |
|
||||
| **`value`** | The value of the [Field](../fields/overview). |
|
||||
|
||||
#### Return value
|
||||
|
||||
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may
|
||||
optionally return the value that should be used within the field.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important</strong>
|
||||
<br />
|
||||
Due to GraphQL's typed nature, you should never change the type of data that you return from a
|
||||
field, otherwise GraphQL will produce errors. If you need to change the shape or type of data,
|
||||
reconsider Field Hooks and instead evaluate if Collection / Global hooks might suit you better.
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
It's a good idea to conditionally scope your logic based on which operation is executing. For example, if you are writing a `beforeChange` hook, you may want to perform different logic based on if the current `operation` is `create` or `update`.
|
||||
</Banner>
|
||||
|
||||
## Examples of Field Hooks
|
||||
|
||||
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the
|
||||
flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the
|
||||
true potential of field-level hooks lies in their adaptability to a wide array of use cases.
|
||||
|
||||
### beforeValidate
|
||||
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes
|
||||
validation.
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes validation.
|
||||
|
||||
```ts
|
||||
import type { Field } from 'payload'
|
||||
|
||||
@@ -1,33 +1,44 @@
|
||||
---
|
||||
title: Global Hooks
|
||||
label: Globals
|
||||
order: 40
|
||||
order: 30
|
||||
desc: Hooks can be added to any Global and allow you to validate data, flatten locales, hide protected fields, remove fields and more.
|
||||
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Globals feature the ability to define the following hooks:
|
||||
Global Hooks are [Hooks](./overview) that run on [Global](../configuration/globals) Documents. They allow you to execute your own logic during specific events of the Document lifecycle.
|
||||
|
||||
- [beforeValidate](#beforevalidate)
|
||||
- [beforeChange](#beforechange)
|
||||
- [afterChange](#afterchange)
|
||||
- [beforeRead](#beforeread)
|
||||
- [afterRead](#afterread)
|
||||
|
||||
## Config
|
||||
|
||||
All Global Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs.
|
||||
|
||||
`globals/example-hooks.js`
|
||||
To add hooks to a Global, use the `hooks` property in your [Global Config](../configuration/globals):
|
||||
|
||||
```ts
|
||||
import type { GlobalConfig } from 'payload';
|
||||
|
||||
const ExampleHooks: GlobalConfig = {
|
||||
slug: 'header',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text'},
|
||||
]
|
||||
export const GlobalWithHooks: GlobalConfig = {
|
||||
// ...
|
||||
hooks: { // highlight-line
|
||||
// ...
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The following Global Hooks are available:
|
||||
|
||||
- [`beforeValidate`](#beforevalidate)
|
||||
- [`beforeChange`](#beforechange)
|
||||
- [`afterChange`](#afterchange)
|
||||
- [`beforeRead`](#beforeread)
|
||||
- [`afterRead`](#afterread)
|
||||
|
||||
## Config Options
|
||||
|
||||
All Global Hooks accept an array of [synchronous or asynchronous functions](./overview#async-vs-synchronous). Each Global Hook receives specific arguments based on its own type, and has the ability to modify specific outputs.
|
||||
|
||||
```ts
|
||||
import type { GlobalConfig } from 'payload';
|
||||
|
||||
const GlobalWithHooks: GlobalConfig = {
|
||||
// ...
|
||||
// highlight-start
|
||||
hooks: {
|
||||
beforeValidate: [(args) => {...}],
|
||||
beforeChange: [(args) => {...}],
|
||||
@@ -35,6 +46,7 @@ const ExampleHooks: GlobalConfig = {
|
||||
afterChange: [(args) => {...}],
|
||||
afterRead: [(args) => {...}],
|
||||
}
|
||||
// highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
@@ -54,6 +66,16 @@ const beforeValidateHook: GlobalBeforeValidateHook = async ({
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeValidate` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between Hooks. [More details](./context). |
|
||||
| **`data`** | The incoming data passed through the operation. |
|
||||
| **`originalDoc`** | The Document before changes are applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeChange
|
||||
|
||||
Immediately following validation, `beforeChange` hooks will run within the `update` operation. At this stage, you can be confident that the data that will be saved to the document is valid in accordance to your field validations. You can optionally modify the shape of data to be saved.
|
||||
@@ -70,6 +92,16 @@ const beforeChangeHook: GlobalBeforeChangeHook = async ({
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeChange` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`data`** | The incoming data passed through the operation. |
|
||||
| **`originalDoc`** | The Document before changes are applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterChange
|
||||
|
||||
After a global is updated, the `afterChange` hook runs. Use this hook to purge caches of your applications, sync site data to CRMs, and more.
|
||||
@@ -86,6 +118,16 @@ const afterChangeHook: GlobalAfterChangeHook = async ({
|
||||
}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `afterChange` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`previousDoc`** | The Document before changes were applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### beforeRead
|
||||
|
||||
Runs before `findOne` global operation is transformed for output by `afterRead`. This hook fires before hidden fields are removed and before localized fields are flattened into the requested locale. Using this Hook will provide you with all locales and all hidden fields via the `doc` argument.
|
||||
@@ -99,6 +141,15 @@ const beforeReadHook: GlobalBeforeReadHook = async ({
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeRead` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
### afterRead
|
||||
|
||||
Runs as the last step before a global is returned. Flattens locales, hides protected fields, and removes fields that users do not have access to.
|
||||
@@ -113,6 +164,17 @@ const afterReadHook: GlobalAfterReadHook = async ({
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
The following arguments are passed to the `beforeRead` hook:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`global`** | The [Global](../configuration/globals) in which this Hook is running against. |
|
||||
| **`context`** | Custom context passed between hooks. [More details](./context). |
|
||||
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many (useful in versions). |
|
||||
| **`doc`** | The resulting Document after changes are applied. |
|
||||
| **`query`** | The [Query](../queries/overview) of the request.
|
||||
| **`req`** | The [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. This is mocked for [Local API](../local-api/overview) operations. |
|
||||
|
||||
## TypeScript
|
||||
|
||||
Payload exports a type for each Global hook which can be accessed as follows:
|
||||
|
||||
@@ -6,42 +6,35 @@ desc: Hooks allow you to add your own logic to Payload, including integrating wi
|
||||
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner type="info">
|
||||
Hooks are powerful ways to tie into existing Payload actions in order to add your own logic like
|
||||
integrating with third-party APIs, adding auto-generated data, or modifing Payload's base
|
||||
functionality.
|
||||
</Banner>
|
||||
Hooks allow you to execute your own logic during specific events of the Document lifecycle. With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework. They allow you to perform business tasks, third-party integrations, etc. during precise moments within the data lifecycle.
|
||||
|
||||
**With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework.**
|
||||
There are many use cases for Hooks, including:
|
||||
|
||||
Example uses:
|
||||
|
||||
- Integrate user profiles with a third-party CRM such as Salesforce or Hubspot
|
||||
- Modify data before it is read or updated
|
||||
- Encrypt and decrypt sensitive data
|
||||
- Integrate with a third-party CRM like HubSpot or Salesforce
|
||||
- Send a copy of uploaded files to Amazon S3 or similar
|
||||
- Automatically add `lastModifiedBy` data to a document to track who changed what over time
|
||||
- Encrypt a field's data when it's saved and decrypt it when it's read
|
||||
- Send emails when `ContactSubmission`s are created from a public website
|
||||
- Integrate with a payment provider like Stripe to automatically process payments when an `Order` is created
|
||||
- Securely recalculate order prices on the backend to ensure that the total price for `Order`s that users submit is accurate and valid
|
||||
- Generate and store a `lastLoggedIn` date on a user by adding an `afterLogin` hook
|
||||
- Add extra data to documents before they are read such as "average scores" or similar data that needs to be calculated on the fly
|
||||
- Process orders through a payment provider like Stripe
|
||||
- Send emails when contact forms are submitted
|
||||
- Track data ownership or changes over time
|
||||
|
||||
There are many more use cases for Hooks and the sky is the limit.
|
||||
There are three main types of Hooks in Payload:
|
||||
|
||||
- [Collection Hooks](/docs/hooks/collections)
|
||||
- [Global Hooks](/docs/hooks/globals)
|
||||
- [Field Hooks](/docs/hooks/fields)
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Reminder:</strong>
|
||||
Payload also ships a set of _React_ hooks that you can use in your frontend application. Although they share a common name, these are very different things and should not be confused. [More details](../admin.hooks).
|
||||
</Banner>
|
||||
|
||||
## Async vs. synchronous
|
||||
|
||||
All hooks can be written as either synchronous or asynchronous functions. If the Hook should modify data before a document is updated or created, and it relies on asynchronous actions such as fetching data from a third party, it might make sense to define your Hook as an asynchronous function, so you can be sure that your Hook completes before the operation's lifecycle continues. Async hooks are run in series - so if you have two async hooks defined, the second hook will wait for the first to complete before it starts.
|
||||
All Hooks can be written as either synchronous or asynchronous functions. If the Hook should modify data before a document is updated or created, and it relies on asynchronous actions such as fetching data from a third party, it might make sense to define your Hook as an asynchronous function. This way you can be sure that your Hook completes before the operation's lifecycle continues. Async hooks are run in series - so if you have two async hooks defined, the second hook will wait for the first to complete before it starts.
|
||||
|
||||
If your Hook simply performs a side-effect, such as updating a CRM, it might be okay to define it synchronously, so the Payload operation does not have to wait for your hook to complete.
|
||||
|
||||
## Server-only execution
|
||||
|
||||
Payload Hooks are only triggered on the server and are automatically excluded from the Payload Admin bundle.
|
||||
|
||||
## Hook Types
|
||||
|
||||
You can specify hooks in the following contexts:
|
||||
|
||||
- [Collection Hooks](/docs/hooks/collections)
|
||||
- [Field Hooks](/docs/hooks/fields)
|
||||
- [Global Hooks](/docs/hooks/globals)
|
||||
Hooks are only triggered on the server and are automatically excluded from the client-side bundle. This means that you can safely use sensitive business logic in your Hooks without worrying about exposing it to the client.
|
||||
|
||||
Reference in New Issue
Block a user