made with
payload
  • Showcases
  • Plugins
  • Creators
  • Tutorials
  • Templates
  • Videos

Not affiliated with PayloadCMS. Made by paul

  • Contact
  • Submit an entry
  • Releases
  • Stats
Back to Releases

v3.60.0

Version v3.60.0Minor Release
Released:

October 16, 2025

Type:

New features, backward compatible

GitHub:View Release
Download TarballDownload ZIP

Release Notes

v3.60.0 (2025-10-16)

๐Ÿš€ Features

  • accept multiple locales in fallbackLocale (#13822) (623a1b8)
  • adds settingsMenu to admin navigation sidebar (#14139) (ee8b3cf)
  • plugin-multi-tenant: allow collection access to be overridden via callback (#14127) (c40eec2)
  • plugin-multi-tenant: allow hasMany on tenant field overrides (#14120) (fb93cd1)
  • plugin-multi-tenant: user collection access overrides (#14119) (38b7a60)
  • richtext-lexical: add collection filtering to UploadFeature, refactor relationship hooks (#14111) (6defba9)
  • richtext-lexical: client-side block markdown shortcuts, code block (#13813) (07a1eff) Localization
  • Multiple fallback locales - fallbackLocale now accepts an array of locales for queries and locale configs. Payload will check each locale in order until finding a value, eliminating the need for manual fallback handling. #13822
    /** Local API **/
    await payload.findByID({
    id,
    collection,
    locale: 'en',
    fallbackLocale: ['fr', 'es'],
    })
    /** REST API **/
    await fetch(`${baseURL}/api/${collectionSlug}?locale=en&fallbackLocale[]=fr&fallbackLocale[]=es`)
    /** GraphQL **/
    await restClient.GRAPHQL_POST({
    body,
    query: { locale: 'en', fallbackLocale: ['fr', 'es']},
    })
    /** Locale Configs **/
    locales: [
    {
    code: 'en',
    label: 'English',
    fallbackLocale: ['fr', 'es'],
    },
    ]
    ts

Admin UI

  • Settings menu in navigation - New admin.components.settingsMenu config option adds a gear icon above the logout button. Click to open a popup menu with custom admin-level utilities and actions that don't fit into collection or global navigation. #14139
    Image from GitHub release

    Multi-Tenant Plugin
  • Collection access overrides - New accessResultOverride callback allows modifying multi-tenant access control results per operation (read, create, update, delete, readVersions, unlock). Enables custom logic like allowing shared content across tenants. #14127
    multiTenantPlugin<ConfigType>({
    collections: {
    posts: {
    accessResultOverride: async ({ accessResult, accessKey, req }) => {
    // here is where you can change the access result or return something entirely different
    if (accessKey === 'read') {
    return {
    or: [
    {
    isShared: {
    equals: true,
    }
    },
    accessResult
    ]
    }
    } else {
    return accessResult
    }
    }
    }
    }
    })
    ts
  • Multiple tenants per document - Tenant field overrides now support hasMany relationships, allowing documents to belong to multiple tenants. #14120
  • User collection access overrides - New usersAccessResultOverride callback enables customizing access control on the users collection, overriding default tenant privacy when needed. #14119
    usersAccessResultOverride: ({
    accessKey: 'read', // 'create', 'read', 'update', 'delete', 'readVersions', 'unlock'
    accessResult: AccessResult, // the `AccessResult` type
    ...args, // AccessArgs
    }) => {
    // this is where you could adjust what gets returned here.
    if (accessKey === 'read') {
    return true // over simplified example
    }
    // default to returning the result from the plugin
    return accessResult
    }
    ts

Lexical Rich Text

  • Upload collection filtering - UploadFeature now supports disabledCollections and enabledCollections to control which collections appear in the upload drawer. Also refactors enabled relationships logic with cleaner useEnabledRelationships hook. #14111
  • Client-side markdown shortcuts & code blocks - Blocks with admin.jsx now support markdown shortcuts on the client (previously server-only). Includes pre-made CodeBlock component for use in BlocksFeature. Also fixes readOnly handling across nested fields. #13813 <https://github.com/user-attachments/assets/cfc0d2a8-ffb3-4926-b097-ad9c2b133586>

๐Ÿ› Bug Fixes

  • findDistinct by explicit ID paths in relationships and virtual fields (#14215) (2b1b6ee)
  • hasMany / polymorphic relationships to custom number IDs (#14201) (a3b3865)
  • hide fields with read: false in list view columns, filters, and groupBy (#14118) (bcd40b6)
  • validate Point Field to -180 to 180 for longitude and -90 to 90 for latitude (#14206) (13a1d90)
  • urls in upload sizes are not encoded (#14205) (747a049)
  • restoring trashed drafts with empty required fields fails validation (#14186) (3317207)
  • db-d1-sqlite: add missing blocksAsJSON property (#14103) (f14a38e)
  • db-mongodb: documents not showing in folders with useJoinAggregations: false (#14155) (e613a78)
  • db-mongodb: improve check for ObjectId (#14131) (32e2be1)
  • graphql: bump tsx version to get around esbuild vulnerability (#14207) (d7ec48f)
  • next: custom views not overriding built-in single-segment routes (#14066) (691f810)
  • plugin-multi-tenant: object reference mutations in addFilterOptionsToFields (#14150) (e62f1fe)
  • richtext-lexical: state key collisions when multiple TextStateFeatures are registered (#14194) (f01a6ed)
  • richtext-lexical: editor throws an error if OrderedList is registered but not UnorderedList or CheckList (#14149) (1fe75e0)
  • richtext-lexical: editing a copied inline block also modifies the original (#14137) (5bacb38)
  • richtext-lexical: correctly type field property of RenderLexical (#14141) (cd94f8e)
  • richtext-lexical: improve type autocomplete and assignability for lexical nodes (#14112) (a46faf1)
  • sdk: pagination is not passed to search params (#14126) (ee9f160)
  • storage-gcs: bump @google-cloud/storage for vulnerability (#14199) (1077aa7)
  • storage-r2: uploads with prefix don't work, add test/storage-r2 (#14132) (4fd4cb0)
  • templates: encoding and decoding slugs in website template (#14216) (cacf523)
  • templates: ecommerce seeding issue (#14196) (d65b8c6)

๐Ÿ›  Refactors

  • richtext-lexical: add jsdoc to deprecated HTMLConverterFeature (#14193) (0b718bd)

๐Ÿ“š Documentation

  • revert sentry docs change (#14113) (8844eaf)
  • incorrect pg driver injection example in Sentry integration docs (#14088) (95dbaed)

๐Ÿงช Tests

  • allows running Jest tests through Test Explorer in VSCode and other improvements (#13751) (0d92a43)

โš™๏ธ CI

  • notify website repo on release [skip ci] (#14140) (a36e5d2)
  • add website dispatch event, testing for releases [skip ci] (#14138) (b0d31ba)
  • add missing labels to bug report template [skip ci] (#14134) (3069e5b)
  • update generate-template-variations script to cover cloudflare template (#14105) (e78057b)

๐Ÿก Chores

  • better audit dependencies script (#14189) (f9e75a4)
  • ignore agent local files [skip ci] (#14184) (7ecb5a0)
  • drizzle: bump drizzle-orm and drizzle-kit for vulnerabilities (#14200) (4afa286)
  • email-nodemailer: bump nodemailer dependencies to latest (#14121) (077c6f5)

๐Ÿค Contributors

  • Sasha (@r1tsuu)
  • Patrik (@PatrikKozak)
  • Paul (@paulpopus)
  • Jessica Rynkar (@jessrynkar)
  • German Jablonski (@GermanJablo)
  • Elliot DeNolf (@denolfe)
  • Elliott W (@elliott-w)
  • Jarrod Flesch (@JarrodMFlesch)
  • Alessio Gravili (@AlessioGr)
  • Diogo Gaspar (@shadowoff09)
Browse All ReleasesView on GitHub