---
title: "Global Hooks"
aliases: [global-hooks, hooks-globals, payload-global-hooks]
tags: [payloadcms, hooks, globals, lifecycle]
sources: [raw/hooks__globals.md]
created: 2026-05-15
updated: 2026-05-15
---

Global Hooks run on [[wiki/payloadcms/globals-config|Global]] documents and mirror the structure of [[wiki/payloadcms/hooks-collections|Collection Hooks]], but with a narrower operation set: `read`, `update`, `restoreVersion`, `countVersions`.

## Config

```ts
import type { GlobalConfig } from 'payload'

export const MyGlobal: GlobalConfig = {
  slug: 'site-settings',
  hooks: {
    beforeOperation: [(args) => { return args }],
    beforeValidate: [(args) => { return args.data }],
    beforeChange:   [(args) => { return args.data }],
    beforeRead:     [(args) => {}],
    afterChange:    [(args) => { return args.doc }],
    afterRead:      [(args) => { return args.doc }],
  },
}
```

Each hook key accepts an **array** of sync or async functions.

---

## Hook Reference

### beforeOperation

Runs before any operation starts. Modify `args` to reshape inputs.

| Arg | Type | Notes |
|-----|------|-------|
| `args` | object | Operation arguments — return modified version |
| `operation` | string | `read`, `update`, `restoreVersion`, `countVersions` |
| `req` | Request | Mocked for Local API |
| `context` | object | See [[wiki/payloadcms/hooks-context|Hooks Context]] |

---

### beforeValidate

Runs during `update` **before** server-side validation. Use to normalise/format incoming data.

**Validation order:**
1. Client-side `validate` (field component)
2. `beforeValidate` on the server
3. Server-side `validate`

| Arg | Notes |
|-----|-------|
| `data` | Partial incoming data |
| `originalDoc` | Full document before changes |

> **Gotcha:** `data` on update contains **only changed fields**. Use `originalDoc` to read unchanged values.

---

### beforeChange

Runs after validation, still within `update`. Data is guaranteed valid here. Use to transform the shape before it is saved.

Same `data` / `originalDoc` pattern as `beforeValidate`.

---

### afterChange

Runs after a global is saved. Ideal for cache-busting, CRM syncs, webhooks.

| Arg | Notes |
|-----|-------|
| `doc` | Full resulting document |
| `previousDoc` | Document before the update |
| `data` | The data that was submitted |

---

### beforeRead

Runs before `afterRead`, **before** locale flattening and hidden-field removal. You receive all locales and all hidden fields via `doc`.

---

### afterRead

Final step before the document is returned. Locales are flattened, protected fields removed. Use to derive or reshape returned values.

| Extra arg | Notes |
|-----------|-------|
| `findMany` | `true` when iterating versions |
| `query` | The originating query object |

---

## TypeScript

```ts
import type {
  GlobalBeforeOperationHook,
  GlobalBeforeValidateHook,
  GlobalBeforeChangeHook,
  GlobalBeforeReadHook,
  GlobalAfterChangeHook,
  GlobalAfterReadHook,
} from 'payload'
import type { SiteSettings } from '@/payload-types'

// Generic narrows doc/data/previousDoc types
const afterChange: GlobalAfterChangeHook<SiteSettings> = async ({
  doc,        // SiteSettings
  previousDoc // SiteSettings
}) => {
  return doc
}
```

---

## Key Takeaways

- Global hooks mirror collection hooks but only cover `read` / `update` / `restoreVersion` / `countVersions` operations.
- `beforeValidate` and `beforeChange` receive **partial** `data` on updates — always use `originalDoc` for fields you didn't change.
- `beforeRead` gives raw access to **all locales and hidden fields** before Payload strips them.
- `afterRead` is the right place to add derived/computed properties on the way out.
- `afterChange` is the standard integration point for cache invalidation and third-party syncs.
- Use [[wiki/payloadcms/hooks-context|req.context]] flags to prevent infinite loops when hooks trigger further operations.
- Field-level isolation: prefer [[wiki/payloadcms/hooks-fields|Field Hooks]] when logic is scoped to a single field.

---

## Sources

- `raw/hooks__globals.md` — https://payloadcms.com/docs/hooks/globals
