Payload CMS Release: 3.40.0

Tag Name: v3.40.0

Release Date: 5/29/2025

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.40.0 introduces significant enhancements to field filtering, folder management, and authentication strategies. This release includes new features like select field filtering options, query preset constraints, and improved folder view performance. It also addresses numerous UI fixes for Safari rendering issues, textarea descriptions, and relationship fields. Translation improvements for Norwegian, Spanish, and Dutch have been implemented, along with critical bug fixes for database operations and cookie handling.

Highlight of the Release

    • Dynamic filtering for select field options based on user roles or document data
    • Improved folder view performance with optimized image loading
    • Enhanced query preset constraints with filtering capabilities
    • Better authentication strategies with new canSetHeaders property
    • Nested fields in named tabs now appear as separate columns in list views
    • Improved translations for Norwegian, Spanish, and Dutch

Migration Guide

Upgrading to v3.40.0

This release doesn't contain breaking changes, so upgrading should be straightforward. However, there are a few things to be aware of:

Select Field Filtering

If you're using select fields and want to take advantage of the new filterOptions property, you can update your field configurations:

// Before
{
  name: 'select',
  type: 'select',
  options: [
    { label: 'One', value: 'one' },
    { label: 'Two', value: 'two' },
    { label: 'Three', value: 'three' },
  ],
  validate: (value, { data }) => {
    if (data.disallowOption1 && value === 'one') {
      return 'This option is not allowed';
    }
    return true;
  }
}

// After
{
  name: 'select',
  type: 'select',
  options: [
    { label: 'One', value: 'one' },
    { label: 'Two', value: 'two' },
    { label: 'Three', value: 'three' },
  ],
  filterOptions: ({ options, data }) =>
    data.disallowOption1
      ? options.filter(
          (option) => (typeof option === 'string' ? options : option.value) !== 'one',
        )
      : options,
}

Query Preset Constraints

If you're using query presets and want to restrict who can change constraints, add the new filterConstraints property to your configuration:

import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  queryPresets: {
    // existing configuration...
    filterConstraints: ({ req, options }) =>
      !req.user?.roles?.includes('admin')
        ? options.filter(
            (option) =>
              (typeof option === 'string' ? option : option.value) !==
              'everyone',
          )
        : options,
  },
})

Authentication Strategies

If you've created custom authentication strategies, consider implementing the new canSetHeaders property to improve compatibility with Next.js server components:

// Example implementation
{
  name: 'myCustomStrategy',
  // other properties...
  canSetHeaders: ({ req }) => {
    // Determine if this strategy can set headers in the current context
    return !req.headers.get('next-url');
  }
}

Upgrade Recommendations

We recommend upgrading to v3.40.0 as soon as possible to benefit from the numerous bug fixes, performance improvements, and new features. This release is particularly valuable if you:

  1. Use select fields and need dynamic filtering capabilities
  2. Work with folder views and want improved performance
  3. Need better control over query preset constraints
  4. Have experienced any of the specific bugs that were fixed

The upgrade process should be straightforward as there are no breaking changes. Simply update your package.json and run your package manager's install command:

# For npm
npm install [email protected]

# For yarn
yarn add [email protected]

# For pnpm
pnpm add [email protected]

After upgrading, test your application thoroughly, especially if you're using features that received significant updates like folder views, select fields, or authentication strategies.

Bug Fixes

Database Operations

  • Fixed migrate:reset executing migrations in the wrong order
  • Properly escaped the ' character in Postgres default values
  • Disabled database connection for payload migrate:create command
  • Fixed exists query on checkbox fields in MongoDB

UI Improvements

  • Fixed Safari CSS rendering issues with tables and folder cards
  • Prevented textarea descriptions from overlapping fields and now properly honoring rows attribute
  • Fixed CloudFront removing X-HTTP-Method-Override header
  • Ensured live-preview-tab shows beforeDocumentControls
  • Fixed filtering on hasMany fields
  • Reduced pill sizing in autosave cells and column selectors
  • Fixed index-based IDs without useAsTitle breaking folders
  • Replaced CSS function with CSS calc for better compatibility
  • Fixed issue where only files/folders added to the current folder should appear in grid/list views

Rich Text Editor

  • Fixed opening relationship fields with appearance: "drawer" inside rich text inline blocks
  • Added respect for disableBlockName property in Lexical rich text editor

Folder Management

  • Made browseByFolder route optional
  • Fixed thread req into internal folder payload operations
  • Fixed delete subfolders hook with relational databases
  • Fixed folder redirects not working in Next.js

Cookie Handling

  • Improved parseCookies to ignore invalid encoded values
  • Refactored to use parseCookies method from Next.js for better compatibility

Infinite Loop Fix

  • Fixed infinite loop in findUp utility when a result is not found, which could hang the entire application

Storage

  • Fixed client uploads with a prefix in Vercel Blob storage

Templates and Examples

  • Updated template/plugin and fixed import map issue
  • Updated live-preview example to ESM
  • Fixed read permission in auth example
  • Removed unused imports from custom server example

New Features

Dynamic Select Field Filtering

Select fields now support dynamic filtering of options based on various criteria such as user roles or document data. This powerful feature allows you to:

  • Restrict options based on a user's role (e.g., admin-only options)
  • Display different options based on the value of another field (e.g., city/state selectors)
  • Dynamically adjust available options based on document context

Implementation is straightforward with the new filterOptions property:

{
  name: 'select',
  type: 'select',
  options: [
    { label: 'One', value: 'one' },
    { label: 'Two', value: 'two' },
    { label: 'Three', value: 'three' },
  ],
  filterOptions: ({ options, data }) =>
    data.disallowOption1
      ? options.filter(
          (option) => (typeof option === 'string' ? options : option.value) !== 'one',
        )
      : options,
}

Query Preset Constraints Filtering

You can now specify exactly who can change constraints within a query preset. This allows for fine-grained control over preset modifications:

import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  queryPresets: {
    // ...
    filterConstraints: ({ req, options }) =>
      !req.user?.roles?.includes('admin')
        ? options.filter(
            (option) =>
              (typeof option === 'string' ? option : option.value) !==
              'everyone',
          )
        : options,
  },
})

Enhanced Authentication Strategies

A new canSetHeaders property has been added to authentication strategies, allowing developers to determine if an auth strategy can set response headers. This is particularly useful for Next.js server components where setting headers isn't possible.

Nested Fields in Named Tabs as List Columns

Fields nested inside named tabs can now appear as separate columns in the list view when moveSubFieldsToTop is enabled. This improves visibility of important data without requiring users to open individual documents.

Before and After Operation Hooks for resetPassword

The resetPassword operation now supports before and after operation hooks, providing more control over the password reset flow.

Safe Redirect Utility

The getSafeRedirect utility has been moved into the payload package, making it easier to implement secure redirects in your applications.

Field Action Type Export

The FieldAction type is now exported, allowing for better TypeScript integration when working with custom field actions.

Security Updates

This release includes an important security improvement with the addition of the getSafeRedirect utility to the payload package. This utility helps prevent open redirect vulnerabilities by ensuring that redirect URLs are properly validated before being used.

Additionally, the improvements to cookie handling with the refactored parseCookies method enhance security by properly handling cookie values and preventing potential issues with malformed cookies.

Performance Improvements

Optimized Folder View Image Loading

Folder views now download only the images needed and get the best fit from available image sizes. This significantly improves loading performance when browsing folders with many images, reducing bandwidth usage and speeding up the user experience.

The optimization works by:

  1. Only downloading images that are actually needed for the current view
  2. Selecting the most appropriate image size based on the display requirements
  3. Avoiding unnecessary high-resolution downloads for thumbnail displays

This change is particularly beneficial for users with slower connections or when working with folders containing numerous high-resolution images.

Impact Summary

Payload CMS v3.40.0 delivers substantial improvements across multiple areas of the platform, making it a recommended upgrade for all users.

The introduction of dynamic select field filtering addresses a common need for context-aware option presentation, eliminating the need for custom components in many scenarios. This feature alone will significantly improve developer experience and end-user interfaces by ensuring only relevant options are displayed.

Folder management has received considerable attention with multiple bug fixes and performance optimizations. The improved image loading in folder views will be particularly noticeable for content editors working with media-heavy sites.

Authentication and security enhancements provide developers with more control over header management and redirects, which is especially valuable for Next.js applications. The addition of operation hooks to resetPassword offers greater flexibility for implementing custom password reset workflows.

UI improvements address various rendering issues across browsers, with special attention to Safari compatibility. These fixes ensure a consistent experience regardless of the user's browser choice.

The internationalization improvements for Norwegian, Spanish, and Dutch translations demonstrate Payload's commitment to serving a global user base with accurate, culturally appropriate terminology.

Overall, this release balances new features with important refinements to existing functionality, resulting in a more robust, performant, and user-friendly CMS.

Full Release Notes

v3.40.0 (2025-05-29)

🚀 Features

🐛 Bug Fixes

  • parseCookies ignore invalid encoded values (#12515) (bfdcb51)
  • improve translation script prompt and fix some incorrectly used terms in spanish and dutch (#12548) (1731dd7)
  • browseByFolder route should be optional (#12527) (c010d51)
  • thread req into interal folder payload operations (#12523) (64443d8)
  • infinite loop in findUp utility when a result is not found (#12457) (842d184)
  • delete subfolders hook with relational databases (#12507) (45f4c5c)
  • db-*: disable DB connection for payload migrate:create (#12596) (12395e4)
  • db-*: migrate:reset executes in a wrong order (#12445) (1b1e36e)
  • db-mongodb: exists query on checkbox fields (#12567) (f2b6c4a)
  • db-postgres: properly escape the ' character (#12590) (6888f13)
  • examples: update live-preview example to ESM (#12570) (d6f6b05)
  • next: folder redirects not working (#12509) (bc43982)
  • richtext-lexical: respect disableBlockName (#12597) (ca26402)
  • richtext-lexical, ui: opening relationship field with appearance: "drawer" inside rich text inline block (#12529) (f2b54b5)
  • storage-vercel-blob: client uploads with a prefix (#12559) (b61ef13)
  • templates: update template/plugin and fix import map issue (#12305) (68ba24d)
  • translations: improve Spanish translations (#12555) (8a7ac78)
  • translations: correct Norwegian terms for “locale” and language labels (#12557) (bd2571c)
  • ui: reduces pill sizing in autosave cells (#12606) (a17d84e)
  • ui: oversized column selector pills (#12583) (3022cab)
  • ui: filtering on hasMany fields (#12579) (166dafe)
  • ui: prevent textarea description overlapping fields and not honoring rows attribute (#12406) (032375b)
  • ui: cloudfront removing X-HTTP-Method-Override header (#12571) (8448e5b)
  • ui: live-preview-tab should show beforeDocumentControls (#12568) (dfa0974)
  • ui: safari css rendering issues with table and folder cards (#12531) (293cdc1)
  • ui: only and files/folders to the grid/list if they were added to the current folder (#12525) (5a75881)
  • ui: replaces css fn with css calc (#12520) (feeee19)
  • ui: index based ids without useAsTitle breaks folders (#12519) (e9cda1e)

⚡ Performance

  • folder views download only images and get best fit from image sizes (#12514) (11a4a20)

🛠 Refactors

📚 Documentation

📝 Templates

🏡 Chores

🤝 Contributors

Statistics:

File Changed275
Line Additions5,261
Line Deletions3,197
Line Changes8,458
Total Commits48

User Affected:

  • Can now filter select field options dynamically based on user roles or document data
  • Benefit from improved authentication strategies with the new canSetHeaders property
  • Can use the new getSafeRedirect utility for secure redirects
  • Have access to before and after operation hooks in resetPassword
  • Can filter query preset constraints to control who can change them

Contributors:

denolfer1tsuurrelmyjakegrellajacobsfletchJarrodMFleschakhrarovsaidrjgtavDanRibbensanyujandershermansenpaulpopusjessrynkarPatrikKozakzubricksGermanJabloAlessioGralexrahjordanlambrechtjmikrut