vault backup: 2026-05-15 15:49:53
This commit is contained in:
parent
dfa0a4ce7d
commit
885dc09d7f
2 changed files with 161 additions and 0 deletions
|
|
@ -88,6 +88,7 @@
|
|||
| [[wiki/payloadcms/fields-ui\|UI Field]] | Presentational-only field — inject arbitrary React components into Admin Panel Edit/List views; no data stored; use for action buttons, context text, custom controls | raw/fields__ui.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/fields-upload\|Upload Field]] | Reference upload-enabled Collection docs as thumbnail — hasMany, polymorphic multi-collection, filterOptions, bi-directional via Join | raw/fields__upload.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/graphql-overview\|GraphQL API — Overview]] | Auto-generated GraphQL endpoint: queries/mutations for Collections, Globals, Preferences; playground, complexity limits, custom validation rules | raw/graphql__overview.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/hooks-collections\|Collection Hooks]] | All 18 collection hook types (write/read/delete/auth lifecycle), `data` vs `originalDoc` gotcha, auth hooks, TypeScript generics | raw/hooks__collections.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/concepts-overview\|Core Concepts]] | Config, Collections, Globals, Fields, Hooks, Auth, Access Control, Admin Panel; Local/REST/GraphQL APIs; package structure | raw/getting-started__concepts.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/installation\|Installation]] | Requirements (Node 24+, Next.js 16.2.6+), create-payload-app quickstart, manual install steps, withPayload ESM config, tsconfig path alias | raw/getting-started__installation.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/graphql-extending\|GraphQL — Custom Queries and Mutations]] | Add custom GraphQL ops via `graphQL.queries`/`graphQL.mutations` in buildConfig; resolver signature, `depth: 0` gotcha, `buildPaginatedListType`, collection graphQL types | raw/graphql__extending.md | 2026-05-15 |
|
||||
|
|
|
|||
160
wiki/payloadcms/hooks-collections.md
Normal file
160
wiki/payloadcms/hooks-collections.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
title: "Collection Hooks"
|
||||
aliases: [collection-hooks, payload-collection-hooks]
|
||||
tags: [payloadcms, hooks, collections, lifecycle, auth]
|
||||
sources: [raw/hooks__collections.md]
|
||||
created: 2026-05-15
|
||||
updated: 2026-05-15
|
||||
---
|
||||
|
||||
Collection Hooks run on Documents within a specific [[wiki/payloadcms/collection-config|Collection]], letting you execute custom logic at precise moments in the Document lifecycle.
|
||||
|
||||
```ts
|
||||
export const MyCollection: CollectionConfig = {
|
||||
hooks: {
|
||||
beforeOperation: [fn],
|
||||
beforeValidate: [fn],
|
||||
beforeChange: [fn],
|
||||
afterChange: [fn],
|
||||
beforeRead: [fn],
|
||||
afterRead: [fn],
|
||||
beforeDelete: [fn],
|
||||
afterDelete: [fn],
|
||||
afterOperation: [fn],
|
||||
afterError: [fn],
|
||||
// Auth-only:
|
||||
beforeLogin: [fn], afterLogin: [fn], afterLogout: [fn],
|
||||
afterRefresh: [fn], afterMe: [fn], afterForgotPassword: [fn],
|
||||
refresh: [fn], me: [fn],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Each hook accepts an **array** of synchronous or asynchronous functions.
|
||||
|
||||
---
|
||||
|
||||
## Hook Reference
|
||||
|
||||
### Write Lifecycle (create / update)
|
||||
|
||||
| Hook | When | Typical use |
|
||||
|------|------|-------------|
|
||||
| `beforeOperation` | Before any operation starts | Modify operation args, early side-effects |
|
||||
| `beforeValidate` | Before server validation | Format / enrich incoming data |
|
||||
| `beforeChange` | After validation, before DB write | Data transformation, enforce business rules |
|
||||
| `afterChange` | After DB write | Sync to CRM, recalculate aggregates |
|
||||
|
||||
**Order:** `beforeOperation` → `beforeValidate` → client `validate` → server `validate` → `beforeChange` → DB write → `afterChange` → `afterOperation`
|
||||
|
||||
### Read Lifecycle
|
||||
|
||||
| Hook | When | Notes |
|
||||
|------|------|-------|
|
||||
| `beforeRead` | Before locale-flattening / hidden-field removal | Has access to **all locales** and hidden fields |
|
||||
| `afterRead` | Last step before response | Locales flattened, protected fields removed |
|
||||
|
||||
### Delete Lifecycle
|
||||
|
||||
| Hook | Return value |
|
||||
|------|-------------|
|
||||
| `beforeDelete` | Discarded |
|
||||
| `afterDelete` | Discarded |
|
||||
|
||||
### Error Hook
|
||||
|
||||
`afterError` — fires on any Payload application error. Use for Sentry/DataDog/email alerts. Can transform the result object and HTTP status code.
|
||||
|
||||
---
|
||||
|
||||
## Key Arguments
|
||||
|
||||
### `data` vs `originalDoc`
|
||||
|
||||
> **`data` is a delta** — it only contains fields being changed, NOT the full document.
|
||||
|
||||
```ts
|
||||
// On UPDATE — get id from originalDoc, not data
|
||||
const id = operation === 'update' ? originalDoc.id : undefined
|
||||
|
||||
// On CREATE — id is not available until afterChange
|
||||
```
|
||||
|
||||
| Hook | `data` | `originalDoc` | `doc` |
|
||||
|------|--------|--------------|-------|
|
||||
| `beforeValidate` | changed fields | full pre-change doc (update only) | — |
|
||||
| `beforeChange` | changed fields | full pre-change doc (update only) | — |
|
||||
| `afterChange` | changed fields | — | full resulting doc |
|
||||
| `afterRead` | — | — | full resulting doc |
|
||||
|
||||
### Common Arguments (all hooks)
|
||||
|
||||
- **`collection`** — Collection config object
|
||||
- **`context`** — custom pass-through between hooks (see [[wiki/payloadcms/hooks|Hooks overview]])
|
||||
- **`req`** — Web Request (mocked for [[wiki/payloadcms/local-api|Local API]])
|
||||
- **`operation`** — `'create' | 'update' | 'delete' | 'find' | ...`
|
||||
|
||||
---
|
||||
|
||||
## Auth-Enabled Hooks
|
||||
|
||||
For collections with `auth: true`. See [[wiki/payloadcms/authentication-overview|Authentication Overview]].
|
||||
|
||||
| Hook | Fires | Can modify |
|
||||
|------|-------|-----------|
|
||||
| `beforeLogin` | After credentials matched, before token | Return modified user or throw to deny login |
|
||||
| `afterLogin` | After successful login | Return modified user |
|
||||
| `afterLogout` | After logout | Side-effects only |
|
||||
| `afterRefresh` | After token refresh | Side-effects only |
|
||||
| `afterMe` | After `/me` request | Return modified response |
|
||||
| `afterForgotPassword` | After forgot-password | Return value discarded |
|
||||
| `refresh` | Replaces default refresh logic | Return value skips default operation |
|
||||
| `me` | Replaces default me logic | Return value skips default operation |
|
||||
|
||||
---
|
||||
|
||||
## TypeScript
|
||||
|
||||
```ts
|
||||
import type {
|
||||
CollectionBeforeOperationHook,
|
||||
CollectionBeforeValidateHook,
|
||||
CollectionBeforeChangeHook,
|
||||
CollectionAfterChangeHook,
|
||||
CollectionAfterReadHook,
|
||||
CollectionBeforeReadHook,
|
||||
CollectionBeforeDeleteHook,
|
||||
CollectionAfterDeleteHook,
|
||||
CollectionBeforeLoginHook,
|
||||
CollectionAfterLoginHook,
|
||||
CollectionAfterLogoutHook,
|
||||
CollectionAfterRefreshHook,
|
||||
CollectionAfterMeHook,
|
||||
CollectionAfterForgotPasswordHook,
|
||||
CollectionRefreshHook,
|
||||
CollectionMeHook,
|
||||
} from 'payload'
|
||||
|
||||
// Generic typing for doc/data
|
||||
const afterChangeHook: CollectionAfterChangeHook<Post> = async ({ doc, previousDoc }) => {
|
||||
return doc
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
- **`data` is always a partial delta** — never assume `id` or unchanged fields are present; use `originalDoc` on updates, `afterChange` for the `id` on creates
|
||||
- **`beforeChange` data is unvalidated** — treat it as raw user input; required fields may be missing
|
||||
- **`beforeRead`** sees all locales and hidden fields before Payload strips them — use it for internal transforms
|
||||
- **`afterRead`** sees the cleaned, user-visible document — use it for computed props exposed to clients
|
||||
- Auth hooks (`beforeLogin`, `refresh`, `me`) can **replace default behavior** by returning early — powerful but be careful
|
||||
- `afterError` hook is the right place for Sentry / alerting integration, not `try/catch` in every hook
|
||||
- Field-level hooks are an alternative for isolating logic — see [[wiki/payloadcms/hooks|Hooks Overview]]
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
- `raw/hooks__collections.md` (source: https://payloadcms.com/docs/hooks/collections)
|
||||
Loading…
Add table
Reference in a new issue