npm payload 3.74.0
v3.74.0

latest releases: 3.75.0-canary.1, 3.75.0-canary.0, 3.75.0-internal.880861f...
13 hours ago

v3.74.0 (2026-01-30)

๐Ÿš€ Features

  • thread override access in doc level hooks (#15421) (85d5263)
  • extend strictDraftTypes to all draft operations (#15292) (9239164)
  • add support for custom UnpublishButton component (#15400) (94254da)
  • storage-r2: client uploads using R2 multipart api (#14733) (5c38902)
  • ui: allows opting out of popup closing logic (#15407) (fb2b602)
  • ui: allows customizing Popup component portal className (#15406) (0f55464)

Override Access in Document-Level Hooks - Access the overrideAccess value inside collection and global hooks. Useful when hook logic needs to know whether access control was bypassed, such as when querying related documents up a hierarchy. #15421

export const Posts: CollectionConfig = {
  slug: 'posts',
  hooks: {
    beforeChange: [
      ({ overrideAccess, req }) => {
        if (overrideAccess) {
          // Access control was bypassed
        }
      },
    ],
  },
}

Extended strictDraftTypes to All Operations - When strictDraftTypes: true is enabled, TypeScript now enforces draft type safety across all Local API operations (not just queries). The draft option is forbidden for collections/globals without drafts enabled, preventing silent runtime behavior where draft flags are ignored. #15292

import { buildConfig } from 'payload'

export default buildConfig({
  typescript: {
    strictDraftTypes: true, // Enables compile-time draft enforcement
  },
  // ...
})

โš ๏ธ Note: Generic collection slugs may require explicit type assertions when using draft options.


Custom UnpublishButton Component - Customize the UnpublishButton in collection and global configs, following the same pattern as PublishButton and SaveButton. Previously hardcoded. #15400

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    components: {
      edit: {
        UnpublishButton: '/components/CustomUnpublishButton',
      },
    },
  },
}

R2 Multipart Client Uploads (storage-r2) - Upload large files directly from the client using R2's multipart API. Files are split into smaller parts and uploaded separately, avoiding Cloudflare Worker memory limits. #14733


Popup Prevent Close Attribute (ui) - Add interactive elements inside popups without triggering close behavior by adding the data-popup-prevent-close attribute. #15407

<Popup>
  <button data-popup-prevent-close onClick={handleClick}>
    Click me without closing
  </button>
</Popup>

Popup Portal className (ui) - Customize the Popup component's portal container with the new portalClassName prop. #15406

<Popup portalClassName="my-custom-portal-class">
  {/* content */}
</Popup>

๐Ÿ› Bug Fixes

  • isolate payload-preferences by auth collection (#15425) (2dc2e7c)
  • traverseFields returning wrong parentPath dot notation for non-localised tabs (#15394) (99b051e)
  • widgets and other features failing with transitive dependency imports (#15392) (5561799)
  • replace deprecated scmp with crypto.timingSafeEqual (#15322) (2511c02)
  • find afterRead hooks should behave like findByID (#15357) (3e27155)
  • remove depth from count operation types (#15356) (dfc1600)
  • publish button incorrectly shown after saving draft when access denied (#15319) (e833fe6)
  • next: version view throws useLocale() server error (#15380) (2ce26fa)
  • next: ensure query preset from url is applied (#15323) (592f404)
  • next: ensure save preset button is not shown when there are no changes (#15320) (e9af097)
  • plugin-cloud-storage: prevent infinite loop when cropping media (#15393) (345a9c7)
  • plugin-cloud-storage: adds beforeChange hook to generate url on create (#15401) (d269d39)
  • richtext-slate: localized indicator not displaying in label (#15412) (126f713)
  • ui: use the formatAdminUrl function to generate unpublish url (#15375) (453e8a6)
  • ui: restore default columns after clearing query preset (#15360) (029699d)
  • ui: prevent globals crash with arrays fields when lock state user is undefined in handleDocumentLocking (#15259) (ea76ca0)
  • ui: getEntityConfig did not respect globalSlug if collectionSlug is undefined (#15362) (b54059c)

๐Ÿ“š Documentation

  • clarify beforeValidate and beforeChange hook data behavior (#15300) (ba9605e)
  • add payload.logger.error usage guidelines to CLAUDE.md (#15398) (cdbfda2)
  • updated redirects plugin integration docs and postgres connection troubleshooting (#15383) (9b2221e)
  • improve select jsdocs and empty select docs (#15336) (4181a12)

๐Ÿงช Tests

  • make integration tests for the fields and select suites faster (#15434) (26ba779)

๐Ÿ“ Templates

๐Ÿ”จ Build

โš™๏ธ CI

  • enable retries for int and unit tests (#15397) (8b21263)
  • cache e2e prod preparation to run once instead of per-shard, various improvements and flake fixes (#15368) (2b3b9d5)
  • automatically shard int tests (#15367) (1041b15)
  • disable playwright tracing for first test runs, to improve performance and reduce flakes (#15337) (ab603c3)
  • automatically shard e2e tests (#15366) (2f19f8f)
  • add missing value property to outputs (#15338) (479b057)
  • bump monorepo Node.js version from 23.11.0 to 24.13.0 (#15364) (d95c365)
  • add linked PR feature to popular-issues action (#15355) (614f13c)

๐Ÿก Chores

๐Ÿค Contributors

Don't miss a new payload release

NewReleases is sending notifications on new releases.