Home

>

Tools

>

Payload CMS

>

Releases

>

3.0.0-beta.128

Payload CMS Release: 3.0.0-beta.128

Pre Release

Tag Name: v3.0.0-beta.128

Release Date: 11/12/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

PayloadCMS v3.0.0-beta.128 introduces a major overhaul to the way custom React components are rendered in the Admin UI. Now, server components receive contextual props like data and value, enabling more powerful server-side functionality. The release also includes significant performance improvements, MongoDB collection naming enhancements, deep querying for JSON/rich text fields in Postgres, and an upgrade to Lexical 0.20.0. Several breaking changes require updates to your layout file and handling of server functions.

Highlight of the Release

    • On-demand React Server Components for more contextual and efficient rendering
    • Deep querying on JSON and rich text fields in PostgreSQL
    • MongoDB collection naming improvements with proper dbName usage
    • Lexical rich text editor upgraded to version 0.20.0
    • Performance improvements reducing bundle size and dependencies
    • Enhanced relationship field displays showing document titles

Migration Guide

Migrating to On-demand RSC

  1. Update your root layout file (typically at (app)/(payload)/layout.tsx):
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
+ import type { ServerFunctionClient } from 'payload'

import config from '@payload-config'
import { RootLayout } from '@payloadcms/next/layouts'
+ import { handleServerFunctions } from '@payloadcms/next/utilities'
import React from 'react'

import { importMap } from './admin/importMap.js'
import './custom.scss'

type Args = {
  children: React.ReactNode
}

+ const serverFunctions: ServerFunctionClient = async function (args) {
+  'use server'
+  return handleServerFunctions({
+    ...args,
+    config,
+    importMap,
+  })
+ }

const Layout = ({ children }: Args) => (
  <RootLayout
    config={config}
    importMap={importMap}
+    serverFunctions={serverFunctions}
  >
    {children}
  </RootLayout>
)

export default Layout
  1. If you were using the /api/form-state endpoint, update to the new server function approach:
- import { getFormState } from '@payloadcms/ui'
- const { state } = await getFormState({
-   apiRoute: '',
-   body: {
-     // ...
-   },
-   serverURL: ''
- })

+ const { getFormState } = useServerFunctions()
+
+ const { state } = await getFormState({
+   // ...
+ })
  1. Replace removed hooks with direct prop access:
- const { path } = useFieldProps();
+ const { path } = props;

- const { cellData } = useTableCell();
+ const { cellData } = props;

- const { _schemaPath } = props.field
+ const { schemaPath } = props

MongoDB Collection Naming

If you're using MongoDB and have defined dbName properties on your collections, be aware that these will now be used as the actual MongoDB collection names instead of the collection slug. Additionally, autoPluralization will not be applied to collections with a defined dbName.

Lexical Rich Text Editor

If you're using the Lexical rich text editor, update your dependencies from 0.18.0 to 0.20.0. Check the Lexical changelog for any breaking changes if you're using Lexical APIs directly.

Upgrade Recommendations

This is a significant beta release with several breaking changes, but the improvements to React Server Components and performance make it worthwhile for most users.

Priority: Medium-High

Who should upgrade immediately:

  • Teams building complex admin UIs with custom components that need contextual data
  • PostgreSQL users who need deep querying on JSON fields
  • MongoDB users who want proper collection naming with dbName
  • Anyone experiencing the specific bugs fixed in this release

Who can wait:

  • Production environments that cannot tolerate breaking changes right now
  • Teams without custom server components or complex admin UI customizations

Upgrade Difficulty: Moderate - requires code changes to layout files and potentially to custom components

Follow the migration guide carefully, especially regarding the changes to the root layout file and server functions. Test thoroughly after upgrading, particularly if you have custom components or are using MongoDB with dbName properties.

Bug Fixes

UI Fixes

  • Fixed empty publish dropdown when localization is disabled
  • Fixed custom ID field not showing depending on field and database types
  • Fixed error in filtered relationship field component when scrolling if the select option label is a number
  • Fixed incorrect relationTo being passed to locked documents creation
  • Fixed issue with document locking not respecting user access

Database Fixes

  • Fixed destructuring error when trying to filter date fields by string query in MongoDB
  • Fixed schema path lookup when upload is not enabled

Other Fixes

  • Fixed issue with queue specification in job queues
  • Fixed Turbopack serverExternalPackages warnings in Next.js
  • Fixed proper branch tag usage in CPA
  • Fixed README asset URLs

New Features

On-demand React Server Components

The most significant change in this release is the overhaul of how custom React components are rendered in the Admin UI. Previously, all custom components were rendered on initial compile without contextual data. Now, components are rendered on-demand as they're needed, receiving proper contextual props like data and value. This enables much more powerful server-side functionality.

Deep Querying for PostgreSQL JSON Fields

PostgreSQL users can now query JSON and rich text fields with any nesting level, similar to MongoDB. This utilizes the jsonb_path_exists PostgreSQL function to enable complex queries like:

payload.find({
  collection: 'json-fields',
  where: {
    'json.array.object.text': {
      equals: 'deep-text',
    }
  }
})

Enhanced Relationship Field Display

Relationship fields now show the document title in popup links instead of just the collection name. For example, instead of just showing "Linked to Users", it will display the actual document title based on the useAsTitle field.

MongoDB Collection Naming Improvements

The dbName property is now properly used as the MongoDB collection name instead of just for versions. Additionally, autoPluralization is disabled for collections with a defined dbName, making the behavior more consistent and aligned with documentation.

New Template: with-vercel-website

A new template has been added that uses the website template as a base, optimized for Vercel deployment.

Mongoose Index Ensuring

Added an ensureIndexes option to the Mongoose adapter, which ensures indexes are ready prior to completing connection.

Security Updates

No specific security fixes were mentioned in this release.

Performance Improvements

Bundle Size Reduction

Upgraded pino-pretty, which reduced the bundle size and total number of dependencies from 94 to 85, making the application lighter and faster to load.

On-demand Component Rendering

The new on-demand RSC (React Server Components) approach significantly improves performance by only rendering components when they're needed, rather than pre-rendering all components during initial compile. This reduces unnecessary server-side rendering and improves the overall responsiveness of the admin panel.

Abort Controller Logic Improvements

Improved abort controller logic for server functions to prevent different fetches from accidentally canceling each other. Previously, abort controllers were shared globally inside the server actions provider, causing issues when two components called server functions.

Impact Summary

This release represents a significant architectural improvement to PayloadCMS's admin panel rendering system. By moving to on-demand React Server Components, the CMS now provides contextual data to custom components and improves performance by only rendering components when needed.

The most impactful changes are:

  1. On-demand RSC: Custom server components now receive contextual props like data and value, enabling much more powerful server-side functionality. This is a breaking change requiring updates to your layout file and potentially to custom components.

  2. MongoDB Collection Naming: The dbName property is now properly used as the actual MongoDB collection name, which may affect existing applications that rely on the previous behavior.

  3. PostgreSQL Deep Querying: PostgreSQL users gain the ability to perform deep queries on JSON and rich text fields with any nesting level, similar to MongoDB.

  4. Lexical Upgrade: The rich text editor has been upgraded from 0.18.0 to 0.20.0, which may introduce breaking changes for users who interact directly with Lexical APIs.

  5. Performance Improvements: Bundle size reduction and more efficient rendering improve the overall performance of the admin panel.

These changes collectively make PayloadCMS more powerful and efficient, particularly for developers building complex admin UIs with custom components. The breaking changes are relatively straightforward to address following the migration guide.

Full Release Notes

v3.0.0-beta.128 (2024-11-12)

This is a significant release which overhauls the way that we render, and provide, custom React components to the Payload Admin UI. Now, custom server components receive contextual props, like data and value, so you can do considerably more with them on the server.

It also ships with a variety of performance improvements to the server-side rendering done for the admin panel.

There are a few relatively simple breaking changes outlined below.

šŸš€ Features

  • adds option to mongoose to ensure indexes (#9155) (6bb4067)
  • on demand rsc (#8364) (c96fa61)
  • db-postgres: deep querying on json and rich text fields (#9102) (b878daf)
  • docs: add example for customising the filename of an upload via hooks (#9124) (d839138)
  • richtext-lexical: add useAsTitle to the popup links label (#8718) (23907e4)
  • richtext-lexical: backport relevant from lexical playground between 0.18.0 and 0.20.0 (#9129) (a30eeaf)
  • richtext-lexical: upgrade lexical from 0.18.0 to 0.20.0 (#9126) (7767c94)
  • templates: add with-vercel-website (#9144) (def595e)

⚔ Performance

  • upgrade pino-pretty. This reduces bundle size and total amount of dependencies from 94 => 85 (#9127) (7261faa)

šŸ› Bug Fixes

  • allow specifying queue (#9151) (e0309a1)
  • incorrectly looking for schema paths when upload is not enabled (#9146) (a3ebf51)
  • empty publish dropdown when localization is false (#9106) (3e954f4)
  • custom id field not shown depending on field and db types (#9091) (9a970d2)
  • update README with new asset, image URL (#9099) (d7fc944)
  • cpa: use proper branch tag (#9141) (7cd805a)
  • db-mongodb: use dbName for mongodb model (#9107) (09c41d5)
  • db-mongodb: destructuring error when trying to filter date fields by string query (#9116) (6899a3c)
  • next: disable turbopack serverExternalPackages warnings (#9147) (64967e4)
  • next, ui: respect access of user for document locking (#9139) (48d0fae)
  • ui: pass correct relationTo to locked documents creation (#9137) (3298113)
  • ui: error in filtered relationship field component while scrolling, if the select option label is a number (#9117) (2ad9917)

āš ļø BREAKING CHANGES

  • on-demand rsc (#8364) (c96fa61)

    1. Add the following to your root layout file, typically located at (app)/(payload)/layout.tsx:

      /* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
      /* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
      + import type { ServerFunctionClient } from 'payload'
      
      import config from '@payload-config'
      - import { RootLayout } from '@payloadcms/next/layouts'
      + import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
      import React from 'react'
      
      import { importMap } from './admin/importMap.js'
      import './custom.scss'
      
      type Args = {
        children: React.ReactNode
      }
      
      + const serverFunction: ServerFunctionClient = async function (args) {
      +  'use server'
      +  return handleServerFunctions({
      +    ...args,
      +    config,
      +    importMap,
      +  })
      + }
      
      const Layout = ({ children }: Args) => (
        <RootLayout
          config={config}
          importMap={importMap}
      +    serverFunction={serverFunction}
        >
          {children}
        </RootLayout>
      )
      
      export default Layout
    2. If you were previously posting to the /api/form-state endpoint, it
      no longer exists. Instead, you'll need to invoke the form-state Server
      Function, which can be done through the new getFormState utility:

      - import { getFormState } from '@payloadcms/ui'
      - const { state } = await getFormState({
      -   apiRoute: '',
      -   body: {
      -     // ...
      -   },
      -   serverURL: ''
      - })
      
      + const { getFormState } = useServerFunctions()
      +
      + const { state } = await getFormState({
      +   // ...
      + })
    3. Multiple layer of React Context were removed in favor of direct props. As a result, the following React hooks were removed:

      - useFieldProps()
      - useTableCell()

      If you were previously using any of these hooks, for example to access field path or cellData, you can now access that directly from the props object.

      - const { path } = useFieldProps();
      + const { path } = props;
      
      - const { cellData } = useTableCell();
      + const { cellData } = props;

      The field prop also no longer contains a _schemaPath property. Instead, this is now also accessed directly through props:

      - const { _schemaPath } = props.field
      + const { schemaPath } = props
  • db-mongodb: use dbName for mongodb model (#9107) (09c41d5)

    If a dbName was previously provided, it will now be used as the
    MongoDB collection name instead of the collection slug.
    autoPluralization will not be applied to dbName.

  • richtext-lexical: upgrade lexical from 0.18.0 to 0.20.0 (#9126) (7767c94)

    This upgrades our lexical dependencies from 0.18.0 to 0.20.0. If you
    have lexical dependencies installed in your project, you will have to
    upgrade those.

    Additionally, the lexical team may introduce breaking changes in this
    upgrade. If you use lexical APIs directly, please consult their
    changelog for more information:
    https://github.com/facebook/lexical/releases

šŸ¤ Contributors

Statistics:

File Changed300
Line Additions8,372
Line Deletions5,435
Line Changes13,807
Total Commits38

User Affected:

  • Need to update their root layout file to support the new on-demand RSC pattern
  • Must update code that previously used `/api/form-state` endpoint to use the new server function approach
  • Need to replace removed hooks like `useFieldProps()` and `useTableCell()` with direct prop access
  • Should update Lexical dependencies if using the rich text editor

Contributors:

ncaminatapaulpopusdenolfejessrynkarjacobsfletchJarrodMFleschAlessioGrGermanJablor1tsuuPatrikKozakjmikruttak-amboss