Rich Text
The <RichText /> component makes a control's value editable straight on the canvas, the way a caption on a core block is. The same value stays editable from the inspector, so the two are two views of one attribute.
Basic Usage
Add the component to your block code and point it at a control by name:
<div useBlockProps>
<RichText name="title" tagName="h2" placeholder="Add title…" />
</div>The control named title now takes its text from the canvas. On the front end the component renders as the tag you gave it:
<div class="wp-block-lazyblock-your-block-name">
<h2>Your typed title</h2>
</div>Attributes
| Name | Type | Description |
|---|---|---|
name | String | control to bind to. Letters, numbers, - and _ only |
tagName | String | tag to render, p by default. none renders the text with no tag around it |
placeholder | String | text shown while the value is empty |
allowedFormats | String | formats to offer, comma-separated or a JSON array. Everything, by default |
inlineToolbar | Boolean | show the formatting toolbar inline, true by default |
withoutInteractiveFormatting | Boolean | drop formats that produce clickable elements, false by default |
disableLineBreaks | Boolean | stop Enter from inserting a line break, false by default |
Any other attribute is passed through to the rendered element, so class, id and data-* work as they do on a plain tag.
<div useBlockProps>
<RichText
name="intro"
tagName="p"
class="my-intro"
allowedFormats="core/bold,core/italic"
placeholder="Add an intro…"
/>
</div>Links
Give the component tagName="a" and it edits the link text on the canvas while rendering a real anchor on the front end, the same way the core Button block behaves. The link is not followable while you are editing it.
<div useBlockProps>
<RichText name="label" tagName="a" href="https://example.com" placeholder="Add label…" />
</div>href, target, rel and download are all passed through to the anchor.
Which controls it can bind to
The component works with the controls that store text:
| Control | Formatting kept | Line breaks |
|---|---|---|
| Rich Text (WYSIWYG) | yes | yes |
| Classic Editor (WYSIWYG) | yes | yes |
| Textarea | no | yes |
| Code Editor | no | yes |
| Text | no | no |
| URL | no | no |
| no | no |
The component never stores more than the control behind it can hold. The same value is still edited by the control in the inspector, so putting HTML or a second line into a plain Text control would destroy it there — for those controls the component turns formatting and line breaks off by itself, whatever you passed in allowedFormats or disableLineBreaks.
Controls that store JSON rather than text — Image, Gallery, Repeater — cannot be bound, and neither can a control living inside a Repeater. Naming one warns in the browser console and leaves the value alone.
An empty value is offered for editing only while the block is selected, the same as a caption on a core block, and prints nothing on the front end.
Notes
- The control keeps appearing wherever its Placement setting puts it. Content places it in the canvas beside the component, Inspector puts it in the sidebar.
- The component warns in the browser console when
nameis missing, names a reserved attribute, names a Repeater child, or names a control that does not hold text. Each warning is printed once rather than on every render.