Skip to content

HeadingFeature({ enabledHeadingSizes: [] }) creates invalid h0 heading nodes #15899

@fkkehlet

Description

@fkkehlet

Describe the Bug

When using HeadingFeature({ enabledHeadingSizes: [] }) to disable all heading sizes in a Lexical editor, the heading node type is still registered. Certain editor actions (such as pressing space at the start of a paragraph) trigger Lexical's Markdown shortcut handling and convert the paragraph into a heading node with an invalid tag: "h0".

This produces corrupted data in the database:

{
    "tag": "h0",
    "type": "heading",
    "children": [{ "type": "text", "text": "some content" }]
  }

If the HeadingFeature is later removed from the editor config, these nodes cause a runtime error:

parseEditorState: type "heading" + not found

Link to the code that reproduces this issue

https://github.com/fkkehlet/payload-h0-heading-bug

Reproduction Steps

  1. Create a Lexical editor with HeadingFeature({ enabledHeadingSizes: [] }):
import { HeadingFeature, FixedToolbarFeature, lexicalEditor } from '@payloadcms/richtext-lexical'

export const basicText = lexicalEditor({
  features: ({ rootFeatures }) => [
    ...rootFeatures,
    HeadingFeature({ enabledHeadingSizes: [] }),
    FixedToolbarFeature(),
  ],
})
  1. Use this editor on any rich text field
  2. Type some text in a paragraph
  3. Place cursor at the start of the paragraph and press space
  4. Save the document
  5. Inspect the stored JSON — the paragraph has been converted to { "type": "heading", "tag": "h0" }

Which area(s) are affected?

plugin: richtext-lexical

Environment Info

Payload: 3.77.0
Next.js: 15.5.12
@payloadcms/richtext-lexical: 3.77.0
Node: 22.22.0
Platform: linux x64

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions