Alessio Gravili c337e12896 refactor(richtext-lexical): upgrade lexical to 0.50.0 (3.x) (#18148)
Upgrades `lexical` and every installed `@lexical/*` package from
`0.41.0` to `0.50.0` for Payload 3.x. Updates the dependency pins,
lockfile, and `lexicalTargetVersion`.

Also exposes the 15 React entry points added on main in
[#17554](https://github.com/payloadcms/payload/pull/17554) through
`@payloadcms/richtext-lexical/lexical/react/*`, so custom features can
use these APIs through Payload.

## Breaking changes

**No application changes or data migration are needed when using
Payload's built-in rich text features.**

If you maintain custom rich text features, check that they still compile
and that custom content loads, copies, and pastes correctly. Lexical
removed some older APIs, tightened TypeScript types, and changed how
custom nodes are loaded and copied. Tests that inspect the editor's HTML
may also need updated selectors or snapshots because Lexical adds some
internal markup.

**Do not install `lexical` or `@lexical/*` yourself for use with
Payload.** Remove any direct dependencies you added for the editor and
use Payload's re-exports from `@payloadcms/richtext-lexical/lexical` and
`@payloadcms/richtext-lexical/lexical/*`. Payload supplies the matching
versions; mixing versions can break the editor. This is the existing
[custom feature
requirement](https://payloadcms.com/docs/rich-text/custom-features).

The 3.x Markdown implementation and converter defaults are preserved.
This does not backport the v4 Markdown API changes.

## Breaking changes and Payload migrations

Reviewed
[0.42.0](https://github.com/facebook/lexical/releases/tag/v0.42.0),
[0.43.0](https://github.com/facebook/lexical/releases/tag/v0.43.0),
[0.44.0](https://github.com/facebook/lexical/releases/tag/v0.44.0),
[0.45.0](https://github.com/facebook/lexical/releases/tag/v0.45.0),
[0.46.0](https://github.com/facebook/lexical/releases/tag/v0.46.0),
[0.47.0](https://github.com/facebook/lexical/releases/tag/v0.47.0),
[0.48.0](https://github.com/facebook/lexical/releases/tag/v0.48.0),
[0.49.0](https://github.com/facebook/lexical/releases/tag/v0.49.0),
[0.50.0](https://github.com/facebook/lexical/releases/tag/v0.50.0).
Listed below are breaking API/type changes and behavior changes
explicitly identified as breaking in the release notes. Deprecations and
routine bug fixes are omitted. **Yes** means we had to change Payload
code; **No** means no Payload migration was required.

| Release | Breaking change | Required migration in Payload | Changes
made |
| ------- |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| ----------------------------- |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 0.42 | [Experimental `hasFitNestedTables` moves out of the table
package into the
playground](https://github.com/facebook/lexical/pull/8210). | No | - |
| 0.42 | [The deprecated context-menu plugin is
removed](https://github.com/facebook/lexical/pull/8199). | Yes | Removed
the invalid `LexicalContextMenuPlugin` proxy and package export. Custom
consumers must use
`@payloadcms/richtext-lexical/lexical/react/LexicalNodeContextMenuPlugin`
and adapt to its node-context-menu API. |
| 0.43 | [Nested editors delegate asynchronously to their
parent](https://github.com/facebook/lexical/pull/8308), restoring the
behavior from before 0.42.0. | No | - |
| 0.45 | [`$getReconciledDirection` now inherits direction through
shadow-root nodes](https://github.com/facebook/lexical/pull/8479). | No
| - |
| 0.45 | [Backspace at the start of a non-empty block preserves the
current block type and
formatting](https://github.com/facebook/lexical/pull/8493). | No | - |
| 0.45 | [Moving nodes between parents adjusts selection
offsets](https://github.com/facebook/lexical/pull/8501). | No | - |
| 0.45 | [Markdown shortcuts can trigger when IME composition
commits](https://github.com/facebook/lexical/pull/8503). | No | - |
| 0.45 | [Rich/plain text automatically removes empty inline
elements](https://github.com/facebook/lexical/pull/8497). | No | - |
| 0.45 | [Triple-click selection normalization moves from core into
rich/plain text
registration](https://github.com/facebook/lexical/pull/8520). Editors
bypassing that registration must add
`NormalizeTripleClickSelectionExtension`. | No | - |
| 0.45 | [`DOMSlot` and the DOM rendering override APIs are
generalized](https://github.com/facebook/lexical/pull/8519); playground
`AutocompleteNode` is replaced by `VisibleLineBreakExtension`. | No | -
|
| 0.46 | [`static importJSON` widens its parameter to
`SerializedLexicalNode & Record<string,
unknown>`](https://github.com/payloadcms/payload/pull/17554). Overrides
using serialized interfaces can fail TypeScript checks. | No | - |
| 0.46 | [Node lookups and traversal no longer infer unchecked subclass
types](https://github.com/facebook/lexical/pull/8661). Explicit
unchecked traversal generics are deprecated. | Yes | Removed the upload
drawer’s assumption that a node lookup returns `UploadNode`. Added
`$isUploadNode` before reading or updating upload data. |
| 0.46 | [DOM lookups of the editor root return `RootNode` instead of
`null`](https://github.com/facebook/lexical/pull/8588).
Selection-capture handling is also generalized beyond decorators. | No |
- |
| 0.46 | [`insertNodes` preserves leading line breaks, and managed line
breaks receive a DOM
marker](https://github.com/facebook/lexical/pull/8615). | No | - |
| 0.46 | [Experimental DOM-import rules register through node
extensions](https://github.com/facebook/lexical/pull/8662); the separate
per-package import extensions become deprecated aliases. | No | - |
| 0.46 | [Experimental named slots change the Yjs sync
signature](https://github.com/facebook/lexical/pull/8603):
`syncLexicalUpdateToYjsV2__EXPERIMENTAL` gains a `dirtyLeaves`
parameter. | No | - |
| 0.46 | [Copying an element through `NodeSelection` includes its
children](https://github.com/facebook/lexical/pull/8603), instead of
copying an empty shell. | No | - |
| 0.46 | [Previously deprecated exports are
removed](https://github.com/facebook/lexical/pull/8704): `toggleLink`,
`insertList`, `removeList`, and ContentEditable’s `Props` alias.
Replacements are `$toggleLink`, `$insertList`, `$removeList`, and
`ContentEditableProps`. | No | - |
| 0.47 | [React 17 support is
removed](https://github.com/facebook/lexical/pull/8782); React 18 or
later is required. | No | - |
| 0.47 | [Segmented text temporarily switches to normal mode during IME
composition while keeping its
DOM](https://github.com/facebook/lexical/pull/8784). Subclasses must
tolerate that temporary mode. | No | - |
| 0.49 | [Built-in nodes adopt
`$config()`](https://github.com/facebook/lexical/pull/8640). Direct
static `importJSON`, `importDOM`, `clone`, and `transform`
implementations change; `__type` becomes readonly and automatic node
construction needs zero-argument defaults. Custom static implementations
remain supported. | No | - |
| 0.49 | [`LexicalCommand<T>` checks its payload type more
strictly](https://github.com/facebook/lexical/pull/8877).
`LexicalCommand<unknown>` is no longer a safe catch-all. | Yes | Focus
and blur commands were incorrectly registered with `MouseEvent`. Removed
the explicit types so Lexical infers `FocusEvent`. |
| 0.50 | [Named-slot values cannot be replaced with
`LexicalNode.replace()`](https://github.com/facebook/lexical/pull/8938).
Block converters also [skip slot
values](https://github.com/facebook/lexical/pull/8905). | No | - |
| 0.50 | [Lexical JSON clipboard copying checks
`excludeFromCopy('clone')`, not
`'html'`](https://github.com/facebook/lexical/pull/8995). | No | - |

Also updated the copied table action menu for merged-cell bounds, header
toggles, and merge/unmerge selection, and fixed the upload alignment
test’s image selector. Formatting and diff checks pass for the upload
selector fix.

Verified all 15 new entry points through source and published export
maps with runtime imports and TypeScript checks. ESLint and formatting
checks pass.

## Previous Lexical upgrades

- [#15760](https://github.com/payloadcms/payload/pull/15760) — 0.35.0 →
0.41.0
- [#13715](https://github.com/payloadcms/payload/pull/13715) — 0.34.0 →
0.35.0
- [#13622](https://github.com/payloadcms/payload/pull/13622) — 0.28.0 →
0.34.0
2026-09-11 16:01:50 -04:00
2024-08-16 15:22:56 -04:00
2024-08-13 12:54:33 -04:00
2026-07-01 13:42:19 -07:00
2026-09-10 10:49:00 -04:00
2025-12-19 16:07:14 -05:00

Payload headless CMS Admin panel built with React

GitHub Workflow Status   Discord   npm   npm   npm   Payload Twitter


Explore the Docs · Community Help · Roadmap · View G2 Reviews


Important

Star this repo or keep an eye on it to follow along.

Payload is the first-ever Next.js native CMS that can install directly in your existing /app folder. It's the start of a new era for headless CMS.

Benefits over a regular CMS

  • It's both an app framework & headless CMS
  • Deploy anywhere, including serverless on Vercel for free
  • Combine your front+backend in the same /app folder if you want
  • Don't sign up for yet another SaaS - Payload is open source
  • Query your database in React Server Components
  • Both admin and backend are 100% extensible
  • No vendor lock-in
  • Never touch ancient WP code again
  • Build faster, never hit a roadblock

Quickstart

Before beginning to work with Payload, make sure you have all of the required software.

pnpx create-payload-app@latest

If you're new to Payload, you should start with the website template (pnpx create-payload-app@latest -t website). It shows how to do everything - including custom Rich Text blocks, on-demand revalidation, live preview, and more. It comes with a frontend built with Tailwind all in one /app folder.

One-click deployment options

You can deploy Payload serverlessly in one-click via Vercel and Cloudflare—giving everything you need without the hassle of the plumbing.

Deploy on Cloudflare

Fully self-contained — one click to deploy Payload with Workers, R2 for uploads, and D1 for a globally replicated database.

Deploy to Cloudflare

Deploy on Vercel

All-in-one on Vercel — one click to deploy Payload with a Next.js front end, Neon database, and Vercel Blob for media storage.

Deploy with Vercel

One-click templates

Jumpstart your next project with a ready-to-go template. These are production-ready, end-to-end solutions designed to get you to market fast. Build any kind of website, ecommerce store, blog, or portfolio — complete with a modern front end built using React Server Components and Tailwind.

🌐 Website

🛍️ Ecommerce 🎉 NEW 🎉

We're constantly adding more templates to our Templates Directory. If you maintain your own, add the payload-template topic to your GitHub repo so others can discover it.

🔗 Explore more:

Payload Features

Request Feature

🗒️ Documentation

Check out the Payload website to find in-depth documentation for everything that Payload offers.

Migrating from v2 to v3? Check out the 3.0 Migration Guide on how to do it.

🙋 Contributing

If you want to add contributions to this repository, please follow the instructions in contributing.md.

📚 Examples

The Examples Directory is a great resource for learning how to setup Payload in a variety of different ways, but you can also find great examples in our blog and throughout our social media.

If you'd like to run the examples, you can use create-payload-app to create a project from one:

npx create-payload-app --example example_name

You can see more examples at:

🔌 Plugins

Payload is highly extensible and allows you to install or distribute plugins that add or remove functionality. There are both officially-supported and community-supported plugins available. If you maintain your own plugin, consider adding the payload-plugin topic to your GitHub repository for others to find.

🚨 Need help?

There are lots of good conversations and resources in our Github Discussions board and our Discord Server. If you're struggling with something, chances are, someone's already solved what you're up against. 👇

Like what we're doing? Give us a star

👏 Thanks to all our contributors

S
Description
Use when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors,…
Readme 379 MiB
Languages
TypeScript 75.5%
JavaScript 22.3%
CSS 1.9%
SCSS 0.1%