Releases: payloadcms/payload
Release list
v3.86.0
v3.86.0 (2026-07-10)
🚀 Features
- collection-level disableBulkDelete (#17207) (ca02cdc)
- plugin-form-builder: v3 backport to support translations (#17255) (2cde8c8)
- ui: add livePreview.openByDefault config option (#17213) (f23b693)
🐛 Bug Fixes
- coerce schedulePublish doc.value to collection ID type before update (#17238) (7de11b2)
- escape regex metacharacters in isURLAllowed pathname allow-list (#17237) (2061859)
- respect disabled GraphQL config, v3 backport (#17228) (9e9c35a)
- allow access to files reuploaded on a draft (#17209) (f02d22a)
- plugin-multi-tenant: run tenant delete cleanup inside the request transaction (#17175) (d128fde)
- sdk: use qs-esm allowEmptyArrays parameter (#17208) (c7dc68e)
- ui: presentational fields skipped in form state when admin.condition is false (#17224) (f31f26d)
- ui: prevent slug field error tooltip from hiding lock button (#15885) (908fba1)
⚙️ CI
🤝 Contributors
- Jessica Rynkar (@JessRynkar)
- Ævar Þór Gunnlaugsson (@aevarOrigo)
- Sasha (@r1tsuu)
- Herman Ciechanowiec (@ciechanowiec)
- Vivek Tyagi (@darkspirit2802)
- Noah Bachmann (@noahbachmann)
- Jake Fletcher (@jacobsfletch)
- Amelia (@LimChorngUan)
- German Jablonski (@GermanJablo)
- Elliot DeNolf (@denolfe)
- Jarrod Flesch (@JarrodMFlesch)
v3.85.2
v3.85.2 (2026-07-01)
🐛 Bug Fixes
- payload bin fails with tsx on node v23.5+ (#17081) (afb0226)
- regenerate reused array and block row IDs during bulk update (3.x) (#17018) (e526c88)
- prevent type generation script from hanging on storage-r2 (#17020) (b681448)
- prevent reordering from unpublishing documents that have a newer draft (#16969) (b4d43c0)
- db-mongodb: remove duplicate IDs in nested relationship queries (#17019) (8533dfb)
- deps: resolve high severity audit vulnerabilities (#17086) (ac000e5)
- deps: override transitive js-cookie to ^3.0.7 (CVE-2026-46625) (#17000) (ef888de)
- drizzle: preserve failing sub-table on unique-constraint ValidationError (3.x) (#17015) (6dfac53)
- plugin-cloud-storage: split client and server utility exports (#17152) (30bc3fd)
- plugin-cloud-storage: prevent draft file reupload from unpublishing the document (3.x) (#17034) (a18ae22)
- richtext-lexical: preserve hard line breaks on markdown import (#17061) (c0affcb)
- translations: replace Malay strings in Burmese (my) locale (3.x) (#17032) (c3ae01d)
- ui: preserve polymorphic upload bulk select relation (#17112) (9691e42)
- ui: list relationship cell shows (Untitled) for draft-only titles (#16979) (16152e2)
- ui: respect admin.condition on row fields (#16954) (29afa77)
⚙️ CI
- backport test service image pinning to ghcr on 3.x (#17162) (d04d47e)
- reintroduce audit script (#17122) (f76d670)
🤝 Contributors
- Jarrod Flesch (@JarrodMFlesch)
- Elliot DeNolf (@denolfe)
- Sasha (@r1tsuu)
- German Jablonski (@GermanJablo)
- Amelia (@LimChorngUan)
v3.85.1
v3.85.1 (2026-06-09)
🐛 Bug Fixes
- fix draft save and duplicate behaviour on upload-enabled collections (#16853) (fad992c)
- bin scripts cannot import dependencies without explicit "type": "module" (backport) (#16848) (6707e85)
- add type declarations for css export (TypeScript 6 compat) (#16348) (6c81355)
- follow redirects when fetching uploaded files for MIME type detection (#16708) (ac46214)
- plugin-import-export: fix CSV import of arrays and richText nest… (#16923) (ccbdcc2)
- ui: use explicit relative paths for internal SCSS imports v3.x (#16827) (c039e55)
- ui: hide entire tabs field when admin.condition is false (#16809) (79b4e4c)
⚡ Performance
📚 Documentation
- fixes 404 link to monaco editor options (#16877) (5f40868)
- restructure getting started and concepts pages (#16846) (0f384f4)
⚙️ CI
🤝 Contributors
- Paul (@paulpopus)
- Habeeb (@haxllo)
- Sean Zubrickas (@zubricks)
- Alessio Gravili (@AlessioGr)
- Jake Fletcher (@jacobsfletch)
- Anders Semb Hermansen (@andershermansen)
- Elliot DeNolf (@denolfe)
v3.85.0
v3.85.0 (2026-05-26)
🚀 Features
- plugin-import-export: out of beta and added support for collection-level and field-level hooks (#16556) (cf9252d)
🐛 Bug Fixes
- bump uuid package to 13.0.2 (#16545) (274af06)
- stop workflows retrying forever when no retries are configured (#16465) (caf9150)
- db-mongodb: bump mongoose to 8.22.1 for GHSA-wpg9-53fq-2r8h (#16688) (4baba91)
- plugin-cloud-storage: propagate custom hook errors during upload (#16632) (055c508)
- plugin-cloud-storage: preserve user-defined prefix.defaultValue (#16529) (8d14915)
- plugin-cloud-storage: dedupe filename in clientUploads signed URL (#16510) (64b2860)
- plugin-multi-tenant: tenant field unselectable in bulk upload "Edit all" (#16466) (695df3c)
- richtext-lexical: cursor kicked out of nested richtext while typing in a block (#16490) (931a349)
- richtext-lexical: drag/drop image into rich text fails when a field name matches the collection slug (#16409) (d6f7b47)
- ui: bulk upload silently counts failed files as saved (#16532) (c31f4ef)
- ui: respect formatDocURL returning null in ListDrawer (#16464) (0facc44)
- ui: show all listSearchableFields in ListDrawer search placeholder (#16467) (3cd4a64)
📚 Documentation
📝 Templates
⚙️ CI
🏡 Chores
🤝 Contributors
- Sean Zubrickas (@zubricks)
- German Jablonski (@GermanJablo)
- Jake Fletcher (@jacobsfletch)
- Paul (@paulpopus)
- Alessio Gravili (@AlessioGr)
v3.84.1
v3.84.0
v3.84.0 (2026-04-22)
🚀 Features
- allow client components to also be used as custom collection views (#16312) (8fe5f04)
- email-nodemailer: add email recipient override config (#16311) (1c1ed97)
- plugin-ecommerce: add locale-aware currency formatting and symbol positioning (#15139) (6731036)
- plugin-form-builder: add support for multi part uploads (#15268) (aa01a45)
- plugin-mcp: add support for server instructions (#15858) (c852d85)
🐛 Bug Fixes
- unique value errors are not displayed properly for localized fields (#16069) (f6e9073)
- correct slugifyTitle hook example in documentation (#16306) (48db8c1)
- handle multipart uploads without content-length (#16301) (c150ef8)
- plugin-ecommerce: verify PaymentIntent succeeded before creating… (#15902) (500e39d)
- richtext-lexical: internal links export as text in markdown transformer (#16302) (3dc6041)
- storage-*: simplify key handling for signed urls and composite prefixes (#16291) (6139508)
- templates: remove tilde SCSS imports and add Sass loadPaths for Windows (#16295) (7ca8b05)
- ui: json and richText fields expose unsupported operators in WhereBuilder (#16353) (a507fcc)
- ui: bulk edit ignores fields in named tabs and shows incorrect labels for unlabeled containers (#16340) (e5bc6be)
📚 Documentation
🧪 Tests
- add tests for autosave creating new versions and losing draft status on reload (#16335) (60d8678)
- add more integration tests to CI (#15419) (8a470c1)
📝 Templates
⚙️ CI
- disable audit-dependencies slack notification (#16329) (eeee018)
- use SLACK_CHANNEL env var for activity notifications (#16323) (a7cc58b)
- use artifacts for e2e prep so job retries don't fail on cache eviction (#16310) (bc590bd)
🏡 Chores
- change other instances of port 3000 being hardcoded in tests (#16290) (7f0b069)
- templates: fix link to one-click deployment (#16337) (5a39afc)
- templates: strengthen types in preview url gen (#14947) (fcbc987)
- templates: remove unused image-3 from website templates (#16155) (f0735b1)
🤝 Contributors
- Patrik (@PatrikKozak)
- Sasha (@r1tsuu)
- Jake Fletcher (@jacobsfletch)
- Elliot DeNolf (@denolfe)
- German Jablonski (@GermanJablo)
- Marcin Gierada (@teastudiopl)
- Anton Ambarov (@AntonAmbarov)
- Paul (@paulpopus)
- Jens Becker (@jhb-dev)
- Neha Prasad (@nehaaprasad)
- Jarrod Flesch (@JarrodMFlesch)
v3.83.0
v3.83.0 (2026-04-15)
🚀 Features
- expand plugin API (#16247) (54189e1)
- add profiling utilities for performance analysis (#16198) (9391c20)
- add internal plugin priority and slug api for cross-plugin discovery (#16244) (5f5694f)
- hide slug field buttons when field is read-only (#14824) (67c2c47)
- cpa: add --agent flag for coding agent skill installation (#16278) (9f9f343)
- drizzle: add uuidv7 support (#16113) (ac01e82)
- email-resend: add Custom headers for the Resend adapter (#15645) (a7dd17c)
- next: add support for custom collection views (#16243) (835a0ad)
- plugin-form-builder: change checkbox label from 'Default Value' to 'Checked by default' (#15229) (b3d2054)
- plugin-mcp: allow external plugins to extend mcp plugin (#16245) (ac4fc31)
- richtext-lexical: add view override system for custom node rendering (#14244) (1ef43eb)
- storage-*: add useCompositePrefixes option and fix client upload prefix handling (#16230) (74aa825)
Expanded Plugin API — New definePlugin helper introduces opt-in execution ordering, cross-plugin discovery via a slug-keyed plugins map, and module augmentation for type-safe plugin options. The existing (config) => config contract remains unchanged. #16247
import { definePlugin } from 'payload'
export const seoPlugin = definePlugin<SEOPluginOptions>({
slug: 'plugin-seo',
order: 10,
plugin: ({ config, plugins, collections, generateTitle }) => ({
...config,
// collections and generateTitle come from SEOPluginOptions
}),
})Profiling Utilities — Lightweight timeSync and timeAsync wrappers for measuring function execution time during development. Wrap any function to capture its duration, then call printProfileResults for a formatted timing table. Not intended for production use. #16198
Internal Plugin Priority & Slug API — Plugins can now attach priority, slug, and options properties for execution ordering and cross-plugin discovery. Lower priority runs first; other plugins can find each other by slug via config.plugins without imports. Marked @internal for now. #16244
Hidden Slug Field Buttons on Read-Only — The Generate and Lock/Unlock buttons on slug fields are now automatically hidden when the field is read-only, removing controls that serve no purpose in that state. #14824
Agent Flag for CPA (cpa) — create-payload-app now supports a --agent / -a flag (claude, codex, cursor) that downloads the Payload coding skill from GitHub and installs it in the correct directory for your agent. A root-level CLAUDE.md or AGENTS.md is written for discoverability. Use --no-agent to skip. #16278
UUIDv7 Support (drizzle) — New idType: 'uuidv7' option for Postgres and SQLite adapters generates time-ordered UUIDs that are friendlier for B-tree indexes than random v4 UUIDs, while using the same storage column type. IDs are generated in application code so older Postgres versions are supported. #16113
Custom Email Headers (email-resend) — The Resend adapter now passes custom headers from sendEmail options to the Resend API, enabling features like List-Unsubscribe headers that were previously silently dropped. #15645
await payload.sendEmail({
from: "Test <test@domain.com>",
to: "jimmybillbob@example.com",
subject: "Email with custom headers",
html: html,
headers: {
"List-Unsubscribe": "<https://domain.com/unsubscribe>",
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
},
});Custom Collection Views (next) — Register custom views at the collection level via admin.components.views[key] with a Component and path. Folders take routing precedence over custom views on upload collections. #16243
{
slug: 'products',
admin: {
components: {
views: {
grid: {
Component: '/components/GridView',
path: '/grid',
exact: true,
},
},
},
},
}Checkbox Label Clarity (plugin-form-builder) — The form builder checkbox field label was changed from "Default Value" to "Checked by default" to eliminate confusion about whether the checkbox toggles a default value or sets the initial checked state. #15229
Extensible MCP Plugin (plugin-mcp) — External plugins can now extend plugin-mcp by finding it via slug in config.plugins and injecting custom MCP tools into its options. Also exports the MCPPluginConfig type for type-safe tool injection. #16245
View Override System for Custom Node Rendering (richtext-lexical) —
export const myViews: LexicalEditorViewMap = {
default: {
heading: {
createDOM() {
const h2 = document.createElement('h2')
h2.textContent = 'Custom Heading'
return h2
},
},
horizontalRule: {
Component: () => <div className="custom-hr">---</div>,
},
link: {
html: '<a href="#">Custom Link</a>',
},
},
}{
fields: [
{
name: 'content',
type: 'richText',
editor: lexicalEditor({
views: '/path/to/views.tsx#myViews',
}),
},
]
}Composite Prefixes for Storage Adapters (storage-*) — New useCompositePrefixes option combines collection and document prefixes instead of one overriding the other. Also fixes a bug where client uploads ignored document prefix entirely. Applies to S3, Azure, GCS, R2, and Vercel Blob. #16230
| Mode | Collection Prefix | Doc Prefix | Result |
|---|---|---|---|
false (default) |
media-folder |
user-123 |
user-123/file.jpg |
true |
media-folder |
user-123 |
media-folder/user-123/file.jpg |
🐛 Bug Fixes
- restore falling back to current document values for
undefinedfields (#16272) (4b4d61c) - enforce mimeTypes restriction when useTempFiles is enabled (#16255) (bb749a5)
- prevent cron from permanently dying after handler errors (#16219) (c5e0e02)
- use safe property assignment in deepMergeSimple (#16271) (2b23010)
- handle concurrent autosave write conflicts gracefully (#16216) (e8502fa)
- use instanceof instead of constructor name in formatErrors (#16089) (216d162)
- parse JSON string where query param (#15745) (2a26b5a)
- expose type for field's
position(#14390) (d9b3c07) - default virtual fields to readOnly in admin UI (#16016) (72396f6)
- localized array,group,blocks fields duplicate with empty values ([#15849](https://github....
v3.82.1
v3.82.1 (2026-04-09)
🐛 Bug Fixes
- next: use correct config key for disabling turbo server fast refresh (#16215) (11adc9d)
- plugin-nested-docs: await populateBreadcrumbs in resaveChildren (#15582) (0554b50)
⚡ Performance
📚 Documentation
📝 Templates
🤝 Contributors
- William Ding (@wingding12)
- Syazwan (@syazwanz)
- Alessio Gravili (@AlessioGr)
- Anders Semb Hermansen (@andershermansen)
v3.82.0
v3.82.0 (2026-04-08)
🚀 Features
- disambiguate media files by prefix via query parameter (#15844) (05ddec1)
- add missing disableErrors to globals findOne operation (#14913) (c8332e7)
- improve default slugify utility by triming whitespace first (#14421) (fdaa051)
- add typescript.postProcess hook for type generation (#16103) (67b5dc3)
- plugin-redirects: add Portuguese translation (#15269) (122f4c1)
- plugin-search: pass collection slug to
beforeSynchook (#11581) (ebbd6ad) - ui: export drag-and-drop components (#12626) (23b0f1b)
🐛 Bug Fixes
- incorrect 24 hour format comment example (#15649) (f42b767)
- resolve 404/500 error when downloading files containing hash in filename (#15799) (3a09387)
- JSDoc string for focalPoint option in uploads so it correctly mentions defaults to true (#13070) (84090ac)
- skip validation for unpublish operations with localized required fields (#16120) (24b9e13)
- skip default validation for virtual fields (#16015) (e09c619)
- db-mongodb: update mongoose-paginate-v2 to fix collation pagination (#16049) (78a27ab)
- drizzle: convert equals/not_equals to in/not_in for hasMany relationship array values (#15766) (59af156)
- next: fix hmr, bump minimum required next.js 16 version to 16.2.2 (#16202) (7f83571)
- next: admin.meta.title object form renders [object Object] in browser tab (#16117) (0981cdc)
- plugin-mcp: add error handling to convertCollectionSchemaToZod (#16114) (6184b0c)
- plugin-multi-tenant: infinite api calling loop on user switch (#16065) (3da805f)
- storage-*: redundant re-uploads when file was already uploaded by the client and add comprehensive E2E tests for
s3andvercel-blob(#16115) (a6735f3) - storage-azure: fix azure storage mime type handling for streaming uploads (#15949) (cd7fcea)
- templates: tailwind file extension is wrong in website template components.json file (#9342) (2011f28)
- templates: fixed forgot password link (#15037) (b505e36)
- templates: add generated files to ESLint ignores (#15716) (941a41f)
- templates: typo in with-cloudflare-d1 template (#14243) (14b708f)
- translations: fix Swedish unpublish translations and capitalization (#15353) (4e48706)
- translations: correct French translation for 'move' action (#14771) (750d29f)
- translations: update passive voice and newLabel wording in zh-TW translations (#13761) (e284ab5)
- translations: update Japanese translations related to localizeStatus (#15358) (7ab2881)
- ui: relationship filter duplicate options when switching operators (#16204) (3a1f31a)
- ui: unpublish button missing for globals and version count incorrectly incrementing after unpublish (#16203) (1ddeb60)
- ui: exclude unnamed tab labels from filter and groupBy field options (#9965) (b13c5c9)
- ui: update node to v20 (#15717) (b2593d6)
- ui: radio fields do not reliably trigger admin.condition re-evaluation on sibling fields (#16056) (7e2a126)
⚡ Performance
🛠 Refactors
- plugin-seo: rename non-JSX files from .tsx to .ts (#14418) (b67882c)
- translations: improve German translations for consistency and accuracy (#14439) (f3c0bc8)
📚 Documentation
- fix typo in Collection Config docs (collection → collections) (#16183) (ac085cd)
- remove JSX comment from content in dashboard (#16156) (05447b7)
- add warning about Cosmos dB incompatibility (#13350) (c4375bd)
- add info about custom errors via
APIErrorto hooks overview (#13047) (d03054e) - fix typo in storage-adapters documentation (#13648) (911f059)
- rename incorrect usage of the cloud storage plugin to align with the imported module in storage-adapters.mdx (#11475) (d491f29)
- add dev note about auth strategy hot-reload requirement (#14122) (c4da453)
- fix anchor link reference for settingsMenu (#14391) (8c748d6)
- nested plugin (#15230) (2e653ae)
- add getDataByPath to useForm table (#12098) (69a49e7)
- add missing comma to seo plugin doc (#11516) (df03ed0)
- fix typo in ecommerce template link in seo plugin docs (#15641) (e2cd07c)
- corrects Local API example in import export docs (#16128) (13a726a)
- update link to Custom Components Performance docs (#15723) (9141e34)
- update folders documentation with the right property ([#14060](https://github.com/...
v3.81.0
v3.81.0 (2026-04-01)
🚀 Features
- add LLM eval suite for Payload conventions and code generation (#15710) (db4b00e)
- next: prevent admin panel errors when cacheComponents is enabled (#16020) (1ecd7dd)
🐛 Bug Fixes
- update file-type, ajv and jose packages (#16118) (d09ed54)
- add field-level access control to internal auth fields (#16119) (4ae5577)
- where querying by a join field with relationship nested to an array (#16101) (0f79eed)
- trashed documents still show as IDs in relationship responses (#16102) (aa143e6)
- db-mongodb: virtual fields within blocks (#16107) (77cdb17)
- db-postgres: stabilize read replicas support (#16083) (46ddf8d)
- db-postgres: handle blockType filters for versions (#16071) (727d74e)
- deps: resolve high severity audit vulnerabilities (#16104) (c5a3767)
- next: respect canAccessAdmin when a custom dashboard view is configured (#16105) (329090c)
- next: forgot password
basePathwas not respected (#16084) (3c40241) - plugin-multi-tenant: forbidden error when logging in as a user with no tenant and no access to all tenants (#16047) (9c58e7c)
- richtext-lexical: prevent invalid h0 heading nodes when all heading sizes are disabled (#16090) (185548a)
- sdk: pass trash to request (#16092) (e0b3e81)
- storage-gcs: bump @google-cloud/storage (#16046) (5c06266)
- storage-vercel-blob: properly handle
alwaysInsertFieldsand add comprehensive integration test suite with a vercel blob emulator (#16080) (8530b45) - templates: add --no-server-fast-refresh to all dev scripts for Next.js 16.2+ compatibility (#16074) (8045887)
- ui: prevent data loss in copy-to-locale with drafts (#16073) (43b8de6)
- ui:
tokenInMemorynot set after refreshing cookie (#15928) (17266ab) - ui: respect
admin.dateFormatfor list view filters (#16040) (d5fe0ce)
🛠 Refactors
📚 Documentation
- clarify unique field index behavior and add warnings for array/blocks nesting (#15969) (38c1d4d)
- document ListViewServerProps/ClientProps and custom list view component patterns (#15970) (eb3b227)
- adds code examples for how to fully implement textStateFeature (#16053) (80ae745)
🧪 Tests
📝 Templates
- fix broken images on Next.js 16 by using relative paths for local media (#16058) (1a0f4d0)
- bump to Next.js 16.2.1 (#16032) (5c3244f)
⚙️ CI
🏡 Chores
- claude: update audit-dependencies skill with lockfile strategy and override rules (#16106) (974870a)
- deps: bump qs-esm from 7.0.2 to 8.0.1 (#16110) (d6862fe)
🤝 Contributors
- Dan Ribbens (@DanRibbens)
- Jarrod Flesch (@JarrodMFlesch)
- angus-msquared (@angus-msquared)
- Sean Zubrickas (@zubricks)
- Alessio Gravili (@AlessioGr)
- Patrik (@PatrikKozak)
- Jake Fletcher (@jacobsfletch)
- Mahmoud Hamdy (@mahmoodhamdi)
- Elliot DeNolf (@denolfe)
- Sasha (@r1tsuu)
- Nathan Bo Wang (@nathanbowang)
- Jon Bockhorst (@jmbockhorst)
- Daniel Giljam (@DanielGiljam)
- Kendell (@kendelljoseph)