---
title: Hooks Overview
label: Overview
order: 10
desc: Hooks allow you to add your own logic to Payload, including integrating with third-party APIs, adding auto-generated data, or modifying Payload's base functionality.
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---

Hooks allow you to execute your own side effects during specific events of the Document lifecycle. They allow you to do things like mutate data, perform business logic, integrate with third-parties, or anything else, all during precise moments within your application.

With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework. There are many use cases for Hooks, including:

- 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
- Process orders through a payment provider like Stripe
- Send emails when contact forms are submitted
- Track data ownership or changes over time

There are four main types of Hooks in Payload:

- [Root Hooks](#root-hooks)
- [Collection Hooks](/docs/hooks/collections)
- [Global Hooks](/docs/hooks/globals)
- [Field Hooks](/docs/hooks/fields)

<Banner type="warning">
  **Reminder:** 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/react-hooks).
</Banner>

## Root Hooks

Root Hooks are not associated with any specific Collection, Global, or Field. They are useful for globally-oriented side effects, such as when an error occurs at the application level.

To add Root Hooks, use the `hooks` property in your [Payload Config](/docs/configuration/overview):

```ts
import { buildConfig } from 'payload'

export default buildConfig({
  // ...
  // highlight-start
  hooks: {
    afterError:[() => {...}]
  },
  // highlight-end
})
```

The following options are available:

| Option           | Description                                            |
| ---------------- | ------------------------------------------------------ |
| **`afterError`** | Runs after an error occurs in the Payload application. |

### afterError

The `afterError` Hook is triggered when an error occurs in the Payload application. This can be useful for logging errors to a third-party service, sending an email to the development team, logging the error to Sentry or DataDog, etc. The output can be used to transform the result object / status code.

```ts
import { buildConfig } from 'payload'

export default buildConfig({
  // ...
  hooks: {
    afterError: [
      async ({ error }) => {
        // Do something
      },
    ],
  },
})
```

The following arguments are provided to the `afterError` Hook:

| Argument            | Description                                                                                                                                                                                     |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`error`**         | The error that occurred.                                                                                                                                                                        |
| **`context`**       | Custom context passed between Hooks. [More details](./context).                                                                                                                                 |
| **`graphqlResult`** | The GraphQL result object, available if the hook is executed within a GraphQL context.                                                                                                          |
| **`req`**           | The `PayloadRequest` object that extends [Web Request](https://developer.mozilla.org/en-US/docs/Web/API/Request). Contains currently authenticated `user` and the Local API instance `payload`. |
| **`collection`**    | The [Collection](../configuration/collections) in which this Hook is running against. This will be `undefined` if the hook is executed from a non-collection endpoint or GraphQL.               |
| **`result`**        | The formatted error result object, available if the hook is executed from a REST context.                                                                                                       |

## Async vs. Synchronous

All Hooks can be written as either synchronous or asynchronous functions. Choosing the right type depends on your use case, but switching between the two is as simple as adding or removing the `async` keyword.

#### Asynchronous

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.

#### Synchronous

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

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.
