TL;DR
Payload CMS v3.43.0 brings significant enhancements to database capabilities, storage options, and UI improvements. Key additions include PostgreSQL read replica support, dynamic presigned URL downloads for S3 storage, and the ability to store blocks as JSON for improved performance. The release also features a completely redesigned version diff view, customizable upload controls, and numerous bug fixes across storage adapters to properly return 404 errors instead of 500 when files aren't found.
Highlight of the Release
- PostgreSQL read replica support for offloading read-heavy traffic
- Dynamic presigned URL downloads for S3 storage
- Option to store blocks in a JSON column for improved performance
- Completely redesigned version diff view
- Custom upload controls for file uploads
- Proper 404 errors (instead of 500) when files aren't found in storage adapters
- Access to
data
argument in afterChange
hooks
Migration Guide
PostgreSQL Blocks as JSON
If you choose to use the new blocksAsJSON: true
option with PostgreSQL, be aware that this changes how blocks are stored in the database. This option should be set before creating any collections with blocks, as changing this setting on existing collections would require data migration.
Job System Changes
The payload.jobs.run()
method and npx payload jobs:run
bin script now only run jobs from the default
queue by default. If you were relying on these to run jobs from all queues, you'll need to update your code to use the new allQueues
parameter:
// Run jobs from all queues
await payload.jobs.run({ allQueues: true })
For the CLI:
npx payload jobs:run --all-queues
Version View Changes
The version comparison view has been completely redesigned. The column layout has changed:
- Previously: Selected version on the left, latest version on the right
- Now: Previous version on the left, selected version on the right (similar to GitHub)
This change might require users to adjust their mental model when comparing versions.
Translation Import Changes
If you're using Bengali (Bangladesh) or Bengali (India) translations, the import names have been updated to follow camelCase convention:
Update your imports accordingly if you're using these translations directly.
Upgrade Recommendations
This release contains significant improvements and bug fixes with minimal breaking changes. We recommend upgrading to v3.43.0 for all users, especially those who:
- Use PostgreSQL and need read replica support or better performance with blocks
- Use S3 storage and need dynamic control over presigned URLs
- Have experienced issues with storage adapters returning 500 errors for missing files
- Want to take advantage of the improved version diff view
- Need access to the original data in afterChange hooks
How to Upgrade
-
Update your Payload CMS dependencies:
npm install @payloadcms/payload@3.43.0
# Update any other Payload packages you're using
npm install @payloadcms/db-postgres@latest @payloadcms/storage-s3@latest # etc.
-
Review the migration guide for any changes that might affect your implementation, particularly around job system changes and translation imports.
-
Test your application thoroughly, especially if you're using features that received significant updates like storage adapters or PostgreSQL database functionality.
Bug Fixes
Storage Adapters
- Proper Error Handling: Fixed all storage adapters (S3, GCS, Azure) to return 404 errors instead of 500 when files are not found.
Database Fixes
-
MongoDB:
- Fixed issues with 4+ level deep relationship querying
- Updated Mongoose to version 8.15.1
-
PostgreSQL:
- Fixed regression with 3+ level nested blocks
- Fixed reordering of enum values by updating Drizzle dependencies
- Fixed issues with storing blocks in JSON columns
-
SQLite:
- Fixed unique validation error messages to properly extract field names
UI Fixes
Plugin Fixes
-
Import/Export Plugin:
- Fixed export to include all available fields by default
- Fixed download button appearing in collection edit view
- Fixed incorrect custom type on toCSVFunction changed to toCSV
-
Nested Docs Plugin:
- Fixed error name checking that changes at compile time
-
Redirects Plugin:
- Added missing optional chaining to prevent errors
Other Fixes
-
Job System:
- Fixed
payload.jobs.run()
and bin script to only run jobs from the default
queue by default
- Added support for
allQueues
argument
- Ensured job autoruns are not triggered if jobs collection is not enabled
-
Filtering:
- Fixed filtering joins in
where
queries by ID
- Fixed orderable collections having incorrect sort results with mixed capitalization
-
Translations:
- Reformatted
bnBD
and bnIN
translation imports to camelCase
New Features
Database Improvements
-
PostgreSQL Read Replicas: Added support for read replicas in both db-postgres
and db-vercel-postgres
adapters, allowing you to offload read-heavy traffic to separate database instances.
database: postgresAdapter({
pool: {
connectionString: process.env.POSTGRES_URL,
},
readReplicas: [process.env.POSTGRES_REPLICA_URL],
})
-
JSON Storage for Blocks: Added option to store blocks in a JSON column with blocksAsJSON: true
for SQL adapters, which can significantly improve performance with large amounts of blocks.
Storage Enhancements
-
Dynamic Presigned URL Downloads: S3 storage adapter now supports dynamic control over which files use presigned URLs through a shouldUseSignedURL
function:
s3Storage({
collections: {
media: {
signedDownloads: {
shouldUseSignedURL: ({ collection, filename, req }) => {
return req.headers.get('X-Disable-Signed-URL') !== 'false'
},
},
},
},
})
-
Sharp Constructor Options: Added constructorOptions
property to the upload config to pass options directly to the Sharp image processing library.
UI Improvements
-
Custom Upload Controls: Added ability to add custom components to the file upload component:
export const Media: CollectionConfig = {
slug: 'media',
upload: {
admin: {
components: {
controls: [
'/collections/components/Control/index.js#UploadControl',
],
},
},
},
fields: [],
}
-
Version Diff View Overhaul: Completely redesigned the version comparison view with improved layout, better locale selection, and enhanced diff visualization.
-
Document Tab Ordering: Added ability to customize the order of document view tabs using the new tab.order
property:
admin: {
components: {
views: {
edit: {
myCustomView: {
path: '/my-custom-view',
Component: '/path/to/component',
tab: {
href: '/my-custom-view',
order: 100, // This will put this tab in the first position
},
}
}
}
}
}
API Enhancements
-
Exposed Data in afterChange Hooks: The afterChange
hook for collections and globals now includes the data
argument, providing access to the original input data alongside the saved document:
afterChange: [
({ context, data, doc, operation, previousDoc, req }) => {
if (data?.customFlag) {
// Perform logic based on raw input
}
},
],
-
Server-Side Folder Rendering: Moved folder rendering from the client to the server for improved performance.
Security Updates
This release includes security improvements through the addition of URL filters to help prevent Server-Side Request Forgery (SSRF) attacks. The implementation uses undici
instead of native fetch
to support both overriding agent/dispatch and implementing credentials: include
functionality.
Additionally, the storage adapters (S3, GCS, Azure) now properly return 404 errors instead of 500 when files are not found, which follows security best practices by not exposing unnecessary error details.
Performance Improvements
UI Performance
- Drawer Animation: Improved drawer component to prevent re-animation on re-render, reducing unnecessary visual updates.
- Reduced useEffects: Simplified drawer component by removing unnecessary
useEffect
and useState
calls, making the component more efficient.
- Server-Side Folder Rendering: Moved folder rendering from the client to the server, improving initial load performance.
Database Performance
- JSON Storage for Blocks: Added option to store blocks in a JSON column with
blocksAsJSON: true
for SQL adapters, which can significantly improve performance with large amounts of blocks compared to the relational approach.
Read Replicas
- PostgreSQL Read Replicas: Added support for read replicas in both
db-postgres
and db-vercel-postgres
adapters, allowing you to offload read-heavy traffic to separate database instances, improving overall system performance.
Impact Summary
Payload CMS v3.43.0 delivers substantial improvements across database functionality, storage options, and UI components. The addition of PostgreSQL read replica support enables better handling of read-heavy traffic, while the new option to store blocks as JSON can significantly improve performance for complex content structures.
Storage adapters now properly return 404 errors for missing files and S3 storage gains dynamic control over presigned URLs. The admin UI receives a complete overhaul of the version diff view, making content comparison more intuitive, along with customizable upload controls and document tab ordering.
For developers, the exposure of the data
argument in afterChange
hooks provides greater flexibility when working with saved documents, and the ability to customize Sharp constructor options offers more control over image processing.
This release represents a well-rounded update that improves both developer experience and end-user functionality, with careful attention to performance optimizations and bug fixes across the entire platform.
Full Release Notes
🚀 Features
🐛 Bug Fixes
- ensure job autoruns are not triggered if jobs collection not enabled (#12808) (769ca03)
- filtering joins in
where
by ID (#12804) (9943b35)
- change payload.jobs.run and bin script to only run jobs from
default
queue by default, adds support for allQueues argument (#12799) (06ad171)
- remove unsupported path property from default document view configs (#12774) (f64a0ae)
- field inside an unnamed group field erroring when used as a title (#12771) (143aff5)
- error when saving global with versioning enabled (#12778) (cf43c5c)
- reduce global DOM/Node type conflicts in server-only packages (#12737) (67fb29b)
- orderable has incorrect sort results depending on capitalization (#12758) (37afbe6)
- ensure redirect route is correctly formatted for "Copy to locale" (#12560) (9d2817e)
- db-mongodb: 4x and more level deep relationships querying (#12800) (245a2de)
- db-mongodb: bump
mongoose
to 8.15.1
(#12755) (860e0b4)
- db-postgres: reordering of enum values, bump
drizzle-kit@0.31.0
and drizzle-orm@0.43.1
(#12256) (7045182)
- db-postgres: x3 and more nested blocks regression (#12770) (df8be92)
- db-sqlite: sqlite unique validation messages (#12740) (254ffec)
- plugin-import-export: download button in collection edit view (#12805) (8235fe1)
- plugin-import-export: incorrect custom type on toCSVFunction changed to toCSV (#12796) (3edcc40)
- plugin-import-export: export all available fields by default (#12731) (c4e5831)
- plugin-nested-docs: check error name that is changed at compile time (#12798) (729b676)
- plugin-redirects: add missing optional chaining (#12753) (d0e647a)
- storage-azure: return error status 404 when file is not found instead of 500 (#11734) (018317d)
- storage-gcs: return 404 on file not found instead of 500 (#11746) (d8626ad)
- storage-s3: return error status 404 when file is not found instead of 500 (#11733) (a19921d)
- translations: reformats
bnBD
and bnIN
translation imports to camelCase (#12736) (08fbcb5)
- ui: reordering with a join field inside a group (#12803) (e60db07)
- ui: adjust alignment of list header actions (#12793) (77f3805)
- ui: not showing hyphenated field values in table (#12791) (e7b5884)
- ui: inconsistent pill sizes across admin panel (#12788) (9364d51)
⚡ Performance
- ui: do not re-animate drawer on re-render, reduce useEffects (#12743) (cb3f9bb)
🛠 Refactors
📚 Documentation
🏡 Chores
🤝 Contributors