obsidian/raw/_processed/hooks__globals.md
2026-05-15 15:52:51 +01:00

13 KiB

title label order desc keywords source
Global Hooks Globals 30 Hooks can be added to any Global and allow you to validate data, flatten locales, hide protected fields, remove fields and more. hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs https://payloadcms.com/docs/hooks/globals

Global Hooks are Hooks that run on Global Documents. They allow you to execute your own logic during specific events of the Document lifecycle.

To add Hooks to a Global, use the hooks property in your Global Config:

import type { GlobalConfig } from 'payload'

export const GlobalWithHooks: GlobalConfig = {
  // ...
  hooks: {
    // highlight-line
    // ...
  },
}
**Tip:** You can also set hooks on the field-level to isolate hook logic to specific fields. [More details](./fields).

Config Options

All Global Hooks accept an array of synchronous or asynchronous functions. Each Global Hook receives specific arguments based on its own type, and has the ability to modify specific outputs.

import type { GlobalConfig } from 'payload';

const GlobalWithHooks: GlobalConfig = {
  // ...
  // highlight-start
  hooks: {
    beforeOperation: [(args) => {...}],
    beforeValidate: [(args) => {...}],
    beforeChange: [(args) => {...}],
    beforeRead: [(args) => {...}],
    afterChange: [(args) => {...}],
    afterRead: [(args) => {...}],
  }
  // highlight-end
}

beforeOperation

The beforeOperation hook can be used to modify the arguments that operations accept or execute side-effects that run before an operation begins.

import type { GlobalBeforeOperationHook } from 'payload'

const beforeOperationHook: GlobalBeforeOperationHook = async ({
  args,
  operation,
  req,
}) => {
  return args // return modified operation arguments as necessary
}

The following arguments are provided to the beforeOperation hook:

Option Description
global The Global in which this Hook is running against. Available operation include: countVersions, read, restoreVersion, and update.
context Custom context passed between Hooks. More details.
operation The name of the operation that this hook is running within.
req The Web Request object. This is mocked for Local API operations.

beforeValidate

Runs during the update operation. This hook allows you to add or format data before the incoming data is validated server-side.

Please do note that this does not run before client-side validation. If you render a custom field component in your front-end and provide it with a validate function, the order that validations will run in is:

  1. validate runs on the client
  2. if successful, beforeValidate runs on the server
  3. validate runs on the server
import type { GlobalBeforeValidateHook } from 'payload'
import type { SiteSettings } from '@/payload-types'

const beforeValidateHook: GlobalBeforeValidateHook<SiteSettings> = async ({
  data, // Typed as Partial<SiteSettings>
  req,
  originalDoc, // Typed as SiteSettings
}) => {
  return data
}

The following arguments are provided to the beforeValidate hook:

Option Description
global The Global in which this Hook is running against.
context Custom context passed between Hooks. More details.
data The incoming data passed through the operation.
originalDoc The full document before changes are applied. Present on updates; undefined on creates. Use this to read the document id and any unchanged fields.
req The Web Request object. This is mocked for Local API operations.
On update operations, data contains only the fields being changed. It may omit id and any unchanged fields. Use originalDoc to read existing values. On create, data is the new submission and the document id is not yet available at this stage.

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.

import type { GlobalBeforeChangeHook } from 'payload'
import type { SiteSettings } from '@/payload-types'

const beforeChangeHook: GlobalBeforeChangeHook<SiteSettings> = async ({
  data, // Typed as Partial<SiteSettings>
  req,
  originalDoc, // Typed as SiteSettings
}) => {
  return data
}

The following arguments are provided to the beforeChange hook:

Option Description
global The Global in which this Hook is running against.
context Custom context passed between hooks. More details.
data The incoming data passed through the operation.
originalDoc The full document before changes are applied. Present on updates; undefined on creates. Use this to read the document id and any unchanged fields.
req The Web Request object. This is mocked for Local API operations.
On update operations, data contains only the fields being changed. It may omit id and any unchanged fields. Use originalDoc to read existing values. On create, data is the new submission and the document id is not yet available at this stage.

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.

import type { GlobalAfterChangeHook } from 'payload'
import type { SiteSettings } from '@/payload-types'

const afterChangeHook: GlobalAfterChangeHook<SiteSettings> = async ({
  doc, // Typed as SiteSettings
  previousDoc, // Typed as SiteSettings
  req,
}) => {
  return doc
}

The following arguments are provided to the afterChange hook:

Option Description
global The Global in which this Hook is running against.
context Custom context passed between hooks. More details.
data The incoming data passed through the operation.
doc The resulting Document after changes are applied.
previousDoc The Document before changes were applied.
req The Web Request object. This is mocked for Local API 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.

import type { GlobalBeforeReadHook } from 'payload'

const beforeReadHook: GlobalBeforeReadHook = async ({
  doc,
  req,
}) => {...}

The following arguments are provided to the beforeRead hook:

Option Description
global The Global in which this Hook is running against.
context Custom context passed between hooks. More details.
doc The resulting Document after changes are applied.
req The Web Request object. This is mocked for Local API 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.

import type { GlobalAfterReadHook } from 'payload'
import type { SiteSettings } from '@/payload-types'

const afterReadHook: GlobalAfterReadHook<SiteSettings> = async ({
  doc, // Typed as SiteSettings
  req,
  findMany,
}) => {
  return doc
}

The following arguments are provided to the afterRead hook:

Option Description
global The Global in which this Hook is running against.
context Custom context passed between hooks. More details.
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 of the request.
req The Web Request object. This is mocked for Local API operations.

TypeScript

Payload exports a type for each Global hook which can be accessed as follows:

import type {
  GlobalBeforeValidateHook,
  GlobalBeforeChangeHook,
  GlobalAfterChangeHook,
  GlobalBeforeReadHook,
  GlobalAfterReadHook,
} from 'payload'

You can also pass a generic type to each hook for strongly-typed doc, previousDoc, and data properties:

import type { GlobalAfterChangeHook } from 'payload'
import type { SiteSettings } from '@/payload-types'

const afterChangeHook: GlobalAfterChangeHook<SiteSettings> = async ({
  doc, // Typed as SiteSettings
  previousDoc, // Typed as SiteSettings
}) => {
  return doc
}