Releases: payloadcms/payload
v3.68.5
v3.68.4
v3.68.4 (2025-12-14)
🐛 Bug Fixes
- previousValue from hooks should be populated within lexical blocks (#14856) (bb1501e)
- deps: enforce Next.js 15.4.10 (#14908) (7c675fa)
- next: properly construct local req url (#14907) (471cd1b)
- ui: show localized locale name for publish specific locale button (#14906) (848ea65)
- ui: relationship add button unsafe permissions property access (#14903) (127e41a)
📚 Documentation
- remove unused variable from custom field label translation (#14911) (77f96a4)
- update collection access control reference link on collection config page (#14905) (3a1eb77)
⚠️ BREAKING CHANGES
-
deps: enforce Next.js 15.4.10 (#14908) (7c675fa)
Address
CVE-2025-67779.
🤝 Contributors
- Jake (@jacobsfletch)
- Riley Langbein (@rilrom)
- Jeffery To (@jefferyto)
- Aaron Claes (@AaronClaes)
- kat (@puzzlesremixed)
- Jessica Rynkar (@jessrynkar)
v3.68.3
v3.68.3 (2025-12-11)
⚠️ Security Issue
A high-severity Denial of Service (CVE-2025-55184) and a medium-severity Source Code Exposure (CVE-2025-55183) affect React 19 and frameworks that use it, like Next.js.
Full details here: https://vercel.com/kb/bulletin/security-bulletin-cve-2025-55184-and-cve-2025-55183#how-to-upgrade-and-protect-your-next.js-app
While this is not a Payload vulnerability, it may affect any Payload project running on the affected versions of Next.js. Payload does not install any of these dependencies directly, it simply enforces their versions through its peer dependencies, which will only warn you of the version incompatibilities.
You will need to upgrade React and Next.js yourself in your own apps to the patched versions listed below in order to receive these updates.
Resolution
You are strongly encouraged to upgrade your own apps to the nearest patched versions of Next.js and deploy immediately.
Quick steps:
If using pnpm as your package manager, here's a one-liner:
pnpm add next@15.4.9 For a full breakdown of the vulnerable packages and their patched releases, see https://vercel.com/kb/bulletin/security-bulletin-cve-2025-55184-and-cve-2025-55183#how-to-upgrade-and-protect-your-next.js-app.
🐛 Bug Fixes
🤝 Contributors
- Jake (@jacobsfletch)
- Jarrod Flesch (@JarrodMFlesch)
v3.68.2
v3.68.2 (2025-12-10)
🐛 Bug Fixes
Fixes Windows users getting ENOENT errors on
devstartup.
- next: unhandled error in renderListView server function when no user present (#14878) (10a8f0f)
- next: merge user serverExternalPackages in withPayload (#14881) (dcecc46)
🛠 Refactors
- replace generic Error('Unauthorized') with UnauthorizedError (#14879) (c9a8aa0)
- next: remove unnecessary react hooks from DefaultTemplate rsc (#14876) (7a94cc1)
🏡 Chores
🤝 Contributors
- Rot4tion (@Rot4tion)
- Alessio Gravili (@AlessioGr)
- Maxim Seshuk (@maximseshuk)
v3.68.1
v3.68.0
v3.68.0 (2025-12-09)
🚀 Features
Turbopack Build Support (next) - Automatically enables Turbopack Build compatibility when using Next.js ≥ 16.1.0-canary.3. The withPayload wrapper now detects supported versions and enables transitive dependency externalization, unlocking significantly faster production builds with Turbopack. #14845
🐛 Bug Fixes
- adds read and readDistinct to hook mapping (#14853) (0da0da8)
- undefined drafts error in collections with join fields (#14855) (3a29cec)
- use hasDraftsEnabled utility instead of direct check (#14843) (9c9c7c5)
- file objects being serialized to plain objects in upload form state (#14818) (d86c174)
- db-mongodb: correctly pass through collation config in the adapter to be applied in queries via locales (#11242) (db59cb4)
- plugin-multi-tenant: simplified getTenantOptions function and added access control for regular users (#14620) (f7cc078)
- storage-*: upload filename respects prefix (#14566) (ccfaee0)
- ui: component AddNewRelation saves relationTo as first collection instead of selected collection (#14836) (8c5c1fb)
- ui: list drawer per-page dropdown resets to 10 instead of showing saved limit (#14830) (db13a60)
📚 Documentation
🧪 Tests
🔨 Build
- add build:all:force to clean all then build all (d90bccb)
- bump swc-related dependencies (#14834) (617311a)
⚙️ CI
- remove prepack and prepublishonly scripts (#14832) (20914cc)
- add internal-debug release mode (#14820) (ce934b4)
🏡 Chores
🤝 Contributors
- Elliot DeNolf (@denolfe)
- Alessio Gravili (@AlessioGr)
- Riley Langbein (@rilrom)
- Jarrod Flesch (@JarrodMFlesch)
- Adrian Maj (@AdrianMaj)
- Patrik (@PatrikKozak)
- Paul (@paulpopus)
- Jeffery To (@jefferyto)
- Rot4tion (@Rot4tion)
v3.67.0
v3.67.0 (2025-12-05)
🚀 Features
- add groupBy support to query presets (#14808) (2b7aa7a)
- plugin-ecommerce: add ability to enable guest carts with reworked access config (#14565) (90c92f4)
GroupBy Support for Query Presets - Query presets now save and restore groupBy state when switching between presets. Previously, groupBy settings would persist across preset switches and weren't saved as part of the preset configuration. #14808
Guest Carts (plugin-ecommerce) - Enable guest users to create and manage carts without authentication. Carts created by guests are secured with a generated secret stored in local storage. Configure with allowGuestCarts (enabled by default). Also adds isLoading status to all hooks for conditional UI state.
#14565
// Before ecommercePlugin({ access: { adminOnly, adminOnlyFieldAccess, adminOrCustomerOwner, adminOrPublishedStatus, customerOnlyFieldAccess, } }) // After ecommercePlugin({ access: { adminOnlyFieldAccess, adminOrPublishedStatus, customerOnlyFieldAccess, isAdmin, isDocumentOwner, } })🐛 Bug Fixes
- add missing beforeInput and afterInput properties to UploadAdmin type (#14775) (22a0255)
- add missing afterOperation and beforeOperation hook calls (#14778) (e9cd2a5)
- sanitized versions type was incorrect (#14810) (51c951f)
- plugin-multi-tenant: moves getGlobalViewRedirect from utilities to rsc exports (#14817) (1340818)
- ui: autosave not queued while background process is in flight (#14805) (14f042f)
- ui: ensure block error css only gets applied to the affected block (#14826) (7520140)
- ui: missing translation support in SelectMany component (#14819) (8fa91a5)
⚡ Performance
⚙️ CI
- clean up bug report template for auto-labeling (ebee8e1)
🏡 Chores
- claude: add coding patterns and best practices section (#14829) (c5d8e68)
- deps: bump @types/react and @types/react-dom to 19.2.1 (#14815) (d56796b)
- deps: bump next to 15.4.8 in root and test dirs (#14811) (1c3417d)
This PR introduce a breaking change into the plugin as it was necessary
in order to provide more secure guest carts.
🤝 Contributors
- Paul (@paulpopus)
- Jake (@jacobsfletch)
- Jessica Rynkar (@jessrynkar)
- Elliot DeNolf (@denolfe)
- Patrik (@PatrikKozak)
- Jarrod Flesch (@JarrodMFlesch)
- Jens Becker (@jhb-dev)
v3.66.0
v3.66.0 (2025-12-03)
⚠️ Security Issue
A critical-severity vulnerability in React Server Components (CVE-2025-55182) affects React 19 and frameworks that use it, including Next.js (CVE-2025-66478).
You are strongly encouraged to immediately upgrade your own apps to the nearest patched versions of React and Next.js.
While this is not a Payload vulnerability, it may affect any Payload project running on the affected versions of React or Next.js. Payload does not install any of these dependencies directly, it simply enforces their versions through its peer dependencies, which will only warn of the version incompatibilities.
You will need to upgrade React and Next.js yourself in your own apps to the patched versions listed below in order to receive these updates.
Quick steps:
If using pnpm as your package manager, here's a one-liner:
pnpm add react@19.2.1 next@15.4.8 To do this manually:
- In your
package.json:- Bump
reactto19.2.1 - Bump
nextto15.4.8
- Bump
- Reinstall node modules, e.g.
pnpm i - Redeploy your app
Here's a full breakdown of the vulnerable packages and their patched releases:
| Vulnerable package | Patched release |
|---|---|
| React | 19.0, 19.1, 19.2 19.0.1, 19.1.2, and 19.2.1 |
| Next.js | 14.3.0-canary, 15.x, and 16.x (App Router) 14.3.0-canary.88, 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7 |
See #14807 for more details.
🚀 Features
- support custom slugify functions (#14117) (59a1607)
- accessibility testing and improvements (#14454) (42cbd70)
- support external JSON schema file references in type generation (#14749) (cb3a078)
- cpa: assume adapter for with-cloudflare-d1 template (#14799) (4f03016)
- richtext-lexical: add align support to upload nodes (#14720) (a21c47b)
Feature Details
Custom Slugify Functions - Override the default slug field behavior with your own slugify function. Useful for special character encoding, additional language support, or custom slug formatting. Also deprecates fieldToUse in favor of useAsSlug for consistency with useAsTitle. #14117
import type { CollectionConfig } from 'payload' import { slugField } from 'payload' import slugify from 'slugify'; export const MyCollection: CollectionConfig = { // ... fields: [ // ... slugField({ slugify: ({ valueToSlugify }) => slugify(valueToSlugify, { // ...additional `slugify` options here }) }) ] }Accessibility Testing and Improvements - Adds automated accessibility testing infrastructure including axe a11y scans, focus indicator checks, and horizontal scroll overflow detection. Covers all fields, major views, components, plugins, and Lexical editor. See the a11y report discussion for tracked issues. #14454
External JSON Schema References in Type Generation - Enables $ref pointers to external .json schema files in typescriptSchema field config. External references are resolved relative to process.cwd(). #14749
// payload.config.ts { typescript: { schema: [ ({ jsonSchema }) => { jsonSchema.definitions.MyType = { $ref: './schemas/my-type.json' } return jsonSchema }, ] } }Auto-detect D1 Adapter (cpa) - The with-cloudflare-d1 template now automatically assumes the D1 database adapter, eliminating the database selection prompt during project creation. #14799
Upload Node Alignment (richtext-lexical) - Adds alignment support to upload nodes in the Lexical editor. Upload/media blocks can now be aligned left, center, or right using the FORMAT_ELEMENT_COMMAND. #14720
🐛 Bug Fixes
- remove "all" from JSDoc comment on supported http methods in endpoints (#14777) (8c8def9)
- should exclude svg files from file buffer mime validation (#14751) (015b363)
- deps: bump minimum react and next versions (#14807) (2dfe464)
- plugin-import-export: incorrect user type in Export causing runtime type mismatch (#14790) (61f5aee)
- plugin-multi-tenant: tenant modal not appearing when autosave is off (#14806) (b96e928)
- plugin-multi-tenant: auto assign tenant when autosave is enabled (#14745) (b0674fa)
- richtext-lexical: copying and pasting a single block in Lexical results in an error due to duplicate ID (#14738) (cd9addf)
- richtext-lexical: export serverInlineBlock modules (#14739) (becceb7)
- translations: translate slug field actions (#14784) (5542e56)
- ui: prevent NaN page parameter in polymorphic relationship pagination (#14795) (bbdfdb8)
- ui: reduce spacing between checkbox and first column when few columns shown (#14776) (6ae1bc8)
📚 Documentation
- documents block field image aspect ratio (#14679) (b6a336e)
- document default password reset URL (#14688) (a68423b)
- adds strongly typed examples (#14513) (abe8563)
🧪 Tests
📝 Templates
⚙️ CI
🏡 Chores
⚠️ BREAKING CHANGES
🤝 Contributors
- Jarrod Flesch (@JarrodMFlesch)
- Jake (@jacobsfletch)
- German Jablonski (@GermanJablo)
- Elliot DeNolf (@denolfe)
- Sean Zubrickas (@zubricks)
- Patrik (@PatrikKozak)
- Paul (@paulpopus)
- Jessica Rynkar (@jessrynkar)
- Tobias Odendahl (@tak-amboss)
- Ricardo Tavares (@rjgtav)
v3.65.0
v3.65.0 (2025-11-25)
❗️Breaking Change
This release disables Turbopack Build support. Please use Webpack to build your app for now. You can do so by using pnpm build on Next.js 15 and pnpm build --webpack on Next.js 16.
🚀 Features
- add augmentable interfaces for collection and global custom properties (#14729) (850c252)
- allow to specify payload instance cache key in
handleEndpoints(#14675) (efa2fd2) - db-mongodb: add afterCreateConnection and afterOpenConnection hooks (#14649) (af6ba86)
- plugin-mcp: add localization support to MCP resource operations (#14334) (a3f490b)
- plugin-mcp: adds a PayloadRequest to custom tool, prompt, and resource handlers (#14644) (0d14b06)
- ui: extract block selector from blocks drawer (#14697) (b9b11f0)
Type-Safe Custom Properties - Add augmentable interfaces for collection and global custom properties: CollectionCustom, CollectionAdminCustom, GlobalCustom, and GlobalAdminCustom. Enables type-safe plugin configuration at the collection/global level with full autocomplete support, matching the existing FieldCustom pattern. #14729
// Augment interfaces in your plugin or project declare module 'payload' { export interface CollectionAdminCustom { disabledFields?: string[] } export interface CollectionCustom { myPluginConfig?: { enabled: boolean settings: Record<string, any> } } } // Now get full type safety in collections export const Posts: CollectionConfig = { slug: 'posts', admin: { custom: { disabledFields: ['status'] // ✅ Type-safe! } }, custom: { myPluginConfig: { enabled: true, settings: {} } } }Payload Instance Cache Key - Specify payloadInstanceCacheKey in handleEndpoints and createPayloadRequest to control which cached Payload instance is used for custom endpoints. Useful for multi-tenant scenarios or when managing multiple Payload instances. #14675
MongoDB Connection Lifecycle Hooks (db-mongodb) - Add afterCreateConnection and afterOpenConnection hooks to the MongoDB adapter for performing setup logic after connection/pool initialization. Enables use cases like connection pooling in serverless environments. #14649
export const databaseAdapter = mongooseAdapter({ // ... afterOpenConnection: async (adapter) => { const client = adapter.connection.getClient() attachDatabasePool(client); }, })MCP Localization Support (plugin-mcp) - Add full localization support to MCP resource operations (create, update, find, delete). All MCP tools now accept locale and fallbackLocale parameters, bringing feature parity with Payload's REST API for multilingual content management. #14334
// Create content in English { "name": "createPosts", "arguments": { "title": "Hello", "locale": "en" }} // Add Spanish translation { "name": "updatePosts", "arguments": { "id": "123", "title": "Hola", "locale": "es" }} // Retrieve all translations { "name": "findPosts", "arguments": { "id": "123", "locale": "all" }}PayloadRequest in MCP Handlers (plugin-mcp) - Custom tool, prompt, and resource handlers now receive a PayloadRequest object, enabling access to the Payload instance and consistent access control patterns without additional lookups. #14644
// Previously handler: async (args: Record<string, unknown>) => {} // Now with req parameter handler: async (args: Record<string, unknown>, req: PayloadRequest, _extra) => { // Access payload instance, user, locale, etc. const { payload, user, locale } = req }Reusable Block Selector Component (ui) - Extract BlockSelector component from BlocksDrawer and export for external use. Includes new onSelect callback for custom side effects when blocks are selected. #14697
🐛 Bug Fixes
- trigger login hooks after reset password (#14711) (32560e9)
- ensure restoreAsDraft only updates the published doc when draft is false (#14658) (3f3f5db)
- remove init of transaction for global doc access (#14693) (c455f58)
- count versions should allow querying on localized fields (#14695) (e1168a0)
- prevent upload mimeType error when useTempFiles is true (#14689) (fe8a3e8)
- autoRefresh not working due to stale closure and missing in client config (#14612) (8a3c6dc)
- type TypeWithVersion missing latest property (#14676) (9b6e1a3)
- graphql version error in production (#14622) (cd5b344)
- corrects outgoing localized data from afterRead (#14603) (87137fe)
- relationships should not fallback if fallbackLocale is false (#14641) (9f55254)
- hide turbopack warnings (#14640) (03f19bc)
- logout-inactivity route gets stuck on loading indicator when inactivity and isLoggedIn are true (#14596) (7a31c02)
- tighten up error visibility handling (#14606) (c74a40f)
- claude: properly structure claude plugin (#14432) (3198bbe)
- db-*: do not exit process on error during connect (#14647) (ab03163)
- db-mongodb,drizzle: prevent race condition in transaction session cleanup (#14651) (a7cf30d)
- drizzle: postgres 18 support (#14700) (294ebf5)
- next: remove turbopack build support to fix bundle size regression (#14696) (c484a05)
- next: prevent transaction race condition in renderDocument parallel operations (#14652) (802a21a)
- plugin-multi-tenant: fix infinite sync tenant network calls (#14604) (8901c7b)
- richtext-lexical: block names were not loaded (#14698) (c7a87c0)
- ui: ensures modal closes on route change (#14718) (a044a08)
- ui: query preset crash with empty filters in postgres/sqlite (#14722) (42a4384)
- ui: app header overflow on mobile (#14704) (91d3e04)
- ui: shows minRowsProp instead of minRows (#14681) (e40a4b7)
- ui: publish label regression from 14690 (#14692) (ba5834b)
- ui: publish button shows locale-specific text without localized fields (#14690) ([caf68e4](https://github.com/pay...
v3.64.0
v3.64.0 (2025-11-13)
🚀 Features
- add support for UTC timezone in date fields (#14586) (8b34e40)
- next: turbopack build support, fix incorrect handling of external packages (#14475) (3a975d7)
- plugin-mcp: adds MCP context to req.payloadAPI (#14595) (860bdf2)
- plugin-mcp: adds custom auth config (#14538) (73a18dc)
- plugin-redirects: support translations (#14548) (ad8f0b2)
UTC Timezone Support - Add support for 'UTC' as a timezone value in date fields. Previously unsupported due to validation against Intl API runtime values. Also fixes issue where having only one timezone would make it selected by default. #14586
import { buildConfig } from 'payload' const config = buildConfig({ admin: { timezones: { supportedTimezones: [ { label: 'UTC', value: 'UTC', }, ], defaultTimezone: 'UTC', }, }, })Turbopack Build Support - Full support for Turbopack builds (now default in Next.js 16). Properly externalizes database adapter entry points to prevent production failures. Resolves issues with direct dependency externalization causing runtime errors. #14475
MCP Context Detection - Detect when Payload API calls originate from MCP context using req.payloadAPI === 'MCP'. Enables conditional logic in hooks based on MCP usage. #14595
export const Posts: CollectionConfig = { slug: 'posts', hooks: { beforeRead: [ ({ doc, req }) => { if (req.payloadAPI === 'MCP') { doc.title = `${doc.title} (MCP Hook Override)` } return doc }, ], }, }Custom Auth Configuration - Override default API key authentication with custom authorization logic using overrideAuth. Provides granular control over MCP access permissions. #14538
import { type MCPAccessSettings, mcpPlugin } from '@payloadcms/plugin-mcp' plugins: [ mcpPlugin({ overrideAuth: (req) => { return { posts: { find: true }, products: { find: true, update: true }, } as MCPAccessSettings }, }) ]Redirect Plugin Translation Support - Enable translations for plugin fields, eliminating need for verbose field overrides configuration. Configure field labels in multiple languages directly through i18n config. #14548
export default buildConfig({ i18n: { translations: { en: { 'plugin-redirects': { fromUrl: 'Source URL (Custom)', }, }, de: { 'plugin-redirects': { fromUrl: 'Quell-URL', internalLink: 'Interner Link', }, }, }, }, plugins: [redirectsPlugin({ collections: ['pages'] })], })🐛 Bug Fixes
- previous value undefined for nested fields in afterChange (#14582) (d60ea6e)
- default values inconsistent between Local and REST APIs (#14556) (8f7ef35)
- findGlobalVersionByID id type (#14534) (99ed0e5)
- localized block fields (#14587) (2295c89)
- add secondary PDF mimeType validation and tests (#14529) (ce479ab)
- unlock access not being correctly denied when using a where query (#14585) (f63e34e)
- error when calling jobs.handleSchedules when there are no schedules defined (#14519) (072cb97)
- changing the language of the admin panel does not work for "radio" and "select" fields. (#14569) (bb520d6)
- inject custom translations into supportedLanguages in sanitization (#14549) (d7f1ea2)
- db-mongodb: localization transforms on nested localized fields (#14600) (6070d8d)
- db-mongodb: findVersions/findGlobalVersions not respecting limit of 0 (#14573) (43dcf84)
- graphql: avoid errors with sort as empty string (#14594) (fad476d)
- next: turbopack error when using db-d1-sqlite package (#14558) (bd6decf)
- next, ui: show status "changed" in List View (#14555) (565680d)
- plugin-form-builder: expose formSubmissionID as a variable to be used in emails (#14429) (ad74386)
- plugin-mcp: correctly uses local access controls (#14457) (fc2becf)
- richtext-lexical: urls being wrongly encoded by incomplete URL validation (#14557) (2cb0c59)
- storage-r2: respect data.prefix in handleUpload path construction (#14485) (454d0d3)
- ui: error on inserting new documents on uploads with hasMany (#14567) (fd44d2b)
- ui: save button becomes disabled after failed save with draft validation (#14584) (6fda71a)
- ui: invalid req.locale shows incorrect data (#14537) (f29a07f)
⚡ Performance
🛠 Refactors
📚 Documentation
🧪 Tests
- move draft validation tests from form-state to field error states test suite (#14599) (e1f07ff)
- run cpa against create-next-app latest and canary (#14583) (cca97c6)
- 21x faster versions int suite (#14510) (844f99f)
📝 Templates
⚙️ CI
🏡 Chores
- add .worktrees to .gitignore (87f2bd9)
- fix serverExternalPackages errors in monorepo (#14535) (e76da3f)
🤝 Contributors
- Kendell (@kendelljoseph)
- Jarrod Flesch (@JarrodMFlesch)
- Patrik (@PatrikKozak)
- Paul (@paulpopus)
- German Jablonski (@GermanJablo)
- Jessica Rynkar (@jessrynkar)
- Sasha (@r1tsuu)
- Sam (@damnsamn)
- Alessio Gravili (@AlessioGr)
- Tobias Odendahl (@tak-amboss)
- Elliot DeNolf (@denolfe)
- Jens Becker (@jhb-dev)
- Sean Zubrickas (@zubricks)
