Input Rich Text
lightning-input-rich-text
A WYSIWYG editor with a customizable toolbar for entering rich text
For Use In
Lightning Experience, Experience Builder Sites, Salesforce Mobile App, Lightning Out (Beta), Standalone Lightning App
A lightning-input-rich-text component creates a rich text editor based on the
Quill JS library, enabling you to add, edit, format, and delete rich text. You
can create rich text editors with different toolbar configurations.
Pasting rich content into the editor is supported if the feature is available in the toolbar. For example, you can paste bold text if the bold button is available in the toolbar.
This example creates a rich text editor using lightning-input-rich-text and sets its content during
initialization. The lightning-formatted-rich-text component is used to display the formatted output.
lightning-input-rich-text uses the onchange event handler to listen to a change to its value.
Initialize the rich text content in JavaScript. To bind the input value in the editor, use the event.target.value property. For more information, see Data Binding in a Template.
Depending on the HTML markup that's passed to the component's value attribute, there can be a visual difference between the view state of the component, and upon initial focus on the editor. On focus, the editor removes invalid and uncommon patterns of nested HTML tags. For example, using <p> within a <li> tag results in the removal of the <p> tag.
The editor also removes inline styles from <p> and <div> tags. To preserve inline styles, use a <span> tag instead.
The required attribute marks the text editor as requiring user input. To display an asterisk to indicate input is required,
set label-visible and required. A default label displays after the asterisk. See the Accessibility section for more information about labels.
The component doesn't validate for required input. See Input Validation for more information.
The toolbar provides menus and buttons that are ordered within the following categories.
FORMAT_FONT: Font family and size menus. The font menu provides the following font selections: Arial, Courier, Garamond, Salesforce Sans, Tahoma, Times New Roman, and Verdana. The font selection defaults to Salesforce Sans with a size of 12px. Supported font sizes are: 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, and 72.FORMAT_TEXT: Bold, Italic, Underline, and Strikethrough buttons.FORMAT_BODY: Bulleted List, Numbered List, Indent, and Outdent buttons.ALIGN_TEXT: Left Align Text, Center Align Text, and Right Align Text buttons.INSERT_CONTENT: Image and Link buttons.REMOVE_FORMATTING: Remove formatting button, which stands alone at the end of the toolbar.
You can disable buttons by category using the disabled-categories attribute.
This example shows how to disable the FORMAT_TEXT category for Bold, Italic, Underline, and Strikethrough buttons.
You can also customize the editor using the formats attribute, which lists individual formats that the editor supports within the categories.
By default, lightning-input-rich-text enables some formats with a corresponding toolbar button. Formats that don't provide a toolbar button support only pasted content. For example, the table and header formats are enabled by default but support pasted content only, and do not provide toolbar buttons. You can't create or edit a table or a header in the rich text editor.
| Format Name | Description | Enabled by Default | Provides a Toolbar Button | Toolbar Category |
|---|---|---|---|---|
font | Changes the font on text | Y | Y | FORMAT_FONT |
size | Changes the size on text | Y | Y | FORMAT_FONT |
bold | Bolds text | Y | Y | FORMAT_TEXT |
italic | Italicizes text | Y | Y | FORMAT_TEXT |
underline | Underlines text | Y | Y | FORMAT_TEXT |
strike | Adds a strikethrough to text | Y | Y | FORMAT_TEXT |
list | Creates a bulleted or numbered list | Y | Y | FORMAT_BODY |
indent | Applies an indent or outdent to text | Y | Y | FORMAT_BODY |
align | Aligns text to the left, center, or right | Y | Y | ALIGN_TEXT |
link | Creates a link on text | Y | Y | INSERT_CONTENT |
image | Adds an image | Y | Y | INSERT_CONTENT |
clean | Removes formatting from content | Y | Y | REMOVE_FORMATTING |
table | Supports pasting of tables | Y | ||
header | Supports pasting of headers | Y | ||
color | Provides color selection for text | Y | ||
background | Supports pasting of text with background colors | |||
code | Supports pasting of inline text with code formatting | |||
code-block | Supports pasting of blocks of text with code formatting | |||
script | Supports pasting of text with superscript and subscript formatting | |||
blockquote | Supports pasting of block quotes | |||
direction | Supports RTL and LTR text |
The formats attribute must include the complete list of formats to enable. If you pass in a subset of the formats, all other formats are removed from the toolbar, and pasted content using the missing formats are not rendered correctly in the text editor.
This example shows how to add the color format to the editor, which adds a text color button.
To enable the color format, add it to the list of formats.
This example shows how to remove strike from the editor, which removes the strikethrough button from the toolbar.
Remove the strike format from the list of formats to enable.
You can set some formats programmatically by using the setFormat() method.
This example shows a button that applies a list of formats on content in the editor.
Pass in the formats to setFormat().
This example passes formats to create right-aligned, Garamond font text
that is bold, italic, and colored red, on a black background. The allowedFormats
must also be set because background and color are not default formats.
To retrieve the formats, use getFormat(). The rich text editor removes any font values that are not supported.
Supported formats are as follows.
| Key | Values | Description |
|---|---|---|
| align | left, right, center | Aligns the text to the left, right, or centers the text block where the cursor is located. |
| background | color name, hex value | Applies the specified color to the background of the selected text. If no text is selected, applies to the text you enter next. Specify color by HTML color name or hexadecimal value. |
| bold | true, false | Applies bold format to selected text. If no text is selected, applies to the text you enter next. |
| code | true, false | Applies code format inline to selected text. If no text is selected, applies to the text you enter next. |
| code-block | true, false | Applies code format to the line where the cursor is located. This is a block-level format, so it applies to block-level elements such as <p>. |
| color | color name, hex value | Applies the specified color to the selected text. If no text is selected, applies to the text you enter next. Specify color by HTML color name or hexadecimal value. |
| font | default, sans-serif, courier, verdana, tahoma, garamond, serif | Applies the specified font to the selected text. If no text is selected, applies to the text you enter next. The default sans-serif font is Arial. The default serif font is Times New Roman. |
| header | 1, 2, 3, 4, 5, 6 | Applies the specified header level to the line where the cursor is located. |
| italic | true, false | Applies italic format to selected text. If no text is selected, applies to the text you enter next. |
| link | url | Creates a link to the specified URL using the selected text as the link text. Requires text to be selected before applying the format. |
| size | 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 | Applies the specified font size to the selected text. If no text is selected, applies to the text you enter next. The default font size is 12 |
| strike | true, false | Applies strikethrough format to selected text. If no text is selected, applies to the text you enter next. |
| underline | true, false | Applies underline format to selected text. If no text is selected, applies to the text you enter next. |
You can insert text programmatically in the editor with the setRangeText() method, replacing content
or inserting new content. The method can be used in an action for custom buttons.
The setRangeText() method follows the API of the standard HTMLInputElement.setRangeText() method described on
MDN.
The lightning-input-rich-text component has one exception to the setRangeText() standard behavior which
is described in Inserting Formatted Text Programmatically (Beta).
setRangeText() supports these parameters.
| Parameter | Type | Description |
|---|---|---|
| replacement | string | The string to insert. HTML markup is not supported. |
| start | number | The 0-based index of the first character to replace. |
| end | number | The 0-based index that follows the last character to replace. |
| selectMode | string | Defines how the selection is set after the text is inserted. |
Valid values for selectMode are:
select- Selects the inserted text.start- Moves the selection to just before the inserted text.end- Moves the selection to just after the inserted text.preserve- Attempts to preserve the selection in effect before the insertion. This is the default.
To insert replacement text at the current cursor location, specify only the replacement string and no other parameters. After the insertion, the cursor remains at the original location. If text is selected when the insertion occurs, the text is replaced.
This example uses setRangeText() to insert some text at the beginning of the line
without replacing any content.
The selectMode value causes the cursor to remain at the end of the inserted content.
This example inserts a space at index 10 and removes characters at index 10 through 14.
The resulting content is 0123456789 567890.
You can omit the final parameter of setRangeText() to use the default select mode, preserve.
These examples describe the insertion behavior with various setRangeText() parameter values.
If text is selected when selectMode is preserve and start and end values are specified,
the text insertion has no effect on the selected text. The text remains selected and is not replaced.
However, if the start and end values lie within the currently selected range, part of the selected text is replaced.
For example, suppose you have selected text at index 1 through 5, 0123456789. If you call
setRangeText('Insert', 2, 7) the result is 01Insert789.
The standard setRangeText() method uses preserve selectMode behavior
if you don't specify start or end index parameters, as in this example.
editor.setRangeText('Some new text');
If no text is selected when the method is called, the replacement text is inserted at the cursor position. After the insertion, no text is selected, which preserves the select mode. If text is selected when the method is called, that text is replaced and the inserted text is then selected.
With the standard setRangeText() method, you can only specify a different selectMode behavior
if you specify the index parameters too. You can't pass null or undefined
values to the parameters.
In contrast, the lightning-input-rich-text component's setRangeText() method accepts
undefined as a value for the start and end index parameters. You can then set the
selectMode to any valid value.
This non-standard behavior enables you to set the selectMode select with the
setRangeText() method to insert text, select the inserted text,
and then run setFormat() on the selected text. The text is inserted at the cursor
position if nothing is selected. If text is selected, it is replaced with the new text.
This example sets the formats supported in the text editor, and the initial content to display in the editor panel. The separate button inserts new formatted text.
The handleClick() function uses setRangeText() to insert text at the cursor position.
Specifying undefined for start and end index parameters enables the selectMode value to
be passed. The selectMode value is select so the inserted text is then selected. The
setFormat() method applies formats to the selected text to make it bold and colored green.
You can add custom buttons to the rich text editor. Custom buttons are contained in a button group that displays at the end of the toolbar.
To create a button group, add the lightning-rich-text-toolbar-button-group component
in a named slot called toolbar inside lightning-input-rich-text.
Place a lightning-rich-text-toolbar-button component for each custom button
inside lightning-rich-text-toolbar-button-group.
For more information about custom buttons,
see lightning-rich-text-toolbar-button documentation.
Clicking the image button opens a file picker you can use to locate and select an image on your device. The image is uploaded to the org and inserted inline in the text editor.
Supported image types are png, jpg, jpeg, and gif. The maximum image size is 1MB.
Resizing of images is not supported. Copy and pasting of images is not supported, although it might work on some combinations of browsers and operating systems. By default, guest users can't upload images to Experience Builder sites.
By default, the image is visible only in the text editor as you insert it,
and when you display the editor output, for example by using the lightning-formatted-rich-text
component. However, the image can be accessed by any org user who has access to the image URL.
When you use lightning-input-rich-text in Salesforce, pasting an image from an HTTP source results in the display of a broken image icon. Mixed content is blocked in Salesforce to improve security. We recommend uploading the image as a static resource first before using it in the component. Alternatively, enable the image toolbar button so your users can upload the image to the org.
For LWR sites in Experience Cloud, the rich text editor doesn't display the image button on the toolbar and doesn't support image uploads.
Important: For images that shouldn't be accessible to all org users, you must restrict access to the images.
Uploaded image files are accessible to all org users by default.
Restrict access to the image by using the share-with-entity-id attribute
to specify the ID of a record, org, group, or user that should have access to the image.
The image that's inserted into the text editor is shared with the entity that corresponds to that ID.
If the ID corresponds to:
- the org: all users in the org have access to the image.
- a group: only users in that group can see the image.
- a record: anyone with access to that record can see the image.
- a user: only that user can see the image.
Note that when you use the share-with-entity-id attribute, the image is more
restricted, but it's also viewable in the Files tab. When you share an image
with a record ID, the image is available in the Notes
and Attachments related list of the record page. Only users with
permissions to the record can see the image in any of these locations.
This example shows the text editor used in a record page, where the image is shared with the record ID of the record that's displayed.
Use the @api decorator to create a public recordId property.
The record page sets the property to the ID of the current record.
For more information, see Make a Component Aware of Its Record Context in the Lightning Web Components Developer Guide.
lightning-input-rich-text doesn't provide built-in validation but you can wire
up your own validation logic. Set the valid attribute to false to change
the border color of the rich text editor to red. Set the required and
label-visible attributes to display the asterisk near the label.
This example checks whether the rich text content is empty or undefined.
The validate method toggles the validity of the rich text editor, and
displays the error message when it's invalid.
The rich text editor provides a WYSIWYG interface only. You can't edit HTML
tags using the editor, but you can set the HTML tags via the value
attribute. When you copy content from a web page or another source and paste
it into the editor, unsupported tags are removed. Only formatting that
corresponds to an enabled toolbar button or menu is preserved.
For example, if
you disable the FORMAT_TEXT category, the Bold, Italic,
Underline, and Strikethrough buttons are not available. Furthermore,
pasting bold, italic, underlined, or strikethrough text in the editor are not
supported when you disable the FORMAT_TEXT category. Text that was enclosed
in unsupported tags is preserved as plain text. However, tables that you copy
in a browser window can be pasted into the editor and set
via the value attribute, even though there are no corresponding toolbar
buttons or menus for them.
The component sanitizes HTML tags passed to the value attribute to prevent
XSS vulnerabilities. Only HTML tags that correspond to features available on
the toolbar are supported. If you set unsupported tags via JavaScript,
those tags are removed and the text content is preserved. The
supported HTML tags are: a, col, colgroup, em,
h1, h2, h3, h4, h5, h6, img, li, ol, p, q, s,
strike, strong, table, tbody, td, tfoot, th,
thead, tr, u, ul.
This component converts certain unsupported tags into supported tags with similar functions.
| Unsupported Tag | Becomes |
|---|---|
b | strong |
div | p |
i | em |
span | p |
Other unsupported tags and attributes are removed, and only their text content is displayed. Let's say you copy some text that's rendered bold with color formatting, and its HTML markup looks like this.
If your rich text editor specifies support for the bold format but not the color format,
the editor preserves the bold formatting by converting it to a strong tag. However,
the color formatting in the pasted text is removed.
In Chromium-based browsers, copying content from a lightning-formatted‑rich‑text component
that contains links and pasting the content into the rich text editor inserts
and breaks formatting. We recommend that you use a non-Chromium based web browser,
such as Mozilla Firefox or Apple Safari, when copying and pasting content with hyperlinks.
The value of the label attribute is read by screen readers and the
label-visible attribute determines whether the label is also visible on the
screen. If you don't specify either attribute, a default label is applied and
it's not visible. You can set label to a value of your choice. Use
label-visible to make the label visible, whether label has a default value
or one you have specified.
When focus first shifts to the rich text editor, initial focus is on the first item in the toolbar, which is the font menu by default.
The font menu on the toolbar has an aria-haspopup value of listbox.
You can use the arrow keys to navigate up and down the fonts, then press Enter or
Tab to select a font. To close the font menu, press the Esc or Tab key.
Use Tab and Shift+Tab to navigate between the selectors for font, size, and color. Tab from the color selector to the formatting buttons. Focus goes to the first button, which is the bold button by default. If you've previously selected a different button in the current session, focus initially returns to that button instead of the first button.
Once focus is on a formatting button, use arrow keys to navigate through the buttons. When you select a button, the cursor goes to the editor panel where you can type your formatted text. Press Shift+Tab to return to the toolbar.
If you highlight text in the editor, you can press Shift+Tab to move into the toolbar and press the Spacebar to enable bold formatting. However, you can't press the Spacebar again to toggle the bold formatting because focus moves back into the editor after you set the text to bold. Pressing the Spacebar again removes the highlighted text from the editor.
The link button has an aria-haspopup value of dialog. To open the dialog, navigate to the
link button and press the Spacebar. Focus moves to the first input field on the dialog where you enter
the link title. To close the dialog without saving your input, press Esc. Alternatively, tab to the
Cancel button and press Enter or the Spacebar.
Unlike the bold formatting button, the remove formatting button doesn't use the aria-pressed
attribute as it isn't a toggle button.
When the component is in an invalid state, an error message is displayed using an element with a
randomly generated id value. To enable screen readers to announce error messages during user input, the id value
is associated with the aria-describedby attribute on the rich text editor element that has the role="textbox"
attribute. For example, the rich text editor displays a message when an input is required but the editor is empty
when you remove focus from it.
If you provide your own aria-describedby value for the lightning-input-rich-text component, the value is appended
to the rich text editor element that has the role="textbox" attribute only when the component is in an invalid state.
lightning-input-rich-text implements the
rich text editor blueprint in the Salesforce Lightning Design System (SLDS).
To apply additional styling, use the SLDS utility classes with the class attribute.
This example adds padding on top of the rich text editor using an SLDS class.
Component styling hooks use the --slds-c-* prefix and change styling for specific elements or properties of a component. Component-specific styling isn’t recommended, because it’s unsupported for SLDS 2, but existing customizations still work with the original SLDS. If you use component styling hooks, limit the components to SLDS themes until SLDS 2 and the Salesforce Cosmos theme become generally available. See Rich Text Editor Styling Hooks Overview for documentation on component-specific hooks for this component.
Salesforce uses lightning-input-rich-text in many features, such as in a custom rich text field or Chatter feed. Each feature that uses the rich text editor enforces a character limit. Refer to the documentation in Salesforce Help for a feature's limits and allocations.
Here are several documentation that discuss the character limit for features that use lightning-input-rich-text.
Character limits include HTML tags, even though they're not visible in the editor. By default, Quill appends an additional 7 characters <p></p> to the text. The actual length of text you enter always includes this additional 7 characters. Rich text formatting also adds to the character count. For example, bold formatting includes the <b></b> tag around your text and adds 7 more characters to your actual length of text.
The editor automatically indents nested bulleted lists. If you insert extra indents, they are removed on save.
You can't nest a list that's a different type from its parent list. For example, if you nest a <ul> tag within an <ol> tag, the <ul> tag is removed and its <li> tags are merged with the parent <ol> list.
The value attribute only supports string values. To clear the editor by setting the value attribute, use "" to specify an empty string because null and undefined aren't supported.
Output from the editor can display differently outside of the Salesforce Lightning Experience. If the content is being viewed outside of Lightning contexts (such as in an e-mail), there will be visual inconsistencies.
When using setFormat(), navigating to a previous line removes the user's format settings for empty newlines. For example, the user can set the styling to bold and type three lines, leaving the second line empty. If the user navigates away from the second line, then navigates back, it no longer has bold styling.
Although a toolbar button for creating tables is not available, creating tables programmatically or copying from a browser window and pasting these elements preserves the formatting in the editor.
This component has usage differences from its Aura counterpart. See Base Components: Aura Vs Lightning Web Components in the Lightning Web Components Developer Guide.