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 13px. Supported font sizes are: 8, 9, 10, 11, 12, 13, 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, 13, 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 13. |
| 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.
When you insert an image in the rich text editor, lightning-input-rich-text uploads the image immediately to the org by default. You can also delay image upload and upload the image manually when you're ready. See Upload Images Manually.
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.
Supported image types are .png, .jpg, and .gif. The maximum image size is 1 MB.
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.
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.
Uploaded image files are accessible to all org users by default. For images that shouldn't be accessible to all users, you must restrict access to the images.
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.
Uploading images manually is available as a developer preview. This feature isn’t generally available unless or until Salesforce announces its general availability in documentation or in press releases or public statements. All commands, parameters, and other features are subject to change or deprecation at any time, with or without notice. Don't implement functionality in production with these commands or tools.
By default, inserting an image into the rich text editor uploads the image to your org immediately.
To prevent immediate uploads, use the manual-image-upload attribute. Preventing automatic uploads
enables you to defer the upload, giving you control to upload the image only when you're ready.
Additionally, customize image upload behavior by using the component's custom events,
such as imageupload and imageuploaderror.
For example, defer the upload so you can:
- Upload images only when a form is submitted
- Validate content before uploading
- Reduce unnecessary uploads if users delete images before saving
When you use the manual-image-upload attribute, inserting an image also assigns a temporary local URL to the image. To upload pending images to your org, call uploadPendingImages().
uploadPendingImages() uploads images to your org, updating the image's src value from the temporary URL to a permanent URL.
When you specify manual-image-upload, the lightning-input-rich-text component assigns a temporary local URL for an image that's inserted in the rich text editor.
Temporary URLs are valid only in the current browser session. If users navigate away or refresh before uploading the image, their pending images are lost. We recommend that you handle unsaved states by providing visual notifications to the user.
When the image is successfully uploaded, a permanent URL that's based in your org replaces the temporary URL. The component returns these URLs via its custom events.
By default, uploaded image files are accessible to all org users.
To restrict image access to specific records, groups, or users, specify the share-with-entity-id attribute.
The uploadPendingImages() method returns a promise that resolves to an array of the results for each image. Each result object has these properties.
| Property | Type | Description |
|---|---|---|
| imageId | string | The image's tracking ID, which uses pending-img- followed by the timestamp that represents when the image was inserted, and a unique identifier. |
| file | file | The image file to be uploaded. |
| success | boolean | Returns true if the image upload is successful, or false otherwise. |
| downloadUrl | string | The permanent URL for the uploaded image. downloadUrl isn't returned when the upload fails. |
| contentVersionId | string | The ContentVersion ID for the image. ContentVersion IDs begin with 068. contentVersionId isn't returned when the upload fails. |
| error | string | The error message, which is returned when success is false. |
When there are no pending images to be uploaded, an empty array is returned.
When the image upload is successful, the result object for an image returns:
When the image upload fails, the result object for an image returns:
A pending image is an image that you insert in the rich text editor, which is then assigned a temporary local URL. Consider these upload behaviors for pending images.
- Images that fail to upload remain in the rich text editor. Call
uploadPendingImages()again to attempt another upload. To remove an image from the upload queue, delete it from the editor. - Images over 1 MB are rejected immediately. They aren't inserted into the rich text editor and the
imageuploaderrorevent fires. A notification to inform you about the image size exceeding 1 MB does not appear. We recommend that you handle the error to provide a visual notification for users. - Images that you delete from the editor before upload are removed immediately and their temporary URLs are no longer available.
- Images that failed to upload maintain their temporary URLs until a successful image upload.
Images that aren't uploaded yet maintain their temporary URLs in the image's src attribute and the lightning-input-rich-text component's value attribute. If you access the value before calling uploadPendingImages(), the value contains blob: URLs. Temporary images are removed after a page reload or if you open the same page in a different session. If you reload the page, you must re-insert the images before you can upload them.
If an image upload fails, the imageuploaderror event is fired. When uploading multiple images, the imageuploaderror event is fired for each failed upload and the imageupload event is fired for each successful upload.
Consider these common errors and resolutions when uploading an image from a rich text editor.
- The file size exceeded the 1 MB limit: Resize or compress the image to meet the file size requirements.
- The image format isn't supported: Convert the image to a supported format (.png, .jpg, or .gif).
- The record or user ID doesn't exist: When using
share-with-entity-id, make sure the ID is valid. - The user who attempts an upload has insufficient permissions: Users can work with their admins to make sure they are assigned the correct user profile or permission set.
lightning-input-rich-text deletes the pending image in these scenarios.
- After a successful upload, the image's
srcvalue returns the permanent URL. - When the
lightning-input-rich-textcomponent is removed from the DOM, such as when you navigate away from the page, the image is removed from the text editor. To use the image after the component loads again, reinsert the image in the rich text editor. - If the user deletes the image from the rich text editor, the component revokes the temporary URL. Inserting the image again results in a different temporary URL.
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.
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. 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 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 provide CSS custom properties that use the --slds-c-* prefix and they change styling for specific elements or properties of a component. Component styling hooks are supported for SLDS 1 only. See the SLDS 1 component blueprints for available component styling hooks.
For more information, see Style Components Using Lightning Design System Styling Hooks in the Lightning Web Components Developer Guide.
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.
imageupload
The event fired when each image uploads successfully.
The imageupload event returns these parameters.
| Parameter | Type | Description |
|---|---|---|
| imageId | string | The image's tracking ID, which uses pending-img- followed by the timestamp that represents when the image was inserted, and a unique identifier. |
| downloadUrl | string | The permanent URL for the uploaded image. |
| file | file | The file that was successfully uploaded. |
| contentVersionId | string | The ContentVersion ID for the image. ContentVersion IDs begin with 068. |
The event properties are as follows.
| Property | Value | Description |
|---|---|---|
| bubbles | false | This event does not bubble. |
| cancelable | false | This event cannot be canceled. |
| composed | false | This event does not propagate outside the template in which it was dispatched. |
imageuploaderror
The event fired when an image fails to be inserted into the rich text editor or uploaded.
The imageuploaderror event returns these parameters.
| Parameter | Type | Description |
|---|---|---|
| error | string | The upload error message, which can be returned when there's a permission or ID issue, or something else. When the image upload fails, the image continues to be available at the temporary URL until the image is uploaded successfully. |
| file | file | The rejected file, which includes the file name, size, and type. |
| imageId | string | The image's tracking ID, which uses pending-img- followed by the Unix timestamp that represents when the image was inserted, and a unique identifier. |
| maxSize | number | The maximum file size in bytes, which is 1 MB or 1,048,576 bytes. Files exceeding this limit are not inserted into the rich text editor. |
| reason | string | The cause of the image upload error. Possible reasons are SIZE_EXCEEDED and UPLOAD_FAILED. |
The event properties are as follows.
| Property | Value | Description |
|---|---|---|
| bubbles | false | This event does not bubble. |
| cancelable | false | This event cannot be canceled. |
| composed | false | This event does not propagate outside the template in which it was dispatched. |