---
title: "Rich Text"
description: "Learn how to use the RichText component to edit control values directly on the canvas for WordPress blocks using the Lazy Blocks Pro plugin."
url: "https://www.lazyblocks.com/docs/blocks-code/rich-text/"
lastUpdated: 2026-09-09
source: "blocks-code/rich-text.mdx"
---
# Rich Text [Pro]

The `` 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. A `name` that matches no control works as well, and then the component registers and owns the attribute by itself.

## Basic usage

Add the component to your block code and point it at a control by name:

```html
<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:

```html
<div class="wp-block-lazyblock-your-block-name">
  <h2>Your typed title</h2>
</div>
```

## Attributes

| Name                           | Type        | Description                                                                    |
| ------------------------------ | ----------- | ------------------------------------------------------------------------------ |
| `name`                         | **String**  | control or standalone attribute 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 <kbd>Enter</kbd> from inserting a line break, `false` by default          |
| `default`                      | **String**  | value a freshly inserted block starts with                                     |
| `translate`                    | **String**  | `translate="false"` keeps the value out of WPML                                |
| `format`                       | **String**  | accepted and ignored                                                           |
| `identifier`                   | **String**  | accepted and ignored                                                           |
| `multiline`                    | **String**  | accepted and ignored                                                           |

`default` seeds the block attribute the component registers, so a new block arrives with text in place instead of the placeholder. When the same name appears on more than one tag, the first tag that carries a `default` wins. The value is never printed on the rendered tag.

`translate="false"` on any tag takes that name out of the WPML config for the whole block. A name that belongs to a control follows the control's own **WPML Translation** setting instead. See [Multilingual](https://www.lazyblocks.com/docs/multilingual/).

`format`, `identifier` and `multiline` are accepted and then stripped from the rendered tag. Nothing reads them. A single-line field is `disableLineBreaks`, not `multiline`.

Any other attribute is passed through to the rendered element, so `class`, `id` and `data-*` work as they do on a plain tag.

```html
<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.

```html
<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          |
| Email                    | 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 and 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.

## A name with no control

`name` does not have to match a control. When no control carries that name, the component registers the block attribute itself, `type: string` with the tag's `default` or an empty string, and owns the value outright. Such a value is edited on the canvas only, because there is no inspector control mirroring it.

Two kinds of name are skipped even so, one the block already uses as an attribute of its own, and one belonging to a control with **Save in Meta** turned on, whose value lives in post meta rather than in the block attributes.

Escaping follows the same split. With no control behind the name the component owns the markup and keeps it through `wp_kses_post()`. A name bound to a control that is neither Rich Text nor Classic Editor is printed with `esc_html()`, so a tag typed into a plain Text control shows as text 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 `name` is missing, names an attribute the block already has, names a Repeater child, or names a control that does not hold text.

## Documentation Index
> Fetch the complete documentation index at: https://www.lazyblocks.com/llms.txt
> Fetch every page in a single file at: https://www.lazyblocks.com/llms-full.txt
