Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
40c68c1
feat(payload): prepare validation lifecycle types
paulpopus Jul 23, 2026
365bdbb
fix(payload): preserve field access during validation
paulpopus Jul 23, 2026
717baca
fix(payload): add validation access operation
paulpopus Jul 23, 2026
1df014f
feat(payload): add validation Local API
paulpopus Jul 23, 2026
69ab764
fix(payload): harden local validation
paulpopus Jul 23, 2026
0e77427
feat(payload): add REST validation endpoints
paulpopus Jul 23, 2026
5045bcf
test(payload): strengthen REST validation security coverage
paulpopus Jul 23, 2026
9b7a601
feat(payload): add multi-locale publish validation
paulpopus Jul 23, 2026
f5bd7a2
fix(payload): harden multi-locale validation
paulpopus Jul 23, 2026
278a496
fix(payload): seal publish validation intent
paulpopus Jul 23, 2026
a4de29d
fix(payload): validate post-hook publish intent
paulpopus Jul 23, 2026
e72d902
feat(payload): validate scheduled publications
paulpopus Jul 23, 2026
8954079
test(payload): align localized versions publication
paulpopus Jul 23, 2026
ccc6210
fix(payload): cancel scheduled validation errors
paulpopus Jul 23, 2026
8f863e4
feat(ui): add localized document validation feedback
paulpopus Jul 23, 2026
5329ee2
fix(ui): detect localized fields in referenced blocks
paulpopus Jul 23, 2026
0b79df9
docs(payload): document on-demand validation
paulpopus Jul 23, 2026
b0edbbe
fix(payload): honor validation draft option
paulpopus Jul 23, 2026
c558819
fix(payload): harden validation safety
paulpopus Jul 23, 2026
df19d62
fix(payload): resolve global validation sources
paulpopus Jul 23, 2026
62f569b
add tests
paulpopus Jul 29, 2026
9222278
more docs
paulpopus Jul 29, 2026
1e5e228
remove redundant calls from job.ts
paulpopus Jul 29, 2026
0ca6ed2
update
paulpopus Jul 29, 2026
78c43ac
Merge branch 'main' into feat/add-validate-operation
paulpopus Jul 29, 2026
bea18e6
fix build
paulpopus Jul 29, 2026
6b0e723
fix publish button
paulpopus Jul 30, 2026
071a890
fix e2e
paulpopus Jul 30, 2026
de5ac02
updates
paulpopus Aug 7, 2026
0eb0826
Merge branch 'main' into feat/add-validate-operation
paulpopus Aug 7, 2026
928354e
Merge branch 'main' into feat/add-validate-operation
paulpopus Aug 10, 2026
c1d3f7a
add more test coverage
paulpopus Aug 11, 2026
1c97bdb
remove validate all locales button from UI
paulpopus Aug 12, 2026
473081d
Merge branch 'main' into feat/add-validate-operation
paulpopus Aug 12, 2026
90bee45
reduce scope a bit
paulpopus Aug 19, 2026
320e73c
Merge branch 'main' into feat/add-validate-operation
paulpopus Aug 19, 2026
18ce62d
updates
paulpopus Aug 19, 2026
6388cee
add gql mutation
paulpopus Aug 19, 2026
4815952
updates
paulpopus Aug 20, 2026
cbcca9c
fix some test fixtures
paulpopus Aug 20, 2026
ea0032a
remove breaking change
paulpopus Aug 20, 2026
8945178
remove now descoped breaking change
paulpopus Aug 20, 2026
0c0fd89
updates
paulpopus Aug 20, 2026
21cf8ce
updates
paulpopus Aug 20, 2026
b817d18
reuse util for throwing errors from validation
paulpopus Aug 20, 2026
faff19d
initial commit
paulpopus Aug 20, 2026
944a068
fix versions test
paulpopus Aug 21, 2026
c8c30d2
fix versions test
paulpopus Aug 26, 2026
30d48a9
fix
paulpopus Aug 26, 2026
4631aee
chore: merge main into validate locales branch
paulpopus Sep 30, 2026
a347939
chore: reduce validation test duplication
paulpopus Oct 1, 2026
1d66919
chore: merge main into validation branch
paulpopus Oct 2, 2026
179bebc
test: replace mocked validation tests with integration coverage
paulpopus Oct 2, 2026
6bf95f4
chore: address publish all locales review findings
paulpopus Oct 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/access-control/collections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const CollectionWithAccessControl: CollectionConfig = {
read: () => {...},
update: () => {...},
delete: () => {...},
validate: () => {...},

// Auth-enabled Collections only
admin: () => {...},
Expand All @@ -53,12 +54,13 @@ export const CollectionWithAccessControl: CollectionConfig = {

The following options are available:

| Function | Allows/Denies Access |
| ------------ | -------------------------------------------------------------------- |
| **`create`** | Used in the `create` operation. [More details](#create). |
| **`read`** | Used in the `find` and `findByID` operations. [More details](#read). |
| **`update`** | Used in the `update` operation. [More details](#update). |
| **`delete`** | Used in the `delete` operation. [More details](#delete). |
| Function | Allows/Denies Access |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| **`create`** | Used in the `create` operation. [More details](#create). |
| **`read`** | Used in the `find` and `findByID` operations. [More details](#read). |
| **`update`** | Used in the `update` operation. [More details](#update). |
| **`delete`** | Used in the `delete` operation. [More details](#delete). |
| **`validate`** | Optionally overrides `update` access for [on-demand validation](../validation/overview#access-control-and-hooks). |

If a Collection supports [`Authentication`](../authentication/overview), the following additional options are available:

Expand Down
12 changes: 7 additions & 5 deletions docs/access-control/fields.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const Posts: CollectionConfig = {
create: ({ req: { user } }) => { ... },
read: ({ req: { user } }) => { ... },
update: ({ req: { user } }) => { ... },
validate: ({ req: { user } }) => { ... },
},
// highlight-end
};
Expand All @@ -57,11 +58,12 @@ export const Posts: CollectionConfig = {

The following options are available:

| Function | Purpose |
| ------------ | ---------------------------------------------------------------------------------------------------------- |
| **`create`** | Allows or denies the ability to set a field's value when creating a new document. [More details](#create). |
| **`read`** | Allows or denies the ability to read a field's value. [More details](#read). |
| **`update`** | Allows or denies the ability to update a field's value [More details](#update). |
| Function | Purpose |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **`create`** | Allows or denies the ability to set a field's value when creating a new document. [More details](#create). |
| **`read`** | Allows or denies the ability to read a field's value. [More details](#read). |
| **`update`** | Allows or denies the ability to update a field's value. [More details](#update). |
| **`validate`** | Optionally overrides `update` access for candidate field data during [on-demand validation](../validation/overview#access-control-and-hooks). |

### Create

Expand Down
10 changes: 6 additions & 4 deletions docs/access-control/globals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const GlobalWithAccessControl: GlobalConfig = {
access: {
read: ({ req: { user } }) => {...},
update: ({ req: { user } }) => {...},
validate: ({ req: { user } }) => {...},

// Version-enabled Globals only
readVersions: () => {...},
Expand All @@ -49,10 +50,11 @@ export default Header

The following options are available:

| Function | Allows/Denies Access |
| ------------ | --------------------------------------------------------------- |
| **`read`** | Used in the `findOne` Global operation. [More details](#read). |
| **`update`** | Used in the `update` Global operation. [More details](#update). |
| Function | Allows/Denies Access |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| **`read`** | Used in the `findOne` Global operation. [More details](#read). |
| **`update`** | Used in the `update` Global operation. [More details](#update). |
| **`validate`** | Optionally overrides `update` access for [on-demand validation](../validation/overview#access-control-and-hooks). |

If a Global supports [Versions](../versions/overview), the following additional options are available:

Expand Down
4 changes: 4 additions & 0 deletions docs/access-control/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Access Control determines what a user can and cannot do with any given Document,

Access Control functions are scoped to the _operation_, meaning you can have different rules for `create`, `read`, `update`, `delete`, etc. Access Control functions are executed _before_ any changes are made and _before_ any operations are completed. This allows you to determine if the user has the necessary permissions before fulfilling the request.

[On-demand validation](../validation/overview#access-control-and-hooks) uses its own first-class
`validate` operation for collection, global, and field access control. Its access policy falls back
to the corresponding `update` function unless `validate` is configured explicitly.

There are many use cases for Access Control, including:

- Allowing anyone `read` access to all posts
Expand Down
4 changes: 3 additions & 1 deletion docs/configuration/localization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Localization is one of the most important features of a modern CMS. It allows yo

With Localization, you can begin to serve personalized content to your users based on their specific language preferences, such as a multilingual website or multi-site application. There are no limits to the number of locales you can add to your Payload project.

You can also [validate one or more locales without saving](../validation/overview).

To configure Localization, use the `localization` key in your [Payload Config](./overview):

```ts
Expand Down Expand Up @@ -95,7 +97,7 @@ The locale codes do not need to be in any specific format. It's up to you to def

| Option | Description |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale` |
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale`. |
| **`label`** | A string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use. |
| **`rtl`** | A boolean that when true will make the admin UI display in Right-To-Left. |
| **`fallbackLocale`** | The code for this language to fallback to when properties of a document are not present. This can be a single locale or array of locales. |
Expand Down
1 change: 1 addition & 0 deletions docs/local-api/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Here are some common examples of how you can use the Local API:
- Seeding data via Node seed scripts that you write and maintain
- Opening custom Next.js route handlers which feature additional functionality but still rely on Payload
- Within [Access Control](../access-control/overview) and [Hooks](../hooks/overview)
- [Validating document candidates without saving them](../validation/overview#local-api)

## Accessing Payload

Expand Down
4 changes: 2 additions & 2 deletions docs/plugins/multi-tenant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*
* The function receives:
* - accessResult: the original result from the access control function
* - accessKey: 'read', 'create', 'update', 'delete', 'readVersions', or 'unlock'
* - accessKey: 'read', 'create', 'update', 'delete', 'readVersions', 'unlock', or 'validate'
* - ...restOfAccessArgs: the original arguments passed to the access control function
*/
accessResultOverride?: CollectionAccessResultOverride
Expand Down Expand Up @@ -261,7 +261,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*
* The function receives:
* - accessResult: the original result from the access control function
* - accessKey: 'read', 'create', 'update', 'delete', 'readVersions', or 'unlock'
* - accessKey: 'read', 'create', 'update', 'delete', 'readVersions', 'unlock', or 'validate'
* - ...restOfAccessArgs: the original arguments passed to the access control function
*/
usersAccessResultOverride?: CollectionAccessResultOverride
Expand Down
3 changes: 3 additions & 0 deletions docs/rest-api/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ keywords: rest, api, documentation, Content Management System, cms, headless, ja
The REST API is a fully functional HTTP client that allows you to interact with your Documents in a RESTful manner. It supports all CRUD operations and is equipped with automatic pagination, depth, and sorting.
All Payload API routes are mounted and prefixed to your config's `routes.api` URL segment (default: `/api`).

To check collection or global candidates without saving them, use the
[on-demand validation endpoints](../validation/overview#rest-api).

For example, if you have a Collection called `pages`, you can fetch its documents directly from the browser or any HTTP client:

```ts
Expand Down
Loading
Loading