TL;DR
PayloadCMS v3.0.0-beta.109 brings significant improvements to the admin UI, database adapters, and developer experience. Key updates include a preselected theme option, customizable Drizzle schema hooks, improved error handling, and numerous UI fixes for document status indicators, field alignment, and rich text editor components. This release contains one breaking change to the afterError hook structure, now requiring an array of functions instead of a single function.
Highlight of the Release
- Breaking change to
afterError hook structure - now requires an array of functions
- Added ability to preselect light/dark theme for admin UI
- New Drizzle schema customization with before/after init hooks
- Added database upsert method to all database adapters
- Fixed document status indicators (Published, Draft, Changed)
- Improved rich text editor table display with dark mode support
Migration Guide
Breaking Change: afterError Hook Structure
The afterError hook structure has been changed to accept an array of functions instead of a single function:
- afterError: () => {...}
+ afterError: [() => {...}]
Additionally, the arguments passed to the hook functions have changed to an object with the following properties:
| Argument | Description |
| --- | --- |
| error | The error that occurred. |
| context | Custom context passed between Hooks. |
| graphqlResult | The GraphQL result object, available if the hook is executed within a GraphQL context. |
| req | The Request object containing the currently authenticated user |
| collection | The Collection in which this Hook is running against. This will be undefined if the hook is executed from a non-collection endpoint or GraphQL. |
| result | The formatted error result object, available if the hook is executed from a REST context. |
To migrate:
- Update all
afterError hooks to use an array syntax
- Update the function parameters to use the new object structure
- Test your error handling to ensure it works as expected
Upgrade Recommendations
This beta release contains one breaking change to the afterError hook structure. If you're using this hook in your application, you'll need to update your code.
For most users, this upgrade is recommended as it brings significant UI improvements, database enhancements, and bug fixes. The breaking change is isolated to a specific hook and should be straightforward to update.
To upgrade:
- Update your package.json to reference
v3.0.0-beta.109
- Run
npm install or yarn to update dependencies
- Update any
afterError hook implementations to use the new array syntax
- Test your application thoroughly, especially error handling functionality
Bug Fixes
UI Improvements
- Fixed inconsistent arrow dropdown styling on buttons and popover missing caret
- Fixed document status indicators to correctly show "Published", "Draft", or "Changed" states
- Fixed number field not being able to clear its value
- Improved field alignment inside row fields
- Fixed autosave and preventLeaveWithoutSaving interference with form state
Rich Text Editor
- Added dark mode support for table dropdown menu
- Added max-width to tables as a temporary fix for overflow issues
- Fixed regression in lexical blocks
Database Fixes
- Fixed MongoDB docs being duplicated in list view with drafts enabled
- Added default limit of 0 to MongoDB db.find for documents with joins
- Fixed sanitization of query values for UUID and number IDs
- Fixed array/relationship/select hasMany fields in localized groups for Drizzle
- Fixed join functionality on relationships in unnamed fields
Other Fixes
- Fixed user data not being set after first user registration in Next.js
- Fixed document locking behavior when using live preview
- Fixed client function error on forgot password view
- Fixed SEO plugin titles being displayed twice
New Features
Theme Preselection
Administrators can now enforce light or dark theme in the admin panel to match branding requirements, overriding user preferences.
Drizzle Schema Customization
Added beforeSchemaInit and afterSchemaInit hooks to customize the generated Drizzle schema. This enables:
- Preserving existing database structures when migrating to Payload
- Extending database with tables not managed by Payload
- Adding columns or features not supported in the Payload config
Database Upsert Method
Added an upsert method to the database interface and implemented it across all database adapters. This allows for more efficient update-or-create operations.
Improved Error Handling
Enhanced the afterError hook to accept an array of functions and changed to object arguments with better structure, providing more flexibility and control over error handling.
Security Updates
No significant security fixes were included in this release.
Performance Improvements
Database Performance
- The new upsert method across database adapters reduces the need for separate read and write operations
- Improved handling of localized field sorting in Drizzle adapter
UI Performance
- Better document locking behavior prevents unnecessary lock/unlock operations when switching between tabs
- Fixed form state fetching reliability with improved autosave logic
Impact Summary
This release brings significant improvements to PayloadCMS with a focus on UI enhancements, database adapter improvements, and developer experience. The most notable change is the breaking change to the afterError hook structure, which now requires an array of functions instead of a single function.
For developers, the addition of Drizzle schema customization hooks provides powerful capabilities for database schema management, especially when migrating existing databases to Payload. The new database upsert method across all adapters improves efficiency for update-or-create operations.
Content editors will benefit from numerous UI fixes, including improved document status indicators, better field alignment, and enhanced rich text editor components with dark mode support for tables.
Administrators gain the ability to enforce light or dark theme in the admin panel, which can be valuable for maintaining consistent branding.
Overall, this release represents a solid improvement to the beta version with valuable features and important bug fixes, with minimal breaking changes that should be straightforward to address.
Full Release Notes
š Features
- preselected theme (#8354) (84d2026)
- drizzle: customize schema with before / after init hooks (#8196) (8acbda0)
- add upsert to database interface and adapters (#8397) (82ba193)
- improve afterError hook to accept array of functions, change to object args (#8389) (28ea0c5)
- templates update (#8391) (e72f12a)
š Bug Fixes
- db-mongodb: docs duplicated in list view with drafts (#8435) (adc9bb5)
- richtext-lexical: add max-width to tables (temporary fix for overflow). (#8431) (a09811f)
- ui: autosave and preventLeaveWithoutSaving interfering with fetching form-state reliably (#8434) (c73f6c7)
- ui: number field not being able to clear out the field's value (#8425) (5c2e39e)
- ui: align to the top fields inside row field (#8421) (4b0351f)
- ui: versions in documentInfo and status component reverse latest true changes (#8417) (95231da)
- db-mongodb: add req to migration templates for transactions (#8407) (b10f61c)
- make field property of FieldLabel optional and partial (#8409) (87360f2)
- plugin-seo: titles being displayed twice (#8310) (8fadc33)
- drizzle: migrate args no longer partial payload request (#8375) (c6519ab)
- client function error on forgot password view (#8374) (06ea67a)
- drizzle: use alias for localized field sorting (#8396) (775e6e4)
- lock documents using the
live-preview view (#8343) (57f93c9)
- ui: published, draft and changed labels should now be correctly displayed (#8382) (a37abd1)
- db-vercel-postgres: include needed pg dependency (#8393) (6da4f06)
- templates: proper migration file import source for vercel-postgres (#8394) (50da212)
- safely access user in auth operations (#8381) (a80f5b6)
- db-mongodb: db.find default limit to 0 (#8376) (dc69e2c)
- richtext-lexical: regression in lexical blocks (#8378) (19e2f10)
- richtext-lexical: table dropdown menu dark mode color (#8368) (bd41b4d)
- optional sortOptions type for SingleRelationshipFieldClient (#8340) (fbc395b)
- next: set the user data after first user registration (#8360) (30eb1d5)
- drizzle: sanitize query value uuid / number id NaN (#8369) (dedcff0)
- drizzle: array/relationship/select hasMany in localized field (#8355) (338c93a)
- cannot use join on relationships in unnamed fields (#8359) (c696728)
- ui: inconsistent arrow dropdown on buttons, popover missing caret (#8341) (3583c45)
ā ļø BREAKING CHANGES
-
improve afterError hook to accept array of functions, change to object args (#8389) (28ea0c5)
Changes the afterError hook structure, adds tests / more docs.
Ensures that the req.responseHeaders property is respected in the
error handler.
afterError now accepts an array of functions instead of a single
function:
- afterError: () => {...}
+ afterError: [() => {...}]
The args are changed to accept an object with the following properties:
| Argument |
Description |
error |
The error that occurred. |
context |
Custom context passed between Hooks. More details. |
graphqlResult |
The GraphQL result object, available if the hook is executed within a GraphQL context. |
req |
The Request object containing the currently authenticated user |
collection |
The Collection in which this Hook is running against. This will be undefined if the hook is executed from a non-collection endpoint or GraphQL. |
result |
The formatted error result object, available if the hook is executed from a REST context. |
š¤ Contributors