Home

>

Tools

>

Payload CMS

>

Releases

>

3.0.0-beta.131

Payload CMS Release: 3.0.0-beta.131

Pre Release

Tag Name: v3.0.0-beta.131

Release Date: 11/15/2024

Payload CMS LogoPayload CMS

Payload CMS is a modern, self-hosted headless content management system built with TypeScript, Node.js, and MongoDB. It's designed specifically for developers who want full control over their content management system while maintaining a powerful admin interface for content editors.

TL;DR

Payload CMS v3.0.0-beta.131: Major MongoDB Upgrade & Performance Improvements

This release brings significant updates to Payload CMS, most notably upgrading MongoDB support to Mongoose 8.8.1, which requires a data migration for existing projects. The release also includes performance optimizations for React Server Components, improved type safety for collection slugs, and several UI enhancements. Several breaking changes require attention during upgrade, particularly for MongoDB users who need to run a migration to convert relationship IDs to ObjectIDs.

Highlight of the Release

    • Upgraded MongoDB support to Mongoose 8.8.1 with required migration path
    • Improved performance by optimizing React Server Component requests
    • Enhanced type safety for collection and global slugs
    • Upgraded UploadThing storage plugin to v7
    • Added security improvements to the /api/access endpoint
    • Improved rich text editor with tooltips and visual indicators for links

Migration Guide

MongoDB Migration (Required for MongoDB Users)

After updating to this beta version, MongoDB users need to run a migration to convert relationship IDs from strings to ObjectIDs. Follow these steps:

  1. Create the migration:
pnpm payload migrate:create --file @payloadcms/db-mongodb/relationships-v2-v3
  1. Run the migration:
pnpm payload migrate

UploadThing Configuration Update

If you're using the UploadThing storage plugin, update your configuration:

options: {
- apiKey: process.env.UPLOADTHING_SECRET,
+ token: process.env.UPLOADTHING_TOKEN,
  acl: 'public-read',
},

Cloud Storage Adapter Configuration

Update how you add upload collections to cloud storage adapters:

Before:

azureStorage({
  collections: {
    [Media.slug]: true,
  },
})

After:

azureStorage({
  collections: {
    media: true,
  },
})

DefaultCellComponentProps Generic Order

If you're using DefaultCellComponentProps in custom components, update to the new generic order:

Before:

type DefaultCellComponentProps<TCellData = any, TField extends ClientField = ClientField>

After:

type DefaultCellComponentProps<TField extends ClientField = ClientField, TCellData = undefined>

To override the cellData type, pass it as the second argument:

DefaultCellComponentProps<RelationshipFieldClient, { myShape: string, here: string }>

Mongoose Model Usage

If your project heavily relies on using Mongoose models directly, review the upgrade guides from v6 to v7 and v7 to v8, making adjustments as needed.

Upgrade Recommendations

This release contains several breaking changes, particularly for MongoDB users. We recommend the following approach:

  1. For MongoDB Users: This is a critical update that requires running a migration. Plan for a maintenance window to perform the upgrade and run the required migration to convert relationship IDs from strings to ObjectIDs.

  2. For All Users: Review the breaking changes carefully, especially if you:

    • Use custom cell components with DefaultCellComponentProps
    • Use the UploadThing storage plugin
    • Have custom code that relies on collection or global slug types
    • Directly use Mongoose models
  3. Testing: Before upgrading production environments, thoroughly test in a staging environment to ensure all functionality works as expected, especially if you have custom code that interacts with the database or uses the affected components.

  4. Timing: If you're using MongoDB and have a large dataset with many relationships, allow extra time for the migration to complete.

The performance improvements and bug fixes in this release make it worthwhile to upgrade, but due to the breaking changes, careful planning and testing are essential.

Bug Fixes

List Column State Synchronization

Fixed an issue where list column state could become out of sync if toggling columns happened in rapid succession or when using a spotty connection where responses could come back out of order. This was resolved by updating internal column state before making requests to the server and introducing an abort controller to prevent out-of-order response issues.

Layout Shift on Form Submission

Fixed layout shifts that occurred when submitting forms with certain fields, reducing UI flicker and providing a smoother user experience.

HasMany Uploads Jumping

Fixed an issue where HasMany uploads would jump when a form was submitting or in readonly mode, improving the stability of the UI.

Duplicate List Preferences

Fixed an issue where duplicate list preferences were being stored in the payload-preferences collection. Now existing preferences are updated rather than creating new documents with each column change.

New Features

MongoDB Upgrade to Mongoose 8.8.1

The MongoDB adapter has been upgraded to use Mongoose 8.8.1, providing better compatibility with MongoDB Atlas and other modern MongoDB features. This is a major upgrade from Mongoose 6 and requires running a migration to convert relationship IDs from strings to ObjectIDs.

Enhanced Type Safety for Collection and Global Slugs

Collection and global slugs now use specific types (CollectionSlug, UploadCollectionSlug, and GlobalSlug) instead of generic strings, improving type safety throughout the codebase. This also changes how upload collections are added to cloud storage adapters.

Rich Text Editor Improvements

  • Added tooltips to toolbar dropdown items, making it easier to see the full text of options that might be cut off
  • Added a visual indicator icon for links that open in new tabs

UploadThing v7 Integration

The UploadThing storage plugin has been upgraded to v7, with configuration options now mirroring the UTApiOptions of v7. The most notable change is using token with process.env.UPLOADTHING_TOKEN instead of apiKey with process.env.UPLOADTHING_SECRET.

Secured Access Endpoint

The /api/access endpoint is now protected behind authentication and returns sanitized results, making it more secure and significantly smaller. The response omits the permission keyword, only includes truthy access results, and consolidates nested permissions when possible.

MongoDB Query Options Support

The MongoDB adapter now supports query options in database update operations, allowing for more control when using the database adapter directly without going through the local API.

Security Updates

Access Endpoint Protection

The /api/access endpoint is now protected behind authentication and returns sanitized results, making it more secure. This change helps prevent potential information leakage by:

  1. Completely omitting the permission keyword from the result
  2. Only returning truthy access results
  3. Consolidating all nested permissions when possible

This reduces the attack surface by limiting the information available to potential attackers about the system's permission structure.

Performance Improvements

Optimized React Server Component Requests

  • Removed undefined props from React Server Component requests to reduce overall HTML bloat. Previously, undefined props were still being sent through requests as $undefined and now they are explicitly omitted.
  • Removed i18n.supportedLanguages from the client config, which is a potentially large object that does not need to be sent through the network when making RSC requests.

More Efficient Access Control

The /api/access endpoint now returns significantly smaller payloads by omitting unnecessary permission data, only including truthy access results, and consolidating nested permissions when possible.

Impact Summary

This release brings significant improvements to Payload CMS with a focus on MongoDB compatibility, performance optimization, and type safety. The most impactful change is the upgrade to Mongoose 8.8.1, which requires MongoDB users to run a migration to convert relationship IDs from strings to ObjectIDs. This change improves compatibility with MongoDB Atlas and modern MongoDB features.

Performance optimizations for React Server Components will result in smaller network payloads and faster rendering, particularly for complex forms and internationalized content. The secured access endpoint provides better protection against potential information leakage while reducing response sizes.

Several UI improvements enhance the content editing experience, including reduced layout shifts when submitting forms, tooltips for toolbar dropdown items in the rich text editor, and visual indicators for links that open in new tabs.

The breaking changes in this release primarily affect developers who use custom components or directly interact with the database. The reordered generics in DefaultCellComponentProps, updated UploadThing configuration, and improved type safety for collection slugs will require code changes but lead to more robust applications in the long run.

Overall, this release represents a significant step forward in Payload's MongoDB support, performance, and developer experience, though it requires careful attention during the upgrade process.

Full Release Notes

v3.0.0-beta.131 (2024-11-15)

🚀 Features

  • sanitise access endpoint (#7335) (26ffbca)
  • bumps date-fns to 4.1.0 (#9221) (6845878)
  • re-order DefaultCellComponentProps generics (#9207) (77c99c2)
  • db-mongodb: update mongoose to 8.8.1 (#9115) (7c6f419)
  • db-mongodb: support query options in db update operations (#9191) (2d2d020)
  • richtext-lexical: add tooltips to toolbar dropdown items (#9218) (7294880)
  • richtext-lexical, ui: add icon if link opens in new tab (#9211) (82e72fa)
  • storage-uploadthing: upgrade to v7 (#8346) (4690cd8)

⚡ Performance

  • removes undefined props from rsc requests (#9195) (2d7626c)
  • removes i18n.supportedLanguages from client config (#9209) (5482e7e)

🐛 Bug Fixes

  • improve collection / global slugs type-safety in various places (#8311) (810c29b)
  • duplicate list preferences stored (#9185) (a5cae07)
  • wires up abort controller logic for list columns (#9180) (129fadf)
  • ui: jumping hasmany uploads when form is submitting or in readonly mode (#9198) (315b4e5)
  • ui: fixes layout shift when form is submitted (#9184) (e6d0443)

⚠️ BREAKING CHANGES

  • db-mongodb: update mongoose to 8.8.1 (#9115) (7c6f419)

    MongoDB projects need to run a migration after updating to this beta version, because all relationship IDs are now stored as ObjectID (as they should have always been saved) and we need to migrate your existing relationship data from string-based IDs to ObjectIDs.

    To create this migration, run:

    pnpm payload migrate:create --file @payloadcms/db-mongodb/relationships-v2-v3
    

    And then run your migrations using:

    pnpm payload migrate
    

    In addition, if your project is heavily relying on using the Mongoose models directly, you may want to review the upgrade guides from v6 to v7 and v7 to v8, making
    adjustments as needed.

  • bumps date-fns to 4.1.0 (#9221) (6845878)

  • improve collection / global slugs type-safety in various places (#8311) (810c29b)

    Improves type-safety of collection / global slugs by using CollectionSlug / UploadCollectionSlug and GlobalSlug types instead of string in these places:
    Adds UploadCollectionSlug and TypedUploadCollection utility types

    This also changes how we suggest to add an upload collection to a cloud-storage adapter:
    Before:

    azureStorage({
      collections: {
        [Media.slug]: true,
      },
    })

    After:

    azureStorage({
      collections: {
        media: true,
      },
    })
  • re-order DefaultCellComponentProps generics (#9207) (77c99c2)

    Changes the order of the DefaultCellComponentProps generic type,
    allowing us to infer the type of cellData when a ClientField type is
    passed as the first generic argument. You can override the cellData type
    by passing the second generic.

    Previously:

    type DefaultCellComponentProps<TCellData = any, TField extends ClientField = ClientField>

    New:

    type DefaultCellComponentProps<TField extends ClientField = ClientField, TCellData = undefined>

    You can override the cellData type by passing in the second argument
    to the generic. ie if you know the shape of your data differs than the
    inferred type then you can do something like:

    DefaultCellComponentProps<RelationshipFieldClient, { myShape: string, here: string }>
  • storage-uploadthing: upgrade to v7 (#8346) (4690cd8)

    Upgrade uploadthing to v7

    The options that can be passed to the plugin now mirror the
    UTApiOptions of v7.

    The most notable change is to pass token with
    process.env.UPLOADTHING_TOKEN instead of apiKey with
    process.env.UPLOADTHING_SECRET.

    options: {
    - apiKey: process.env.UPLOADTHING_SECRET,
    + token: process.env.UPLOADTHING_TOKEN,
      acl: 'public-read',
    },

Statistics:

File Changed266
Line Additions11,788
Line Deletions10,474
Line Changes22,262
Total Commits32

User Affected:

  • Must run a migration to convert relationship IDs from strings to ObjectIDs
  • Need to review Mongoose upgrade guides if directly using Mongoose models
  • Will benefit from improved MongoDB compatibility with Atlas

Contributors:

jacobsfletchJarrodMFleschDanRibbensdenolfer1tsuujmikrutpaulpopusfranciscolourencoOrtimisAlessioGrGermanJabloPatrikKozakakhrarovsaid