
Syncfusion Blazor Rich Text Editor
- 234 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-rich-text-editor for development tasks
About
syncfusion-blazor-rich-text-editor: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-rich-text-editor
Syncfusion Blazor Rich Text Editor by the numbers
- 234 all-time installs (skills.sh)
- +13 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,623 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/blazor-ui-components-skills --skill syncfusion-blazor-rich-text-editorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 234 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-rich-text-editor for development tasks
Files
Syncfusion Blazor Rich Text Editor
A comprehensive skill for implementing and configuring the Syncfusion Blazor Rich Text Editor (SfRichTextEditor) — a full-featured WYSIWYG editor supporting HTML and Markdown editing, rich toolbar customization, media insertion, tables, data binding, import/export, and accessibility.
When to Use This Skill
Use this skill when the user needs to:
- Install and set up
SfRichTextEditorin a Blazor Server, WebAssembly, or Web App project - Configure toolbar items, toolbar types (Expand, MultiRow, Scrollable, Popup), or toolbar position
- Format text: bold/italic/underline, headings, lists, alignment, colors, fonts, line height
- Insert and manage images, videos, or audio with upload support
- Work with tables: insert, resize, merge cells, customize quick toolbar
- Switch between HTML, Markdown, or IFrame editor modes
- Enable inline editing (inline toolbar)
- Add custom toolbar tools or use exec commands
- Handle RTE events (
ValueChange,OnActionBegin, image upload events, etc.) - Bind content two-way with
@bind-Valueor retrieve viaGetTextAsync - Configure paste cleanup behavior
- Import from Word / export to Word or PDF
- Implement accessibility, keyboard shortcuts, RTL, or globalization
Quick Start
1. Install NuGet packages:
dotnet add package Syncfusion.Blazor.RichTextEditor
dotnet add package Syncfusion.Blazor.Themes2. Register in `Program.cs`:
using Syncfusion.Blazor;
builder.Services.AddSyncfusionBlazor();3. Add to `_Imports.razor`:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.RichTextEditor4. Add CSS/JS in `index.html` (WASM) or `App.razor` (Server):
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>5. Add the component:
<SfRichTextEditor @bind-Value="@Content">
<RichTextEditorToolbarSettings Items="@Tools" />
</SfRichTextEditor>
@code {
private string Content { get; set; } = "<p>Start editing...</p>";
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Formats },
new() { Command = ToolbarCommand.Alignments },
new() { Command = ToolbarCommand.OrderedList },
new() { Command = ToolbarCommand.UnorderedList },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.CreateLink },
new() { Command = ToolbarCommand.Image },
new() { Command = ToolbarCommand.CreateTable },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}Navigation Guide
Getting Started & Setup
📄 Read: references/getting-started.md
- NuGet installation for all project types (Visual Studio, VS Code, .NET CLI)
- Service registration and namespace imports
- CSS theme and JS script references
- Adding the first component to a page
- Retrieving content as HTML, plain text, or character count
Toolbar Configuration
📄 Read: references/toolbar.md
- Enabling or disabling the toolbar with
RichTextEditorToolbarSettings.Enable - Toolbar types: Expand, MultiRow, Scrollable, Popup
- Floating toolbar and offset configuration
- Toolbar position (top or bottom)
- Configuring toolbar items with
ToolbarItemModel - Custom toolbar items (template-based)
Built-in Toolbar Tools Reference
📄 Read: references/built-in-tools.md
- Complete list of all
ToolbarCommandenum values - Text formatting, font & styling, alignment, lists, hyperlinks
- Image/table/link quick toolbar item commands
- Undo/redo, fullscreen, print, source code, preview tools
- Removing or reordering default toolbar items
Text Formatting
📄 Read: references/text-formatting.md
- Bold, italic, underline, strikethrough, subscript, superscript, inline code
- Text alignment (left, center, right, justify)
- Ordered/unordered lists with custom number and bullet styles
- Heading formats (H1–H6, paragraph, blockquote, code)
- Line height configuration
- Horizontal line, format painter, clear format
- Markdown auto-format (inline and block shortcuts)
Images, Video & Audio
📄 Read: references/images-and-media.md
- Image insertion from local machine or URL
RichTextEditorImageSettings: SaveUrl, Path, AllowedTypes, EnableResize- Base64 vs server-side upload
- Image quick toolbar configuration
- Video and audio insertion and settings
Tables
📄 Read: references/tables.md
- Creating tables with
CreateTabletoolbar item RichTextEditorTableSettings: width, resize, custom styles- Table quick toolbar: add/remove rows & columns, merge cells, properties
- Advanced table manipulation (cell selection, split, custom borders)
Editor Modes
📄 Read: references/editor-modes.md
- HTML editor mode (default WYSIWYG)
- Markdown editor mode (
EditorMode.Markdown) - IFrame vs DIV rendering mode
- Source code view toggling
Inline Mode
📄 Read: references/inline-mode.md
- Enabling inline toolbar (
InlineMode) - Inline toolbar display on text selection
- Use cases: comment editors, in-place content editing
Custom Tools & Exec Commands
📄 Read: references/custom-tools.md
- Adding custom toolbar buttons with
ToolbarItemModeland templates - Executing commands programmatically with
ExecuteCommandAsync - Slash commands (
/trigger menu) configuration - Format painter advanced settings (
RichTextEditorFormatPainterSettings)
Events
📄 Read: references/events.md
RichTextEditorEventschild component usage and wiring pattern- Lifecycle events:
Created,Destroyed - Focus/interaction:
Focus,Blur,OnToolbarClick,SelectionChanged - Content events:
ValueChange,BeforePasteCleanup,AfterPasteCleanup - Toolbar lifecycle:
OnActionBegin,OnActionComplete - Dialog events:
OnDialogOpen,DialogOpened,OnDialogClose,DialogClosed - Quick toolbar:
OnQuickToolbarOpen,QuickToolbarOpened,QuickToolbarClosed - Image events:
OnImageSelected,BeforeUploadImage,OnImageUploadSuccess,OnImageUploadFailed,ImageUploadChange,OnImageDrop,ImageDelete - Media events:
FileSelected,FileUploading,FileUploadSuccess,FileUploadFailed,FileUploadChange,OnMediaDrop,MediaDeleted - Resize events:
OnResizeStart,OnResizeStop - Toolbar status:
UpdatedToolbarStatus - Export events:
OnExport,OnExportFailure - Slash menu:
SlashMenuItemSelecting - Complete EventArgs class reference with all properties
Methods
📄 Read: references/methods.md
- Focus & selection:
FocusAsync,FocusOutAsync,SaveSelectionAsync,RestoreSelectionAsync,SelectAllAsync,GetSelectionAsync - Content retrieval:
GetTextAsync,GetSelectedHtmlAsync,GetCharCountAsync,GetXhtmlAsync - Command execution: all
ExecuteCommandAsyncoverloads with typed args (image, link, table, video, audio, code block, format painter) - Toolbar control:
EnableToolbarItem,DisableToolbarItem,RemoveToolbarItem - Dialog & UI control:
ShowDialogAsync,CloseDialogAsync,ShowFullScreenAsync,PrintAsync,RefreshUIAsync,ShowSourceCodeAsync - Undo/redo:
ClearUndoRedoAsync - Full
CommandName,ToolbarCommand, andDialogTypeenum references
Properties
📄 Read: references/properties.md
- Content & value:
Value,Placeholder,Readonly,Enabled,MaxLength,ShowCharCount - Editor behaviour:
EditorMode,EnterKey,ShiftEnterKey,EnableTabKey,EnableAutoUrl,EnableMarkdownAutoFormat,EnableClipboardCleanup,EnableXhtml,EnableHtmlEncode,EnableResize - Appearance & layout:
Height,Width,CssClass,ShowTooltip,FloatingToolbarOffset - Security & sanitization:
EnableHtmlSanitizer,AdditionalSanitizeAttributes,AdditionalSanitizeTags,DeniedSanitizeSelectors - Keyboard & shortcuts:
KeyConfigurewith fullShortcutKeysdefault bindings table - Persistence & auto-save:
EnablePersistence,SaveInterval,AutoSaveOnIdle - Undo/redo config:
UndoRedoSteps,UndoRedoTimer - HTTP integration:
HttpClientInstance - Full 37-property summary table
Data Binding & Value Management
📄 Read: references/data-binding.md
- Two-way binding with
@bind-Value - One-way binding and programmatic value updates
ValueChangeevent for detecting edits- Read-only mode (
Readonlyproperty) - Max length enforcement and character count display
Paste Cleanup
📄 Read: references/paste-and-cleanup.md
RichTextEditorPasteCleanupSettingsconfiguration- Stripping/keeping specific HTML attributes and styles on paste
- Forcing plain text paste
- Enter key behavior (
EnterKey,ShiftEnterKey) - Undo/redo manager configuration
Import & Export
📄 Read: references/import-export.md
- Importing Word documents into the editor
- Exporting content to Word (.docx) and PDF
- HTTP client configuration for import/export services
- Mail merge with dynamic data
- WebAssembly performance optimizations for large documents
Accessibility & Globalization
📄 Read: references/accessibility-globalization.md
- WCAG 2.1 compliance details
- Keyboard shortcuts and navigation reference
- ARIA roles and screen reader support
- RTL layout (
EnableRtl) - Localization and culture configuration
- XHTML validation
Common Patterns
Two-way bound editor with character count
<SfRichTextEditor @bind-Value="@HtmlContent" ShowCharCount="true" MaxLength="2000">
</SfRichTextEditor>
@code {
private string HtmlContent { get; set; } = string.Empty;
}Read-only display
<SfRichTextEditor Value="@HtmlContent" Readonly="true">
<RichTextEditorToolbarSettings Enable="false" />
</SfRichTextEditor>Markdown editor mode
<SfRichTextEditor EditorMode="EditorMode.Markdown" @bind-Value="@MarkdownContent">
</SfRichTextEditor>
@code {
private string MarkdownContent { get; set; } = "**Hello** world!";
}Accessibility and Globalization
Table of Contents
- Accessibility Compliance Overview
- WAI-ARIA Attributes
- Keyboard Shortcuts Reference
- Custom Key Configuration
- RTL Support
- Localization
- XHTML Validation
---
Accessibility Compliance Overview
The Rich Text Editor is built to comply with the following accessibility standards:
| Standard | Level / Status |
|---|---|
| WCAG 2.2 | AA |
| Section 508 | ✅ Full support |
| WAI-ARIA | ✅ Roles, states, properties applied |
| Screen Reader | ✅ Supported |
| Right-to-Left (RTL) | ✅ Supported |
| Keyboard Navigation | ✅ Full support |
| Color Contrast | ⚠️ Partial (some elements) |
| Mobile Device | ✅ Supported |
| Axe-core Validation | ✅ Passes automated checks |
---
WAI-ARIA Attributes
The toolbar element is assigned role="toolbar":
| Attribute | Value / Description |
|---|---|
role="toolbar" | Identifies the toolbar region |
aria-orientation | horizontal (default) |
aria-haspopup | true when popup mode is active |
aria-disabled | Reflects toolbar disabled state |
aria-owns | References the editor element ID from the toolbar popup |
The editor content area carries role="application":
| Attribute | Description |
|---|---|
role="application" | Marks the editing surface as an interactive application region |
aria-disabled | Reflects read-only/disabled state |
---
Keyboard Shortcuts Reference
Toolbar Navigation
| Action | Windows | Mac |
|---|---|---|
| Focus toolbar | Alt + F10 | ⌥ + F10 |
| Next tool | → | → |
| Previous tool | ← | ← |
| Execute focused tool | Enter / Space | Enter / Space |
| Close dropdown / dialog | Esc | Esc |
Content Editing and Formatting
| Action | Windows | Mac |
|---|---|---|
| Select all | Ctrl + A | ⌘ + A |
| Bold | Ctrl + B | ⌘ + B |
| Italic | Ctrl + I | ⌘ + I |
| Strikethrough | Ctrl + Shift + S | ⌘ + ⇧ + S |
| Inline code | Ctrl + ` | ⌘ + ` |
| Create link | Ctrl + K | ⌘ + K |
| New paragraph (hard break) | Enter | Enter |
| Soft line break | Shift + Enter | ⇧ + Enter |
| Copy format painter | Alt + Shift + C | ⌥ + ⌘ + C |
| Paste format painter | Alt + Shift + V | ⌥ + ⌘ + V |
| Clear format painter | Esc | Esc |
Text Case and Script
| Action | Windows | Mac |
|---|---|---|
| Uppercase | Ctrl + Shift + U | ⌘ + ⇧ + U |
| Lowercase | Ctrl + Shift + L | ⌘ + ⇧ + L |
| Superscript | Ctrl + Shift + = | ⌘ + ⇧ + = |
| Subscript | Ctrl + = | ⌘ + = |
Alignment and Indentation
| Action | Windows | Mac |
|---|---|---|
| Align left | Ctrl + L | ⌘ + L |
| Align centre | Ctrl + E | ⌘ + E |
| Align right | Ctrl + R | ⌘ + R |
| Justify | Ctrl + J | ⌘ + J |
| Increase indent | Ctrl + ] | ⌘ + ] |
| Decrease indent | Ctrl + [ | ⌘ + [ |
Lists
| Action | Windows | Mac |
|---|---|---|
| Ordered list | Ctrl + Shift + O | ⌘ + ⇧ + O |
| Unordered list | Ctrl + Alt + O | ⌘ + ⌥ + O |
Insert
| Action | Windows | Mac |
|---|---|---|
| Insert table dialog | Ctrl + Shift + E | ⌘ + ⇧ + E |
| Insert image dialog | Ctrl + Shift + I | ⌘ + ⇧ + I |
| Insert audio dialog | Ctrl + Shift + A | ⌘ + ⇧ + A |
| Insert video dialog | Ctrl + Alt + V | ⌘ + ⌥ + V |
Table Navigation
| Action | Windows | Mac |
|---|---|---|
| Next cell | Tab | Tab |
| Previous cell | Shift + Tab | ⇧ + Tab |
| Navigate cells | ↑ ↓ ← → | ↑ ↓ ← → |
| Insert new row (last cell) | Tab | Tab |
Clipboard
| Action | Windows | Mac |
|---|---|---|
| Copy | Ctrl + C | ⌘ + C |
| Cut | Ctrl + X | ⌘ + X |
| Paste | Ctrl + V | ⌘ + V |
| Paste as plain text | Ctrl + Shift + V | ⌘ + ⌥ + ⇧ + V |
Undo / Redo and Misc
| Action | Windows | Mac |
|---|---|---|
| Undo | Ctrl + Z | ⌘ + Z |
| Redo | Ctrl + Y | ⌘ + Y |
| View HTML source | Ctrl + Shift + H | ⌘ + ⇧ + H |
| Toggle fullscreen | Ctrl + Shift + F | ⌘ + ⇧ + F |
| Exit fullscreen | Esc | Esc |
| Clear all formatting | Ctrl + Shift + R | ⌘ + ⇧ + R |
---
Custom Key Configuration
Override default shortcuts with KeyConfigure:
<SfRichTextEditor KeyConfigure="@Keys">
<p>Bold is now Ctrl+1, Italic is Ctrl+2.</p>
</SfRichTextEditor>
@code {
private ShortcutKeys Keys = new()
{
Bold = "ctrl+1",
Italic = "ctrl+2"
};
}UseShortcutKeysproperties matching theCommandNameactions you want to override. Unspecified keys keep their defaults.
---
RTL Support
Enable right-to-left layout for Arabic, Hebrew, and other RTL languages:
<SfRichTextEditor EnableRtl="true">
<p dir="rtl">محتوى باللغة العربية</p>
</SfRichTextEditor>EnableRtl does not change automatically based on the browser culture — set it explicitly when needed.---
Localization
The RTE participates in Syncfusion's standard Blazor localization pipeline. Register resource strings in Program.cs:
// Program.cs (Blazor Server)
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddSyncfusionBlazor();
var app = builder.Build();
app.UseRequestLocalization(new RequestLocalizationOptions()
.SetDefaultCulture("ar")
.AddSupportedCultures("en-US", "ar", "de")
.AddSupportedUICultures("en-US", "ar", "de"));Refer to the Syncfusion Blazor Localization guide for adding locale resource files.
---
XHTML Validation
Enable EnableXhtml to continuously validate the editor's content against XHTML rules. Invalid constructs are automatically removed:
<SfRichTextEditor EnableXhtml="true">
<p>Content is continuously validated as you type.</p>
</SfRichTextEditor>What is validated:
| Rule | Detail |
|---|---|
| Attribute case | All attributes must be lowercase |
| Quoted values | Attribute values must be in quotation marks |
| Valid attributes | Only spec-valid attributes per element |
| Required attributes | Missing required attributes are flagged |
| Tag case | All HTML tags must be lowercase |
| Proper closing | Every opening tag must have a matching close |
| Valid elements | Unknown elements are removed |
| Nesting | Inline elements cannot wrap block elements |
| Single root | Content must have one root element |
CombineEnableXhtml="true"withEnableHtmlSanitizer="true"(the default) for maximum security when displaying user-generated content.
Built-in Toolbar Tools Reference
Table of Contents
- Default Toolbar
- Text Formatting Tools
- Font and Styling Tools
- Alignment Tools
- Lists and Indentation
- Hyperlink Tools
- Image Quick Toolbar Commands
- Table Quick Toolbar Commands
- Utility Tools
- Removing Default Tools
---
Default Toolbar
Out of the box, the RTE renders these toolbar items when no Items list is specified:
Bold | Italic | Underline | | Formats | Alignments | Blockquote | OrderedList | UnorderedList | | CreateLink | Image | | SourceCode | Undo | Redo
---
Text Formatting Tools
ToolbarCommand | Effect |
|---|---|
Bold | Makes selected text bold (<strong>) |
Italic | Italicises selected text (<em>) |
Underline | Underlines selected text |
StrikeThrough | Applies strikethrough |
InlineCode | Wraps selection in <code> |
SubScript | Subscript — positions text lower |
SuperScript | Superscript — positions text higher |
LowerCase | Converts selection to lowercase |
UpperCase | Converts selection to uppercase |
ClearFormat | Strips all inline styles from selection |
---
Font and Styling Tools
ToolbarCommand | Effect |
|---|---|
FontName | Font family dropdown |
FontSize | Font size dropdown |
FontColor | Font colour picker |
BackgroundColor | Highlight / background colour picker |
Formats | Paragraph/heading format dropdown (P, H1–H6, Pre, BlockQuote) |
LineHeight | Line-height dropdown; applies to parent block |
---
Alignment Tools
ToolbarCommand | Effect |
|---|---|
Alignments | Combined alignment dropdown |
JustifyLeft | Left-align |
JustifyCenter | Centre-align |
JustifyRight | Right-align |
JustifyFull | Justify |
Alignment is applied to the entire block that contains the cursor, not just selected inline text.
---
Lists and Indentation
ToolbarCommand | Effect |
|---|---|
OrderedList | Toggle numbered list |
UnorderedList | Toggle bulleted list |
NumberFormatList | Numbered list with style picker (decimal, roman, alpha, …) |
BulletFormatList | Bulleted list with style picker (disc, square, circle, …) |
Indent | Increase indentation / nest list item |
Outdent | Decrease indentation / un-nest list item |
---
Hyperlink Tools
Main toolbar:
ToolbarCommand | Effect |
|---|---|
CreateLink | Open insert-link dialog |
Link quick toolbar — configure via RichTextEditorQuickToolbarSettings.Link:
| Command | Effect |
|---|---|
LinkToolbarCommand.Open | Open the linked URL |
LinkToolbarCommand.Edit | Edit the link href/text |
LinkToolbarCommand.UnLink | Remove hyperlink |
<SfRichTextEditor>
<RichTextEditorQuickToolbarSettings Link="@LinkTools" />
</SfRichTextEditor>
@code {
private List<LinkToolbarItemModel> LinkTools = new()
{
new() { Command = LinkToolbarCommand.Open },
new() { Command = LinkToolbarCommand.Edit },
new() { Command = LinkToolbarCommand.UnLink }
};
}---
Image Quick Toolbar Commands
Configure via RichTextEditorQuickToolbarSettings.Image:
| Command | Effect |
|---|---|
ImageToolbarCommand.Replace | Swap image with another |
ImageToolbarCommand.Align | Align image left / centre / right |
ImageToolbarCommand.Caption | Wrap image in figure/caption |
ImageToolbarCommand.Remove | Delete image from content |
ImageToolbarCommand.OpenImageLink | Follow attached hyperlink |
ImageToolbarCommand.EditImageLink | Edit attached hyperlink |
ImageToolbarCommand.RemoveImageLink | Remove attached hyperlink |
ImageToolbarCommand.Display | Toggle inline / block display |
ImageToolbarCommand.AltText | Edit alternative text |
ImageToolbarCommand.Dimension | Set width/height in px |
<SfRichTextEditor>
<RichTextEditorQuickToolbarSettings Image="@ImageTools" />
</SfRichTextEditor>
@code {
private List<ImageToolbarItemModel> ImageTools = new()
{
new() { Command = ImageToolbarCommand.Replace },
new() { Command = ImageToolbarCommand.Align },
new() { Command = ImageToolbarCommand.Caption },
new() { Command = ImageToolbarCommand.Remove },
new() { Command = ImageToolbarCommand.HorizontalSeparator },
new() { Command = ImageToolbarCommand.AltText },
new() { Command = ImageToolbarCommand.Dimension }
};
}---
Table Quick Toolbar Commands
Configure via RichTextEditorQuickToolbarSettings.Table:
| Command | Effect |
|---|---|
TableToolbarCommand.TableHeader | Toggle table header row |
TableToolbarCommand.TableRows | Insert/delete row dropdown (above / below) |
TableToolbarCommand.TableColumns | Insert/delete column dropdown (left / right) |
TableToolbarCommand.TableCell | Merge / split cells |
TableToolbarCommand.BackgroundColor | Set background color of selected cell(s) |
TableToolbarCommand.Alignments | Align cell content horizontally (left / center / right) |
TableToolbarCommand.TableCellVerticalAlign | Align cell content vertically (top / middle / bottom) |
TableToolbarCommand.Styles | Apply predefined border/style presets |
TableToolbarCommand.TableEditProperties | Edit table width, padding, and cell spacing |
TableToolbarCommand.TableRemove | Delete the entire table |
TableToolbarCommand.Separator | Visual divider between toolbar groups |
---
Utility Tools
ToolbarCommand | Effect |
|---|---|
SourceCode | Toggle HTML source view |
Preview | Show render preview |
FullScreen | Maximise editor to viewport |
Print | Print editor content |
FormatPainter | Copy formatting; double-click for sticky mode |
Undo | Undo last action |
Redo | Redo last undone action |
Separator | Visual divider between toolbar groups |
---
Removing Default Tools
Pass only the tools you want — the default set is replaced entirely:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@MinimalTools" />
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> MinimalTools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}Omitting a tool from Items removes it; you don't need any separate "remove" call.Custom Tools
Table of Contents
---
Custom Toolbar Items
Use RichTextEditorCustomToolbarItems inside RichTextEditorToolbarSettings to add buttons with arbitrary Blazor content (text labels, icons, or full templates). Reference the custom item in Items by its Name:
@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor @ref="RteObj">
<RichTextEditorToolbarSettings Items="@Tools">
<RichTextEditorCustomToolbarItems>
<RichTextEditorCustomToolbarItem Name="Symbol">
<Template>
<SfButton @onclick="InsertSymbol">Ω</SfButton>
</Template>
</RichTextEditorCustomToolbarItem>
</RichTextEditorCustomToolbarItems>
</RichTextEditorToolbarSettings>
<p>Click <b>Ω</b> to insert a special character at the cursor.</p>
</SfRichTextEditor>
@code {
private SfRichTextEditor RteObj = default!;
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Separator },
new() { Name = "Symbol", TooltipText = "Insert Symbol" }, // custom item
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.SourceCode },
new() { Command = ToolbarCommand.FullScreen }
};
private async Task InsertSymbol()
{
await RteObj.ExecuteCommandAsync(
CommandName.InsertText,
"₹",
new ExecuteCommandOption { Undo = true }); // add to undo stack
}
}Key points:
NameinToolbarItemModelmust matchNameinRichTextEditorCustomToolbarItemTooltipTextsets the accessible tooltip- Blazor components (buttons, dropdowns, etc.) are valid template content
---
ExecuteCommandAsync
SfRichTextEditor.ExecuteCommandAsync applies formatting or inserts content at the current cursor position programmatically.
HTML Editor Commands
| Command | Signature | Description |
|---|---|---|
Bold | ExecuteCommandAsync(CommandName.Bold) | Toggle bold |
Italic | ExecuteCommandAsync(CommandName.Italic) | Toggle italic |
Underline | ExecuteCommandAsync(CommandName.Underline) | Toggle underline |
StrikeThrough | ExecuteCommandAsync(CommandName.StrikeThrough) | Toggle strikethrough |
Superscript | ExecuteCommandAsync(CommandName.Superscript) | Toggle superscript |
Subscript | ExecuteCommandAsync(CommandName.Subscript) | Toggle subscript |
Uppercase | ExecuteCommandAsync(CommandName.Uppercase) | Convert to uppercase |
Lowercase | ExecuteCommandAsync(CommandName.Lowercase) | Convert to lowercase |
FontColor | ExecuteCommandAsync(CommandName.FontColor, "Red") | Set font colour |
FontName | ExecuteCommandAsync(CommandName.FontName, "Impact") | Set font family |
FontSize | ExecuteCommandAsync(CommandName.FontSize, "10pt") | Set font size |
BackgroundColor | ExecuteCommandAsync(CommandName.BackgroundColor, "yellow") | Set highlight colour |
JustifyCenter | ExecuteCommandAsync(CommandName.JustifyCenter) | Centre-align |
JustifyLeft | ExecuteCommandAsync(CommandName.JustifyLeft) | Left-align |
JustifyRight | ExecuteCommandAsync(CommandName.JustifyRight) | Right-align |
JustifyFull | ExecuteCommandAsync(CommandName.JustifyFull) | Justify |
Indent | ExecuteCommandAsync(CommandName.Indent) | Increase indent |
Outdent | ExecuteCommandAsync(CommandName.Outdent) | Decrease indent |
InsertText | ExecuteCommandAsync(CommandName.InsertText, "text") | Insert plain text |
InsertHTML | ExecuteCommandAsync(CommandName.InsertHTML, "<b>hi</b>") | Insert HTML at cursor |
InsertOrderedList | ExecuteCommandAsync(CommandName.InsertOrderedList) | Start numbered list |
InsertUnorderedList | ExecuteCommandAsync(CommandName.InsertUnorderedList) | Start bullet list |
NumberFormatList | ExecuteCommandAsync(CommandName.NumberFormatList, "Decimal") | Styled numbered list |
BulletFormatList | ExecuteCommandAsync(CommandName.BulletFormatList, "Disc") | Styled bullet list |
RemoveFormat | ExecuteCommandAsync(CommandName.RemoveFormat) | Strip all formatting |
CreateLink | ExecuteCommandAsync(CommandName.CreateLink, new LinkCommandsArgs { Text="Link", Url="https://..." }) | Insert hyperlink |
InsertImage | ExecuteCommandAsync(CommandName.InsertImage, new ImageCommandsArgs { Url="...", CssClass="rte-img" }) | Insert image |
Undo | ExecuteCommandAsync(CommandName.Undo) | Undo last action |
Redo | ExecuteCommandAsync(CommandName.Redo) | Redo last undone action |
`ExecuteCommandOption`: Pass new ExecuteCommandOption { Undo = true } to ensure programmatic changes are tracked in the undo stack.
@code {
private async Task ApplyYellow()
{
await RteObj.ExecuteCommandAsync(
CommandName.BackgroundColor,
"yellow",
new ExecuteCommandOption { Undo = true });
}
}---
Slash Commands
Slash commands show a floating suggestion menu when the user types / at the start of a line.
Enabling with Built-in Items
<SfRichTextEditor Placeholder="Type / for commands">
<RichTextEditorSlashMenuSettings Enable="true" />
</SfRichTextEditor>Custom Slash Menu Items
Supply an Items list. Built-in items use SlashMenuCommand; custom items use freeform properties:
<SfRichTextEditor @ref="RteObj" Placeholder="Type '/' and choose format">
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorEvents SlashMenuItemSelecting="OnSlashSelect" />
<RichTextEditorSlashMenuSettings Enable="true" Items="@SlashItems" />
</SfRichTextEditor>
@code {
private SfRichTextEditor RteObj = default!;
private List<SlashMenuItemModel> SlashItems = new()
{
// Built-in items
new() { Command = SlashMenuCommand.Heading1 },
new() { Command = SlashMenuCommand.Heading2 },
new() { Command = SlashMenuCommand.Paragraph },
new() { Command = SlashMenuCommand.OrderedList },
new() { Command = SlashMenuCommand.UnorderedList },
new() { Command = SlashMenuCommand.Blockquote },
new() { Command = SlashMenuCommand.CodeBlock },
new() { Command = SlashMenuCommand.Table },
new() { Command = SlashMenuCommand.Image },
// Custom items
new() {
Text = "Meeting Notes",
GroupBy = "Custom",
IconCss = "e-icons e-description",
Description = "Insert a meeting note template."
},
new() {
Text = "Signature",
GroupBy = "Custom",
IconCss = "e-icons e-signature",
Description = "Insert a signature block."
}
};
private async Task OnSlashSelect(SlashMenuSelectEventArgs args)
{
string html = args.ItemData.Text switch
{
"Meeting Notes" => "<p><strong>Meeting Notes</strong></p><table>...</table>",
"Signature" => "<p>Warm regards,<br/>John Doe</p>",
_ => string.Empty
};
if (!string.IsNullOrEmpty(html))
await RteObj.ExecuteCommandAsync(CommandName.InsertHTML, html);
}
}`SlashMenuItemModel` properties:
| Property | Description |
|---|---|
Command | Built-in SlashMenuCommand value (built-in items only) |
Text | Display label |
GroupBy | Group header in the menu |
IconCss | CSS class for the icon |
Description | Short description shown below the label |
---
Enabling and Disabling Toolbar Items
Use EnableToolbarItemAsync / DisableToolbarItemAsync to toggle built-in or custom items at runtime:
<SfRichTextEditor @ref="RteObj">
<RichTextEditorToolbarSettings Items="@Tools">
<RichTextEditorCustomToolbarItems>
<RichTextEditorCustomToolbarItem Name="MyTool">
<Template><SfButton>Custom</SfButton></Template>
</RichTextEditorCustomToolbarItem>
</RichTextEditorCustomToolbarItems>
</RichTextEditorToolbarSettings>
</SfRichTextEditor>
@code {
private SfRichTextEditor RteObj = default!;
// Disable Bold and the custom "MyTool" item
private async Task DisableItems()
{
await RteObj.DisableToolbarItemAsync(new List<ToolbarItemModel>
{
new() { Command = ToolbarCommand.Bold },
new() { Name = "MyTool" } // use "Custom" command name for custom items
});
}
private async Task EnableItems()
{
await RteObj.EnableToolbarItemAsync(new List<ToolbarItemModel>
{
new() { Command = ToolbarCommand.Bold },
new() { Name = "MyTool" }
});
}
}For custom toolbar items, set Command = ToolbarCommand.Custom in the model passed to these methods to correctly target them during source-code-view and quick-toolbar operations.Data Binding
Table of Contents
- Two-way Binding with @bind-Value
- One-way Binding with Value
- Retrieving Content Programmatically
- Auto-save
- Character Count and Limits
- Read-only Mode
---
Two-way Binding with @bind-Value
@bind-Value keeps a C# string variable and the editor's HTML content in sync. Changes in the editor update the variable; changes to the variable update the editor:
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor @bind-Value="@Content" />
<!-- Live preview of bound value -->
<textarea rows="5" cols="60" @bind="@Content" />
@code {
private string Content { get; set; } = "<p>Start editing here.</p>";
}Valueacceptsstringtype and holds valid HTML (or Markdown whenEditorMode="Markdown").
---
One-way Binding with Value
Supply an initial HTML string via Value and handle changes with ValueChange when you need more control over when the bound state updates:
<SfRichTextEditor Value="@InitialContent">
<RichTextEditorEvents ValueChange="@OnChange" />
</SfRichTextEditor>
@code {
private string InitialContent = "<p>Default content.</p>";
private void OnChange(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args)
{
// args.Value holds the current editor HTML
// Save to DB, validate, etc.
InitialContent = args.Value;
}
}ValueChangefires when the editor loses focus or at the configuredSaveInterval. It does not fire on every keystroke — useOnActionCompletefor keystroke-level notifications.
---
Retrieving Content Programmatically
Use the @ref attribute and async API methods to pull content without waiting for a blur:
<SfRichTextEditor @ref="RteObj" @bind-Value="@Content">
<p>Type something here.</p>
</SfRichTextEditor>
<button @onclick="GetContent">Get Content</button>
@code {
private SfRichTextEditor RteObj = default!;
private string Content { get; set; } = string.Empty;
private async Task GetContent()
{
// Plain-text length (excludes HTML tags)
int charCount = await RteObj.GetCharCountAsync();
// Inner text (no tags)
string text = await RteObj.GetTextAsync();
// Full HTML string (same as Value)
string html = Content;
}
}---
Auto-save
Configure periodic or idle-triggered saving with SaveInterval and AutoSaveOnIdle:
| Property | Type | Default | Description |
|---|---|---|---|
SaveInterval | int | 10000 | Interval in ms at which ValueChange fires (or idle timeout when AutoSaveOnIdle is true) |
AutoSaveOnIdle | bool | false | When true, saves after the user stops typing for SaveInterval ms instead of on a fixed timer |
<SfRichTextEditor SaveInterval="5000" AutoSaveOnIdle="true" @bind-Value="@Content">
<RichTextEditorEvents ValueChange="@OnAutoSave" />
<p>Content is saved automatically after 5 s of idle time.</p>
</SfRichTextEditor>
@code {
private string Content { get; set; } = string.Empty;
private async Task OnAutoSave(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args)
{
Content = args.Value;
await MyService.PersistAsync(Content); // save to DB / local storage
}
}---
Character Count and Limits
Show a live character counter and optionally cap content length:
<SfRichTextEditor ShowCharCount="true" MaxLength="500" @bind-Value="@Content">
<p>This editor limits content to 500 characters.</p>
</SfRichTextEditor>
@code {
private string Content { get; set; } = string.Empty;
}| Property | Type | Default | Description |
|---|---|---|---|
ShowCharCount | bool | false | Displays a character counter in the bottom-right corner |
MaxLength | int | int.MaxValue | Hard cap on character count; typing stops at the limit |
---
Read-only Mode
Set Readonly="true" to display content without allowing edits. The toolbar is hidden automatically. Toggle it at runtime via state:
<SfRichTextEditor Readonly="@IsReadonly" @bind-Value="@Content">
<p>This content is read-only by default.</p>
</SfRichTextEditor>
<button @onclick="() => IsReadonly = !IsReadonly">Toggle Edit</button>
@code {
private bool IsReadonly = true;
private string Content { get; set; } = "<p>Saved content displayed here.</p>";
}In read-only mode the editor renders as a styled HTML container, preserving all formatting. Combine with EnableHtmlSanitizer="true" (the default) to prevent XSS when displaying user-supplied content.Editor Modes
Table of Contents
---
HTML Mode (Default)
EditorMode.HTML renders a contenteditable DIV. All toolbar formatting produces standard HTML tags. This is the default and requires no explicit configuration:
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor EditorMode="EditorMode.HTML">
<p>The Rich Text Editor is a WYSIWYG editor that returns <b>valid HTML</b>.</p>
<ul>
<li>Supports IFRAME and DIV modes</li>
<li>Modular toolbar</li>
<li>Markdown editing</li>
</ul>
</SfRichTextEditor>Value / @bind-Value contains the serialised HTML string.
---
IFrame Mode
IFrame mode renders the editing surface inside a sandboxed <iframe>, isolating its CSS from the host page. Use it when the host application's global styles would interfere with the editor content.
IFrame mode is enabled via the <RichTextEditorIFrameSettings Enable="true" /> child component nested inside <SfRichTextEditor>
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" />
<p>Editing in an isolated iframe — host-page styles do not bleed in.</p>
</SfRichTextEditor>Customizing IFrame Body Attributes
Pass additional attributes to the iframe body element using Attributes:
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" Attributes="@IframeAttributes" />
</SfRichTextEditor>
@code {
private Dictionary<string, object> IframeAttributes = new()
{
{ "style", "background: lightgray;" }
};
}Injecting External CSS and Scripts
Inject external stylesheets or scripts into the iframe document using Resources:
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" Resources="@Resources" />
</SfRichTextEditor>
@code {
private ResourcesModel Resources { get; set; } = new ResourcesModel()
{
Styles = new string[] { "/styles.css" },
Scripts = new string[] { "/script.js" }
};
}TheResourcesModelacceptsStyles(CSS paths) andScripts(JS paths) — both are string arrays resolved relative to the app root. Seeproperties.md → RichTextEditorIFrameSettingsfor the full child-component reference.
---
Markdown Mode
Set EditorMode="EditorMode.Markdown" to switch to Markdown editing. The editor input and Value property use Markdown syntax. A third-party library such as Marked.js must be added to the page to render a live HTML preview.
Supported block tags: h1–h6, blockquote, pre, p, ordered list (OL), unordered list (UL)
Supported inline tags: Bold, Italic, StrikeThrough, InlineCode, Subscript, Superscript, UpperCase, LowerCase
<SfRichTextEditor EditorMode="EditorMode.Markdown" @bind-Value="@MarkdownValue">
***Overview*** The Rich Text Editor supports Markdown editing mode.
***Key features***
*Mode*: Provides IFRAME and DIV mode.
*Toolbar*: Provide a fully customizable toolbar.
*Preview*: Preview the modified content before saving it.
</SfRichTextEditor>
@code {
private string MarkdownValue { get; set; } = string.Empty;
}Markdown Toolbar Items
For Markdown mode, use markdown-specific toolbar commands instead of the HTML defaults:
<RichTextEditorToolbarSettings Items="@MdTools" />
@code {
private List<ToolbarItemModel> MdTools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.StrikeThrough },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.OrderedList },
new() { Command = ToolbarCommand.UnorderedList },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Formats },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Preview }, // live HTML preview
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}Displaying a Markdown Preview
Security: Do not load Marked from external CDNs. Bundle locally instead.
Download marked.min.js and place it in wwwroot/lib/marked/:
<!-- wwwroot/index.html or Pages/_Host.cshtml -->
<script src="/lib/marked/marked.min.js"></script><SfRichTextEditor EditorMode="EditorMode.Markdown" @bind-Value="@MarkdownValue">
<RichTextEditorEvents ValueChange="@OnValueChange" />
</SfRichTextEditor>
<div @ref="PreviewDiv"></div>
@code {
private string MarkdownValue { get; set; } = string.Empty;
private ElementReference PreviewDiv;
[Inject] private IJSRuntime JS { get; set; } = default!;
private async Task OnValueChange(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args)
{
await JS.InvokeVoidAsync("renderMarkdown", PreviewDiv, args.Value);
}
}// wwwroot/app.js
function renderMarkdown(el, markdown) {
el.innerHTML = marked.parse(markdown ?? "");
}---
Source Code / HTML View
Add ToolbarCommand.SourceCode to the toolbar to give users an HTML source editor. This is available in HTML mode only — Markdown mode has a Preview button instead:
<RichTextEditorToolbarSettings Items="@Tools" />
@code {
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.SourceCode } // toggle HTML source view
};
}Toggling to source code view and back does not lose content. The WYSIWYG surface and source view stay in sync.
Events
Table of Contents
- Wiring Events
- Complete Event Reference
- Lifecycle Events
- Focus & Interaction
- Value & Content
- Toolbar Command Lifecycle
- Dialog Events
- Quick Toolbar Events
- Image Events
- Media Events
- Resize Events
- Toolbar Status Events
- Export Events
- Slash Menu Events
- Common Patterns
---
Wiring Events
All events are registered through the RichTextEditorEvents child component:
<SfRichTextEditor @bind-Value="@Content">
<RichTextEditorEvents
Created="@OnCreated"
ValueChange="@OnValueChange"
OnActionBegin="@OnActionBegin"
Blur="@OnBlur"
Focus="@OnFocus" />
</SfRichTextEditor>
@code {
private string Content { get; set; } = string.Empty;
private void OnCreated(object args) { /* editor is ready */ }
private void OnValueChange(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args) { Content = args.Value; }
private void OnActionBegin(ActionBeginEventArgs args) { /* before toolbar command executes */ }
private void OnBlur(BlurEventArgs args) { /* editor lost focus */ }
private void OnFocus(Syncfusion.Blazor.RichTextEditor.FocusEventArgs args) { /* editor gained focus */ }
}---
Complete Event Reference
Lifecycle Events
Created
Fires after the editor renders for the first time.
EventArgs: Object — no properties
---
Destroyed
Fires after the component is disposed.
EventArgs: DestroyedEventArgs — no properties (marker class)
---
Focus & Interaction
Focus
Fires when the editor gains focus.
EventArgs: `Syncfusion.Blazor.RichTextEditor.FocusEventArgs`
| Property | Type | Description |
|---|---|---|
IsInteracted | bool | true if focus was triggered by user interaction |
---
Blur
Fires when the editor loses focus.
EventArgs: `BlurEventArgs`
| Property | Type | Description |
|---|---|---|
IsInteracted | bool | true if blur was triggered by user interaction |
---
OnToolbarClick
Fires when a toolbar item is clicked.
EventArgs: `ToolbarClickEventArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the toolbar click action |
Item | Item? | Data for the clicked toolbar item |
OriginalEvent | object? | The underlying JavaScript event object |
RequestType | string? | Type of operation requested by the toolbar action |
---
SelectionChanged
Fires when the selection range changes (not fired for a collapsed cursor).
EventArgs: `SelectionChangedEventArgs`
| Property | Type | Description |
|---|---|---|
EditorMode | EditorMode | HTML or Markdown |
SelectedContent | string? | Full HTML markup of the current non-empty selection |
---
Value & Content
ValueChange
Fires on blur or at SaveInterval.
EventArgs: `Syncfusion.Blazor.RichTextEditor.ChangeEventArgs`
| Property | Type | Description |
|---|---|---|
Value | string? | Current HTML content of the editor |
---
BeforePasteCleanup
Fires before pasted content is sanitised.
EventArgs: `PasteCleanupArgs`
| Property | Type | Description |
|---|---|---|
Value | string? | The pasted content — modify to transform paste output |
FilesData | List<FileInfo>? | Image file data included in the paste |
---
AfterPasteCleanup
Fires after pasted content is sanitised.
EventArgs: `PasteCleanupArgs`
| Property | Type | Description |
|---|---|---|
Value | string? | The cleaned paste content |
FilesData | List<FileInfo>? | Image file data included in the paste |
---
Toolbar Command Lifecycle
OnActionBegin
Fires before a toolbar command executes.
EventArgs: `ActionBeginEventArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the action |
RequestType | string? | Name of the command being initiated |
ExportValue | string? | Content to export (set during export actions) |
---
OnActionComplete
Fires after a toolbar command completes.
EventArgs: `ActionCompleteEventArgs`
| Property | Type | Description |
|---|---|---|
EditorMode | string? | "HTML" or "Markdown" |
RequestType | string? | Name of the completed command |
---
Dialog Events
OnDialogOpen
Fires before a dialog opens (cancellable via args.Cancel).
EventArgs: `BeforeOpenEventArgs` (Syncfusion.Blazor.Popups — see Popups API)
---
DialogOpened
Fires after a dialog finishes opening.
EventArgs: DialogOpenEventArgs — no properties (marker class)
---
OnDialogClose
Fires before a dialog closes (cancellable via args.Cancel).
EventArgs: `BeforeCloseEventArgs` (Syncfusion.Blazor.Popups — see Popups API)
---
DialogClosed
Fires after a dialog has fully closed.
EventArgs: `DialogCloseEventArgs`
| Property | Type | Description |
|---|---|---|
IsInteracted | bool | true if the dialog was closed by user action |
---
Quick Toolbar Events
OnQuickToolbarOpen
Fires before the quick toolbar opens.
EventArgs: `BeforeQuickToolbarOpenArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to prevent the quick toolbar from opening |
PositionX | int | Horizontal position (deprecated) |
PositionY | int | Vertical position (deprecated) |
---
QuickToolbarOpened
Fires after the quick toolbar opens.
EventArgs: QuickToolbarEventArgs — no properties (marker class)
---
QuickToolbarClosed
Fires after the quick toolbar closes.
EventArgs: QuickToolbarEventArgs — no properties (marker class)
---
Image Events
OnImageSelected
Fires when an image is selected or dragged into the insert dialog.
EventArgs: `SelectedEventArgs` (Syncfusion.Blazor.Inputs — see Inputs API)
---
BeforeUploadImage
Fires before image upload begins (cancellable).
EventArgs: `ImageUploadingEventArgs` (inherits `FileUploadingEventArgs`)
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the upload |
CurrentRequest | object? | The XMLHttpRequest instance |
CustomFormData | object? | Extra key/value pairs to append to the upload |
FilesData | List<FileInfo>? | Files preparing for upload |
---
OnImageUploadSuccess
Fires when an image is successfully uploaded.
EventArgs: `ImageSuccessEventArgs` (inherits `FileUploadSuccessEventArgs`)
| Property | Type | Description |
|---|---|---|
DetectImageSource | ImageInputSource? | How the image arrived: Uploaded, Dropped, or Pasted |
DetectMediaSource | MediaInputSource? | How the media arrived: Uploaded, Dropped, or Pasted |
File | FileInfo? | Uploaded file details |
Operation | string? | Upload operation type |
Response | ResponseEventArgs? | HTTP response information |
StatusText | string? | Status message |
---
OnImageUploadFailed
Fires when an image upload fails.
EventArgs: `ImageFailedEventArgs` (inherits `FileUploadFailedEventArgs`)
| Property | Type | Description |
|---|---|---|
File | FileInfo? | Details of the failed file |
Operation | string? | Upload operation type |
Response | ResponseEventArgs? | HTTP response information |
StatusText | string? | Textual description of the failure |
---
ImageUploadChange
Fires when an image is uploaded and inserted into editor content.
EventArgs: `ImageUploadChangeEventArgs`
| Property | Type | Description |
|---|---|---|
ImageUrl | string? | Image URL inserted into the editor |
Files | List<UploadFiles>? | List of image files that were uploaded |
---
OnImageRemoving
Fires when an image is removed from the insert dialog.
EventArgs: `RemovingEventArgs` (Syncfusion.Blazor.Inputs — see Inputs API)
---
OnImageDrop
Fires when an image is being dropped into editor content (cancellable).
EventArgs: `BeforeImageDropEventArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to block the image drop/insert |
---
ImageDelete
Fires when an image is deleted from editor content.
EventArgs: `AfterImageDeleteEventArgs` (inherits `MediaDeletedEventArgs`)
| Property | Type | Description |
|---|---|---|
Src | string? | Source URL of the deleted image |
---
Media Events
FileSelected
Fires when media is selected or dragged into the insert media dialog.
EventArgs: `SelectedEventArgs` (Syncfusion.Blazor.Inputs — see Inputs API)
---
FileUploading
Fires when selected media begins uploading to the server.
EventArgs: `FileUploadingEventArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the upload |
CurrentRequest | object? | The XMLHttpRequest instance |
CustomFormData | object? | Extra key/value pairs to append to the upload |
FilesData | List<FileInfo>? | Files preparing for upload |
---
FileUploadSuccess
Fires when media is successfully uploaded.
EventArgs: `FileUploadSuccessEventArgs`
| Property | Type | Description |
|---|---|---|
DetectImageSource | ImageInputSource? | How the image arrived: Uploaded, Dropped, or Pasted |
DetectMediaSource | MediaInputSource? | How the media arrived: Uploaded, Dropped, or Pasted |
File | FileInfo? | Uploaded file details |
Operation | string? | Upload operation type |
Response | ResponseEventArgs? | HTTP response information |
StatusText | string? | Status message |
---
FileUploadFailed
Fires when a media upload fails.
EventArgs: `FileUploadFailedEventArgs`
| Property | Type | Description |
|---|---|---|
File | FileInfo? | Details of the failed file |
Operation | string? | Upload operation type |
Response | ResponseEventArgs? | HTTP response information |
StatusText | string? | Textual description of the failure |
---
FileUploadChange
Fires when media is uploaded and inserted into editor content.
EventArgs: `FileUploadChangeEventArgs`
| Property | Type | Description |
|---|---|---|
FileUrl | string? | Media URL inserted into the editor |
Files | List<UploadFiles>? | List of media files that were uploaded |
---
FileRemoving
Fires when selected media is removed from the upload location.
EventArgs: `RemovingEventArgs` (Syncfusion.Blazor.Inputs — see Inputs API)
---
OnMediaDrop
Fires when media files are dropped into the editor (cancellable).
EventArgs: `MediaDropEventArgs` (extends `DragEventArgs` — all standard drag/mouse properties inherited)
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to prevent the drop; default false |
MediaType | string? | "Image", "Video", "Audio", or null |
---
MediaDeleted
Fires when media is deleted from editor content.
EventArgs: `MediaDeletedEventArgs`
| Property | Type | Description |
|---|---|---|
Src | string? | Source URL of the deleted media element |
---
Resize Events
OnResizeStart
Fires when image resize begins.
EventArgs: `ResizeArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the resize |
RequestType | string? | Identifies this as a resize start event |
---
OnResizeStop
Fires when image resize ends.
EventArgs: `ResizeArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to cancel the resize completion |
RequestType | string? | Identifies this as a resize stop event |
---
Toolbar Status Events
UpdatedToolbarStatus
Fires when toolbar item states are updated.
EventArgs: `ToolbarStatusEventArgs`
| Property | Type | Description |
|---|---|---|
Html | HtmlStatus? | Active/inactive state of each HTML toolbar item |
Markdown | MarkdownStatus? | Active/inactive state of each Markdown toolbar item |
Redo | bool | true if redo is currently available |
Undo | bool | true if undo is currently available |
---
Export Events
OnExport
Fires before PDF/Word export request is sent.
EventArgs: `ExportingEventArgs`
| Property | Type | Description |
|---|---|---|
ExportType | string? | "Pdf" or "Word" |
RequestHeader | Dictionary<string, string>? | Custom HTTP headers (e.g. Authorization) |
CustomFormData | Dictionary<string, string>? | Additional form-data for the request body |
---
OnExportFailure
Fires when PDF/Word export HTTP request fails.
EventArgs: `ExportFailureEventArgs`
| Property | Type | Description |
|---|---|---|
ExportType | string? | "Word" or "Pdf" |
Message | string? | Error message, e.g. "HTTP error! Status: 404" |
StatusCode | int | HTTP status code, e.g. 404, 500 |
---
Slash Menu Events
SlashMenuItemSelecting
Fires when a slash command item is selected (cancellable).
EventArgs: `SlashMenuSelectEventArgs`
| Property | Type | Description |
|---|---|---|
Cancel | bool | Set true to prevent the slash command from executing |
ItemData | SlashMenuItemModel? | The slash menu item being selected |
---
Common Patterns
Auto-save with ValueChange
<SfRichTextEditor SaveInterval="3000" AutoSaveOnIdle="true">
<RichTextEditorEvents ValueChange="@SaveToDatabase" />
</SfRichTextEditor>
@code {
private async Task SaveToDatabase(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args)
{
await MyService.SaveContentAsync(args.Value);
}
}Cancel a Dialog with OnDialogOpen
<SfRichTextEditor>
<RichTextEditorEvents OnDialogOpen="@PreventImageDialog" />
</SfRichTextEditor>
@code {
private void PreventImageDialog(BeforeOpenEventArgs args)
{
// Cancel image insert dialog when in read-only context
args.Cancel = true;
}
}Delete Image from Server on ImageDelete
<SfRichTextEditor>
<RichTextEditorEvents ImageDelete="@OnImageDeleted" />
</SfRichTextEditor>
@code {
[Inject] private HttpClient Http { get; set; } = default!;
private async Task OnImageDeleted(AfterImageDeleteEventArgs args)
{
var fileName = Path.GetFileName(args.Src);
await Http.DeleteAsync($"/api/images/{fileName}");
}
}Intercept Toolbar Actions with OnActionBegin
<SfRichTextEditor>
<RichTextEditorEvents OnActionBegin="@LogAction" />
</SfRichTextEditor>
@code {
private void LogAction(ActionBeginEventArgs args)
{
Console.WriteLine($"Toolbar action: {args.Name}");
}
}Detect Text Selection with SelectionChanged
<SfRichTextEditor>
<RichTextEditorEvents SelectionChanged="@OnSelection" />
</SfRichTextEditor>
@code {
private void OnSelection(Syncfusion.Blazor.RichTextEditor.SelectionChangedEventArgs args)
{
// args.SelectedHTML contains the HTML of the selected range
}
}---
Event Args Reference
Complete property listing for every event argument class in Syncfusion.Blazor.RichTextEditor.
ActionBeginEventArgs
Used by: OnActionBegin
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to cancel the action before it executes |
RequestType | string? | get/set | Name of the command being initiated |
ExportValue | string? | get/set | Content to export during export actions |
ActionCompleteEventArgs
Used by: OnActionComplete
| Property | Type | Access | Description |
|---|---|---|---|
EditorMode | string? | get | "HTML" or "Markdown" |
RequestType | string? | get/set | Name of the completed command |
AfterImageDeleteEventArgs
Used by: ImageDelete — inherits all members from MediaDeletedEventArgs
| Property | Type | Access | Description |
|---|---|---|---|
Src | string? | get/set | Source URL of the deleted image (inherited) |
BeforeImageDropEventArgs
Used by: OnImageDrop
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to block the image drop/insert |
BeforeQuickToolbarOpenArgs
Used by: OnQuickToolbarOpen
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to prevent the quick toolbar from opening |
PositionX | int | get/set | Horizontal position (deprecated) |
PositionY | int | get/set | Vertical position (deprecated) |
BlurEventArgs
Used by: Blur
| Property | Type | Access | Description |
|---|---|---|---|
IsInteracted | bool | get/set | true if blur was triggered by user interaction |
Syncfusion.Blazor.RichTextEditor.ChangeEventArgs
Used by: ValueChange
| Property | Type | Access | Description |
|---|---|---|---|
Value | string? | get | Updated editor HTML content |
DestroyedEventArgs
Used by: Destroyed — no own properties (marker class).
DialogCloseEventArgs
Used by: DialogClosed
| Property | Type | Access | Description |
|---|---|---|---|
IsInteracted | bool | get | true if the dialog was closed by the user |
DialogOpenEventArgs
Used by: DialogOpened — no own properties (marker class).
ExportFailureEventArgs
Used by: OnExportFailure
| Property | Type | Access | Description |
|---|---|---|---|
ExportType | string? | get | "Word" or "Pdf" |
Message | string? | get/set | Error message, e.g. "HTTP error! Status: 404" |
StatusCode | int | get/set | HTTP status code, e.g. 404, 500; default 0 |
ExportingEventArgs
Used by: OnExport
| Property | Type | Access | Description |
|---|---|---|---|
ExportType | string? | get | "Pdf" or "Word" |
RequestHeader | Dictionary<string, string>? | get/set | Custom HTTP headers for the export request (e.g. Authorization) |
CustomFormData | Dictionary<string, string>? | get/set | Additional form-data key/value pairs for the request body |
FileUploadChangeEventArgs
Used by: FileUploadChange
| Property | Type | Access | Description |
|---|---|---|---|
FileUrl | string? | get/set | Media URL to insert into editor content |
Files | List<UploadFiles>? | get/set | List of media files ready for upload |
FileUploadFailedEventArgs
Used by: FileUploadFailed — base class for ImageFailedEventArgs
| Property | Type | Access | Description |
|---|---|---|---|
File | FileInfo? | get | Details of the failed file |
Operation | string? | get | Upload operation type |
Response | ResponseEventArgs? | get/set | HTTP response information |
StatusText | string? | get/set | Textual description of the failure |
FileUploadSuccessEventArgs
Used by: FileUploadSuccess — base class for ImageSuccessEventArgs
| Property | Type | Access | Description |
|---|---|---|---|
DetectImageSource | ImageInputSource? | get/set | How the image was provided: Uploaded, Dropped, or Pasted |
DetectMediaSource | MediaInputSource? | get/set | How the media was provided: Uploaded, Dropped, or Pasted |
File | FileInfo? | get/set | Uploaded file details |
Operation | string? | get | Upload operation type |
Response | ResponseEventArgs? | get/set | HTTP response information |
StatusText | string? | get | Status message |
FileUploadingEventArgs
Used by: FileUploading — base class for ImageUploadingEventArgs
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to cancel the upload |
CurrentRequest | object? | get/set | The XMLHttpRequest instance |
CustomFormData | object? | get/set | Extra key/value pairs to append to the upload request |
FilesData | List<FileInfo>? | get/set | Files preparing for upload |
Syncfusion.Blazor.RichTextEditor.FocusEventArgs
Used by: Focus
| Property | Type | Access | Description |
|---|---|---|---|
IsInteracted | bool | get/set | true if focus was triggered by user interaction |
ImageFailedEventArgs
Used by: OnImageUploadFailed — inherits all properties from FileUploadFailedEventArgs; no own properties.
ImageSuccessEventArgs
Used by: OnImageUploadSuccess — inherits all properties from FileUploadSuccessEventArgs; no own properties.
ImageUploadChangeEventArgs
Used by: ImageUploadChange
| Property | Type | Access | Description |
|---|---|---|---|
ImageUrl | string? | get/set | Image URL to insert into editor content |
Files | List<UploadFiles>? | get/set | List of image files for upload |
ImageUploadingEventArgs
Used by: BeforeUploadImage — inherits all properties from FileUploadingEventArgs; no own properties.
MediaDeletedEventArgs
Used by: MediaDeleted — base class for AfterImageDeleteEventArgs
| Property | Type | Access | Description |
|---|---|---|---|
Src | string? | get/set | Source URL of the deleted media element |
MediaDropEventArgs
Used by: OnMediaDrop — extends DragEventArgs (all standard mouse/drag properties inherited)
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to prevent the media drop; default false |
MediaType | string? | get/set | Type of dropped media: "Image", "Video", "Audio", or null |
PasteCleanupArgs
Used by: BeforePasteCleanup and AfterPasteCleanup
| Property | Type | Access | Description |
|---|---|---|---|
Value | string? | get/set | The pasted content (modify to transform paste output) |
FilesData | List<FileInfo>? | get/set | Image file data included in the paste |
QuickToolbarEventArgs
Used by: QuickToolbarOpened, QuickToolbarClosed — no own properties (marker class).
ResizeArgs
Used by: OnResizeStart, OnResizeStop
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to cancel the resize action |
RequestType | string? | get/set | Indicates whether this is a resize start or stop event |
SelectionChangedEventArgs
Used by: SelectionChanged
| Property | Type | Access | Description |
|---|---|---|---|
EditorMode | EditorMode | get | HTML or Markdown |
SelectedContent | string? | get | Full HTML markup of the current non-empty selection |
SlashMenuSelectEventArgs
Used by: SlashMenuItemSelecting
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to prevent the slash command from executing |
ItemData | SlashMenuItemModel? | get/set | The slash menu item being selected |
ToolbarClickEventArgs
Used by: OnToolbarClick
| Property | Type | Access | Description |
|---|---|---|---|
Cancel | bool | get/set | Set true to cancel the toolbar click action |
Item | Item? | get/set | Data for the clicked toolbar item |
OriginalEvent | object? | get/set | The underlying JavaScript event object |
RequestType | string? | get | Type of operation requested by the toolbar action |
ToolbarStatusEventArgs
Used by: UpdatedToolbarStatus
| Property | Type | Access | Description |
|---|---|---|---|
Html | HtmlStatus? | get/set | Active/inactive status of each HTML toolbar item |
Markdown | MarkdownStatus? | get/set | Active/inactive status of each Markdown toolbar item |
Redo | bool | get/set | true if redo is currently available |
Undo | bool | get/set | true if undo is currently available |
Getting Started with Syncfusion Blazor Rich Text Editor
Table of Contents
- NuGet Installation
- Service Registration
- Namespace Imports
- CSS and JS References
- Adding the Component
- Retrieving Content
---
NuGet Installation
Install two packages — the RTE component and a theme:
Visual Studio (Package Manager Console):
Install-Package Syncfusion.Blazor.RichTextEditor
Install-Package Syncfusion.Blazor.Themes.NET CLI:
dotnet add package Syncfusion.Blazor.RichTextEditor
dotnet add package Syncfusion.Blazor.Themes
dotnet restoreUse the same version for both packages to avoid compatibility issues.
---
Service Registration
Register the Syncfusion Blazor service in Program.cs before builder.Build():
using Syncfusion.Blazor;
// Blazor WebAssembly
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSyncfusionBlazor();
await builder.Build().RunAsync();
// Blazor Server
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSyncfusionBlazor();---
Namespace Imports
Add to _Imports.razor:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.RichTextEditor---
CSS and JS References
Blazor WebAssembly (wwwroot/index.html)
<head>
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
</head>
<body>
...
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>
<!-- Optional: standalone RTE script for better isolation -->
<!-- <script src="_content/Syncfusion.Blazor.RichTextEditor/scripts/sf-richtexteditor.min.js"></script> -->
</body>Blazor Server / Web App (App.razor or _Host.cshtml)
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>Available themes: bootstrap5.css | material.css | fluent.css | tailwind.css | fabric.css | material-dark.css
Blazor Web App (.NET 8+) — Render Mode
For interactive components in a Blazor Web App, add a render mode directive:
@rendermode InteractiveServer
@* or InteractiveWebAssembly / InteractiveAuto *@---
Adding the Component
Minimal usage
<SfRichTextEditor />With initial content and two-way binding
<SfRichTextEditor @bind-Value="@Content" />
@code {
private string Content { get; set; } = "<p>Hello, <b>World!</b></p>";
}With toolbar configured
<SfRichTextEditor @bind-Value="@Content">
<RichTextEditorToolbarSettings Items="@Tools" />
</SfRichTextEditor>
@code {
private string Content { get; set; } = string.Empty;
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.OrderedList },
new() { Command = ToolbarCommand.UnorderedList },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}---
Retrieving Content
Get HTML value (property)
The Value property always contains the current HTML:
<SfRichTextEditor @bind-Value="@HtmlContent" />
<p>Current HTML: @HtmlContent</p>
@code {
private string HtmlContent { get; set; } = string.Empty;
}Get plain text (method)
<SfRichTextEditor @ref="RteObj" />
<button @onclick="GetPlainText">Get Text</button>
@code {
private SfRichTextEditor RteObj;
private async Task GetPlainText()
{
string plainText = await RteObj.GetTextAsync();
Console.WriteLine(plainText);
}
}Get character count (method)
<SfRichTextEditor @ref="RteObj" />
<button @onclick="GetCount">Get Count</button>
@code {
private SfRichTextEditor RteObj;
private async Task GetCount()
{
double count = await RteObj.GetCharCountAsync();
Console.WriteLine($"Characters: {count}");
}
}Show character count in UI
<SfRichTextEditor @bind-Value="@Content" ShowCharCount="true" MaxLength="1000" />
@code {
private string Content { get; set; } = string.Empty;
}---
Common Setup Issues
| Problem | Fix |
|---|---|
| Styles not applied | Verify theme CSS is in <head>, not <body> |
| Component not rendering | Confirm AddSyncfusionBlazor() is called in Program.cs |
| Scripts not loading | Check syncfusion-blazor.min.js is at end of <body> |
| License warning in console | Register license key before builder.Build() |
| Not interactive in .NET 8 Web App | Add @rendermode InteractiveServer (or WASM/Auto) |
Images, Video, and Audio
Table of Contents
- Image Settings Properties
- Insert Image From URL
- Upload and Save Images Server-Side
- Image Save Format
- Image Restrictions
- Image Quick Toolbar
- Server-Side Delete on Image Removal
- Video Settings
- Audio Settings
---
Image Settings Properties
Security: Validate external media URLs against a whitelist of trusted domains before embedding.
Use RichTextEditorImageSettings to control image behaviour:
| Property | Type | Description |
|---|---|---|
AllowedTypes | List<string> | Allowed file extensions, e.g. new() { ".jpg", ".png", ".gif" } |
SaveUrl | string | API endpoint to receive the uploaded image |
Path | string | Server path prefix appended to saved file name (must be under wwwroot) |
SaveFormat | SaveFormat | Blob (default) or Base64 |
Display | ImageDisplay | Default display: Inline or Break |
Width / Height | string | Default dimensions when inserted |
MinWidth / MaxWidth | string | Resize constraints |
MinHeight / MaxHeight | string | Resize constraints |
EnableResize | bool | Whether to show resize handles (default true) |
ResizeByPercent | bool | Resize using percentage instead of pixel values |
MaxFileSize | double | Maximum upload file size in bytes |
---
Insert Image From URL
No configuration needed — the Image toolbar item opens a dialog where users can paste an online URL:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Image }
};
}If no SaveUrl or Path is set, locally browsed images are inserted as blob: URLs (temporary, lost on reload) or Base64, depending on SaveFormat.
---
Upload and Save Images Server-Side
Component:
<SfRichTextEditor>
<RichTextEditorImageSettings SaveUrl="api/Image/Save" Path="./Images/" />
<RichTextEditorToolbarSettings Items="@Tools" />
</SfRichTextEditor>Minimal ASP.NET Core controller:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using System.Net.Http.Headers;
[ApiController]
public class ImageController : ControllerBase
{
private readonly IWebHostEnvironment _env;
public ImageController(IWebHostEnvironment env) => _env = env;
[HttpPost("[action]")]
[Route("api/Image/Save")]
public void Save(IList<IFormFile> UploadFiles)
{
foreach (var file in UploadFiles)
{
string targetPath = Path.Combine(_env.ContentRootPath, "wwwroot", "Images");
Directory.CreateDirectory(targetPath);
string fileName = ContentDispositionHeaderValue
.Parse(file.ContentDisposition).FileName.Trim('"');
string fullPath = Path.Combine(targetPath, fileName);
if (!System.IO.File.Exists(fullPath))
{
using var fs = System.IO.File.Create(fullPath);
file.CopyTo(fs);
Response.StatusCode = 200;
}
else
{
Response.StatusCode = 204; // Already exists
}
}
}
}ThePathproperty must be a directory underwwwroot. You cannot save outsidewwwrootin Blazor static file serving.
---
Image Save Format
Force Base64 encoding (no server needed, but increases HTML payload size):
<SfRichTextEditor>
<RichTextEditorImageSettings SaveFormat="SaveFormat.Base64" />
</SfRichTextEditor>Use Base64 for: small images, self-contained HTML exports, prototyping. Use server save for: production apps, large images, long-term storage.
---
Image Restrictions
Limit file size (in bytes):
<SfRichTextEditor>
<RichTextEditorImageSettings MaxFileSize="5000000" AllowedTypes='new() { ".jpg", ".png", ".webp" }' />
</SfRichTextEditor>Size restriction only applies to file browse uploads, not to images pasted as hyperlinks.
---
Image Quick Toolbar
Show editing actions when a user clicks an inserted image:
<SfRichTextEditor>
<RichTextEditorQuickToolbarSettings Image="@ImageTools" />
</SfRichTextEditor>
@code {
private List<ImageToolbarItemModel> ImageTools = new()
{
new() { Command = ImageToolbarCommand.Replace },
new() { Command = ImageToolbarCommand.Align },
new() { Command = ImageToolbarCommand.Caption },
new() { Command = ImageToolbarCommand.Remove },
new() { Command = ImageToolbarCommand.HorizontalSeparator },
new() { Command = ImageToolbarCommand.OpenImageLink },
new() { Command = ImageToolbarCommand.EditImageLink },
new() { Command = ImageToolbarCommand.RemoveImageLink },
new() { Command = ImageToolbarCommand.HorizontalSeparator },
new() { Command = ImageToolbarCommand.Display },
new() { Command = ImageToolbarCommand.AltText },
new() { Command = ImageToolbarCommand.Dimension }
};
}---
Server-Side Delete on Image Removal
The ImageDelete event fires after an image is removed from the editor. Use it to delete the file from your server:
<SfRichTextEditor>
<RichTextEditorImageSettings
SaveUrl="api/Image/Save"
Path="./Images/"
RemoveUrl="api/Image/Delete" />
<RichTextEditorEvents ImageDelete="OnImageDeleted" />
</SfRichTextEditor>
@code {
@inject HttpClient Http
private async Task OnImageDeleted(AfterImageDeleteEventArgs args)
{
var fileName = args.Src.Split('/').Last();
var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(Array.Empty<byte>()), "UploadFiles", fileName);
await Http.PostAsync("api/Image/Delete", form);
}
}Without this handler, deleting an image in the editor only removes the <img> tag — the file remains on disk.---
Video Settings
Add ToolbarCommand.Video to the toolbar, then configure RichTextEditorVideoSettings:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorVideoSettings
SaveUrl="api/Video/Save"
Path="./Videos/"
AllowedTypes='new() { ".mp4", ".webm" }'
EnableResize="true"
Width="300px"
Height="200px" />
</SfRichTextEditor>Videos can also be inserted as embedded URLs (e.g. YouTube iframes) from the dialog — no upload needed.
Quick toolbar commands for video: Replace, Edit, Remove, Display, Dimension.
---
Audio Settings
Add ToolbarCommand.Audio to the toolbar, then configure RichTextEditorAudioSettings:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorAudioSettings
SaveUrl="api/Audio/Save"
Path="./Audio/"
AllowedTypes='new() { ".mp3", ".wav", ".ogg" }' />
</SfRichTextEditor>Audio can be inserted from a web URL or uploaded from the local machine.
Import and Export
Table of Contents
- Import HTML File
- Import Text File
- Import RTF File
- Import from Microsoft Word
- Export to Word (DOCX)
- Export to PDF
- Export to HTML / RTF Files
---
Import HTML File
Security: Always enable EnableHtmlSanitizer="true" when importing untrusted content. Validate file types and sizes server-side.Read an HTML file from the server with StreamReader and bind it to @bind-Value:
@using System.IO
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor @bind-Value="@HtmlContent" />
@code {
private string HtmlContent { get; set; } = string.Empty;
protected override void OnInitialized()
{
var path = Path.GetFullPath(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "HtmlFiles", "template.html"));
using var fs = File.Open(path, FileMode.Open, FileAccess.Read);
using var sr = new StreamReader(fs);
HtmlContent = sr.ReadToEnd();
}
}Set EnableHtmlSanitizer="false" when the imported HTML contains complex formatting you want to preserve exactly (trust the source).---
Import Text File
Read a .txt file on button click and load it as the editor's value:
@using System.IO
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor @bind-Value="@Content" EnableHtmlSanitizer="false" />
<button @onclick="ImportText">Import Text File</button>
@code {
private string Content { get; set; } = "<p>Click the button to import a text file.</p>";
private void ImportText()
{
var path = Path.GetFullPath(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "content.txt"));
using var fs = File.Open(path, FileMode.Open, FileAccess.Read);
using var sr = new StreamReader(fs);
Content = sr.ReadToEnd();
}
}---
Import RTF File
RTF import requires a file upload component and a server-side API that converts RTF to HTML and returns it in a response header:
@using Syncfusion.Blazor.RichTextEditor
@using Syncfusion.Blazor.Inputs
<SfRichTextEditor @bind-Value="@Content" EnableHtmlSanitizer="false">
<RichTextEditorImageSettings SaveUrl="api/images/save" Path="../images/" />
</SfRichTextEditor>
<SfUploader>
<UploaderAsyncSettings SaveUrl="api/import/rtf"
RemoveUrl="https://aspnetmvc.syncfusion.com/services/api/uploadbox/Remove" />
<UploaderEvents Success="@OnUploadSuccess" />
</SfUploader>
@code {
private string Content { get; set; } = "<div>Example — import an RTF file above.</div>";
private void OnUploadSuccess(SuccessEventArgs args)
{
// Server returns the converted HTML in a custom "rtevalue" response header
var headers = args.Response.Headers.ToString();
var parts = headers.Split("rtevalue: ");
Content = parts[1].Split("\r")[0];
}
}---
Import from Microsoft Word
Add ToolbarCommand.ImportWord to the toolbar and configure RichTextEditorImportWord with a service URL that converts DOCX → HTML server-side:
<SfRichTextEditor Height="400px">
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorImportWord
ServiceUrl="https://blazor.syncfusion.com/services/production/api/RichTextEditor/ImportFromWord"
MaxFileSize="10000000" /> <!-- 10 MB cap -->
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.ImportWord },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}Adding Auth Headers on Upload
Use the FileUploading event to inject custom form data (e.g., bearer tokens) before the file is sent:
<SfRichTextEditor>
<RichTextEditorEvents FileUploading="@OnFileUploading" />
<RichTextEditorImportWord ServiceUrl="api/word/import" />
</SfRichTextEditor>
@code {
private void OnFileUploading(FileUploadingEventArgs args)
{
args.CustomFormData = new List<object>
{
new { Authorization = "Bearer " + MyAuthService.Token }
};
}
}// Server-side controller (ASP.NET Core)
[HttpPost("api/word/import")]
public void ImportFromWord(IList<IFormFile> UploadFiles)
{
var token = Request.Form["Authorization"].ToString(); // retrieve custom header
// convert DOCX → HTML using Syncfusion.DocIO and return HTML in response header
}---
Export to Word (DOCX)
Add ToolbarCommand.ExportWord and configure a RichTextEditorExportWord tag pointing to a server endpoint that returns a .docx file:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorExportWord
ServiceUrl="https://blazor.syncfusion.com/services/production/api/RichTextEditor/ExportToDocx"
FileName="document.docx" />
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.ExportWord },
new() { Command = ToolbarCommand.ExportPdf },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic }
};
}Server-side controller (Syncfusion.DocIO):
[HttpPost("ExportToDocx")]
public FileStreamResult ExportToDocx([FromBody] ExportParam args)
{
using var document = new WordDocument();
document.EnsureMinimal();
document.HTMLImportSettings.ImageNodeVisited += OpenImage;
bool isValid = document.LastSection.Body.IsValidXHTML(args.Html, XHTMLValidationType.None);
if (isValid)
document.Sections[0].Body.Paragraphs[0].AppendHTML(args.Html);
document.HTMLImportSettings.ImageNodeVisited -= OpenImage;
var stream = new MemoryStream();
document.Save(stream, FormatType.Docx);
stream.Position = 0;
return File(stream, "application/msword", "Result.docx");
}---
Export to PDF
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorExportPdf
ServiceUrl="https://blazor.syncfusion.com/services/production/api/RichTextEditor/ExportToPdf"
FileName="document.pdf" />
</SfRichTextEditor>Server-side controller (Syncfusion.DocIO + DocIORenderer):
[HttpPost("ExportToPdf")]
public ActionResult ExportToPdf([FromBody] ExportParam args)
{
using var wordDoc = new WordDocument();
wordDoc.EnsureMinimal();
wordDoc.HTMLImportSettings.ImageNodeVisited += OpenImage;
wordDoc.LastParagraph.AppendHTML(args.Html);
var renderer = new DocIORenderer();
var pdfDocument = renderer.ConvertToPDF(wordDoc);
wordDoc.HTMLImportSettings.ImageNodeVisited -= OpenImage;
var stream = new MemoryStream();
pdfDocument.Save(stream);
return File(stream.ToArray(), "application/pdf", "document.pdf");
}
public class ExportParam { public string Html { get; set; } = string.Empty; }NuGet packages required:Syncfusion.DocIO.Net.Core,Syncfusion.DocIORenderer.Net.Core,Syncfusion.Pdf.Net.Core
---
Export to HTML / RTF Files
Export to HTML
Convert the Value string into a Word document and then save it as HTML using Syncfusion.DocIO:
public void ExportToHtml(string htmlValue)
{
// Convert HTML → WordDocument → HTML file
using var doc = GetWordDocument(htmlValue);
using var output = new FileStream("output.html", FileMode.Create);
doc.Save(output, FormatType.Html);
}Export to RTF
public async Task ExportToRtf(string htmlValue)
{
using var client = new HttpClient();
var content = new StringContent(htmlValue);
content.Headers.Add("value", htmlValue);
await client.PostAsync("api/export/rtf", content);
// trigger JS file download via IJSRuntime
}Inline Mode
Table of Contents
- Overview
- Enabling Inline Mode
- Show Toolbar on Selection Only
- Customising the Inline Toolbar Items
- Use Cases
---
Overview
Inline mode hides the toolbar by default and shows a floating toolbar when the user focuses or selects text inside the editor. It is ideal for in-place editing scenarios where the toolbar should not take up permanent screen real estate.
---
Enabling Inline Mode
Add <RichTextEditorInlineMode Enable="true" /> inside the editor. The toolbar appears as soon as the user clicks into the editable area:
@using Syncfusion.Blazor.RichTextEditor
<SfRichTextEditor>
<RichTextEditorInlineMode Enable="true" ShowOnSelection="false" />
<p>
The editor is in inline mode. Click anywhere in this text to reveal the
formatting toolbar.
</p>
</SfRichTextEditor>| Property | Type | Default | Description |
|---|---|---|---|
Enable | bool | false | Activates inline (floating) toolbar mode |
ShowOnSelection | bool | false | When true, toolbar only appears when text is selected (not on focus) |
---
Show Toolbar on Selection Only
Set ShowOnSelection="true" to keep the toolbar hidden until the user actually selects some text. This is the most unobtrusive option:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
<RichTextEditorInlineMode Enable="true" ShowOnSelection="true" />
<p>
Select any text in this paragraph to see the inline formatting toolbar appear
at the cursor.
</p>
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.CreateLink },
new() { Command = ToolbarCommand.Image }
};
}The floating toolbar anchors near the selection and repositions automatically when the user scrolls or the selection changes.
---
Customising the Inline Toolbar Items
Inline mode uses the same RichTextEditorToolbarSettings.Items list as regular mode. Limit the list to frequently used commands to keep the floating bar compact:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@InlineTools" />
<RichTextEditorInlineMode Enable="true" ShowOnSelection="true" />
<p>Rich in-place editing with a minimal floating toolbar.</p>
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> InlineTools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.StrikeThrough },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.FontColor },
new() { Command = ToolbarCommand.BackgroundColor },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Alignments },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.CreateLink },
new() { Command = ToolbarCommand.ClearFormat }
};
}---
Use Cases
| Scenario | Recommended Configuration |
|---|---|
| Blog post editor with minimal UI | Enable="true", ShowOnSelection="false" |
| Document viewer with in-place annotation | Enable="true", ShowOnSelection="true" |
| Comment / note editing inside a card | Enable="true", ShowOnSelection="true" + condensed Items list |
| Full-page content editor | Standard mode (no RichTextEditorInlineMode) |
Inline mode can be combined with a read-only initial state. UseReadonly="true"by default and programmatically toggle it on a double-click via@refto create a click-to-edit pattern.
<SfRichTextEditor @ref="Rte" Readonly="@IsReadonly" @ondblclick="EnableEdit">
<RichTextEditorInlineMode Enable="true" ShowOnSelection="true" />
<p>Double-click to start editing.</p>
</SfRichTextEditor>
@code {
private SfRichTextEditor Rte = default!;
private bool IsReadonly = true;
private void EnableEdit() => IsReadonly = false;
}````markdown
SfRichTextEditor – Public Methods
Table of Contents
- Focus & Selection
- Content Retrieval
- Command Execution
- Toolbar Control
- Dialog & UI Control
- Undo / Redo
- CommandName Enum Reference
- ToolbarCommand Enum Reference
- DialogType Enum Reference
---
Focus & Selection
`FocusAsync()` Sets the focus on the editor, enabling user interaction. Returns: Task
`FocusOutAsync()` Removes the focus from the editor. Returns: Task
`SaveSelectionAsync()` Saves the current selection range. Call before any async operation that might move focus, then restore with RestoreSelectionAsync(). Returns: Task
`RestoreSelectionAsync()` Restores the previously saved selection range. Returns: Task
`SelectAllAsync()` Selects all content in the editor. Returns: Task
`GetSelectionAsync()` Retrieves the HTML markup of the currently selected content. Returns: Task<string>
---
Content Retrieval
`GetTextAsync()` Gets the plain-text content of the editor (HTML tags stripped). Returns: Task<string>
`GetSelectedHtmlAsync()` Gets the HTML value of the selected content as a string. Returns: Task<string>
`GetCharCountAsync()` Retrieves the number of characters in the editor. Returns: Task<double>
`GetXhtmlAsync()` Retrieves XHTML-validated HTML content. Requires EnableXhtml="true". Returns: Task<string>
---
Command Execution
All ExecuteCommandAsync overloads take a CommandName value (see CommandName Enum Reference).
Simple command (no arguments)
await rteObj.ExecuteCommandAsync(CommandName.Bold);
await rteObj.ExecuteCommandAsync(CommandName.Undo);
await rteObj.ExecuteCommandAsync(CommandName.InsertParagraph);Command with a string value
// Insert raw HTML at the cursor
await rteObj.ExecuteCommandAsync(CommandName.InsertHTML, "<strong>Hello</strong>");
// Insert plain text
await rteObj.ExecuteCommandAsync(CommandName.InsertText, "typed text");Insert / edit an image
await rteObj.ExecuteCommandAsync(
CommandName.InsertImage,
new ImageCommandsArgs
{
Url = "https://example.com/photo.jpg",
AltText = "A photo",
Width = new CommandsWidth { Width = "300px", MaxWidth = "100%" },
Height = new CommandsHeight { Height = "200px" },
CssClass = "rounded"
}
);Insert / edit a link
await rteObj.ExecuteCommandAsync(
CommandName.CreateLink,
new LinkCommandsArgs
{
Url = "https://syncfusion.com",
Text = "Syncfusion",
Title = "Visit Syncfusion",
Target = "_blank"
}
);Insert a table
await rteObj.ExecuteCommandAsync(
CommandName.InsertTable,
new TableCommandsArgs { Rows = 3, Columns = 4 }
);Insert a video
await rteObj.ExecuteCommandAsync(
CommandName.Video,
new VideoCommandsArgs
{
Url = "https://example.com/video.mp4",
Width = new CommandsWidth { Width = "560px" },
Height = new CommandsHeight { Height = "315px" }
}
);Insert audio
await rteObj.ExecuteCommandAsync(
CommandName.Audio,
new AudioCommandsArgs { Url = "https://example.com/sound.mp3" }
);Insert a code block
await rteObj.ExecuteCommandAsync(
CommandName.InsertCodeBlock,
new CodeBlockCommandArgs { Language = "typescript", Label = "TypeScript" },
new ExecuteCommandOption { Undo = true }
);Format Painter
// Copy formatting from current selection
await rteObj.ExecuteCommandAsync(CommandName.CopyFormatPainter, new FormatPainterParams
{
Action = FormatPainterAction.CopyFormat
});
// Apply copied formatting to new selection
await rteObj.ExecuteCommandAsync(CommandName.ApplyFormatPainter, new FormatPainterParams
{
Action = FormatPainterAction.PasteFormat,
Options = new FormatPainterOptions
{
AllowedFormats = "b;strong;i;em;u",
DeniedFormats = "span[style]"
}
});`ExecuteCommandOption`
| Property | Type | Description |
|---|---|---|
Undo | bool | When true, the command is added to the undo stack so it can be reversed |
---
Toolbar Control
`EnableToolbarItem(List<ToolbarCommand>? items)` Enables the specified toolbar items, making them interactive.
rteObj.EnableToolbarItem(new List<ToolbarCommand>
{
ToolbarCommand.Bold,
ToolbarCommand.Italic
});`DisableToolbarItem(List<ToolbarCommand>? items)` Disables the specified toolbar items, preventing their use.
rteObj.DisableToolbarItem(new List<ToolbarCommand>
{
ToolbarCommand.Image,
ToolbarCommand.CreateTable
});`RemoveToolbarItem(List<ToolbarCommand> items)` Removes the specified toolbar items from the toolbar entirely.
rteObj.RemoveToolbarItem(new List<ToolbarCommand>
{
ToolbarCommand.FullScreen,
ToolbarCommand.Print
});---
Dialog & UI Control
`ShowDialogAsync(DialogType type)` Opens a specific insert/import dialog programmatically.
// Open the insert-image dialog
await rteObj.ShowDialogAsync(DialogType.InsertImage);`CloseDialogAsync(DialogType type)` Closes the specified dialog.
await rteObj.CloseDialogAsync(DialogType.InsertLink);`ShowInlineToolbarAsync()` / `HideInlineToolbarAsync()` Shows or hides the inline quick toolbar.
`ShowFullScreenAsync()` Expands the editor to fill the viewport (full-screen mode).
`ShowSourceCodeAsync()` Toggles the HTML/Markdown source code view.
`PrintAsync()` Opens the browser print dialog for the editor content.
`RefreshUIAsync()` Forces a UI refresh — useful after programmatic content changes.
---
Undo / Redo
`ClearUndoRedoAsync()` Clears both the undo and redo stacks and disables the undo/redo toolbar buttons. Use after loading new content programmatically to give the user a clean history.
// Load fresh content then reset history
rteObj.Value = "<p>New document</p>";
await rteObj.ClearUndoRedoAsync();---
CommandName Enum Reference
| Value | Description |
|---|---|
ApplyFormatPainter | Apply previously copied formatting |
Audio | Insert/manage audio |
BackgroundColor | Set text background color |
Blockquote | Toggle blockquote |
Bold | Toggle bold |
BulletFormatList | Insert bullet list |
Checklist | Insert checklist |
CopyFormatPainter | Copy formatting from selection |
CreateLink | Insert or edit a hyperlink |
EditImage | Edit an existing image |
EditLink | Edit an existing link |
ExportPdf | Export content to PDF |
ExportWord | Export content to Word |
FontColor | Set text color |
FontName | Set font family |
FontSize | Set font size |
FormatBlock | Apply block format |
Heading | Apply heading |
ImportWord | Import from Word |
Indent | Indent content |
InsertBrOnReturn | Insert <br> on Enter |
InsertCode | Insert inline code |
InsertCodeBlock | Insert code block with language |
InsertHTML | Insert raw HTML at cursor |
InsertHorizontalRule | Insert <hr> |
InsertImage | Insert an image |
InsertOrderedList | Insert numbered list |
InsertParagraph | Insert paragraph break |
InsertTable | Insert a table |
InsertText | Insert plain text at cursor |
InsertUnorderedList | Insert bullet list |
Italic | Toggle italic |
JustifyCenter | Center align |
JustifyFull | Justify align |
JustifyLeft | Left align |
JustifyRight | Right align |
Lowercase | Convert to lowercase |
NumberFormatList | Insert number format list |
Outdent | Outdent content |
Redo | Redo last undone action |
RemoveFormat | Clear all formatting |
StrikeThrough | Toggle strikethrough |
Subscript | Toggle subscript |
Superscript | Toggle superscript |
Underline | Toggle underline |
Undo | Undo last action |
Uppercase | Convert to uppercase |
Video | Insert/manage video |
---
ToolbarCommand Enum Reference
Used by EnableToolbarItem, DisableToolbarItem, RemoveToolbarItem.
| Value | Description |
|---|---|
Alignments | Alignment dropdown |
Audio | Audio insertion tool |
BackgroundColor | Background colour picker |
Blockquote | Blockquote toggle |
Bold | Bold toggle |
BulletFormatList | Bullet format list |
Checklist | Checklist tool |
ClearFormat | Clear formatting |
CodeBlock | Code block insertion |
CreateLink | Insert/edit link |
CreateTable | Insert table |
ExportPdf | Export to PDF |
ExportWord | Export to Word |
FontColor | Font colour picker |
FontName | Font family selector |
FontSize | Font size selector |
FormatPainter | Format Painter tool |
Formats | Format block dropdown |
FullScreen | Full-screen toggle |
HorizontalLine | Insert horizontal rule |
HorizontalSeparator | Toolbar separator |
Image | Image insertion tool |
ImportWord | Import Word document |
Indent | Indent |
InlineCode | Inline code |
InsertCode | Insert code |
Italic | Italic toggle |
LineHeight | Line height selector |
LowerCase | Convert to lowercase |
Maximize | Maximize |
Minimize | Minimize |
NumberFormatList | Number format list |
OrderedList | Ordered list |
Outdent | Outdent |
Preview | Preview mode |
Print | |
Redo | Redo |
RemoveLink | Remove hyperlink |
Separator | Toolbar separator |
SourceCode | HTML source view |
StrikeThrough | Strikethrough |
SubScript | Subscript |
SuperScript | Superscript |
Underline | Underline |
Undo | Undo |
UnorderedList | Unordered list |
UpperCase | Convert to uppercase |
Video | Video insertion tool |
---
DialogType Enum Reference
Used by ShowDialogAsync and CloseDialogAsync.
| Value | Description |
|---|---|
ImportWord | Word document import dialog |
InsertAudio | Audio insertion dialog |
InsertImage | Image insertion dialog |
InsertLink | Hyperlink insertion dialog |
InsertTable | Table insertion dialog |
InsertVideo | Video insertion dialog |
````
Paste and Cleanup
Table of Contents
- Paste Cleanup Settings
- Paste Modes
- Denied Tags and Attributes
- Allowed Style Properties
- Accessing Pasted Content
- Pasting Large Content (SignalR Buffer)
- Enter Key Behaviour
- Undo / Redo Manager
---
Paste Cleanup Settings
Security: Always keepEnableHtmlSanitizer="true"when accepting untrusted content. UseDeniedTagsto blockscript,iframe,object,embed.
The RichTextEditorPasteCleanupSettings child component controls how content pasted from Word, Outlook, Excel, or other websites is sanitised before insertion.
| Property | Type | Default | Description |
|---|---|---|---|
Prompt | bool | false | Show a dialog offering Keep / Clean / Plain Text options |
PlainText | bool | false | Strip all tags and paste as plain text |
KeepFormat | bool | true | Retain the source formatting (filtered by AllowedStyleProperties) |
DeniedTags | string[] | null | HTML tags to remove from pasted content |
DeniedAttributes | string[] | null | HTML attributes to strip from pasted content |
AllowedStyleProperties | string[] | (extensive list) | CSS properties to preserve when KeepFormat is true |
Mutual exclusivity rules:
-Prompt = trueoverridesPlainTextandKeepFormat
-PlainText = truerequiresPrompt = false; ignoresKeepFormatandAllowedStyleProperties
-AllowedStylePropertiesis only applied whenKeepFormat = true
---
Paste Modes
Prompt Dialog
Lets the user choose how to paste each time:
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings Prompt="true" />
</SfRichTextEditor>Prompt options: 1. Keep — preserve source formatting (respects AllowedStyleProperties / DeniedTags) 2. Clean — strip inline styles, keep structural tags 3. Plain Text — discard all markup
Plain Text
Always paste without any markup:
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings PlainText="true" Prompt="false" />
</SfRichTextEditor>Keep Format (Default)
Retain source formatting filtered through the allowed-style list:
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings KeepFormat="true" PlainText="false" Prompt="false" />
</SfRichTextEditor>Clean Format
Strip all inline styles but keep structural HTML tags (<p>, <ul>, <table>, etc.):
<!-- All three flags false = clean format -->
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings Prompt="false" PlainText="false" KeepFormat="false" />
</SfRichTextEditor>---
Denied Tags and Attributes
Remove specific tags or attributes from pasted content:
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings
DeniedTags="@DeniedTags"
DeniedAttributes="@DeniedAttrs" />
</SfRichTextEditor>
@code {
// "a" → remove all anchor tags
// "a[!href]" → remove anchors that have no href
// "a[href,target]" → remove anchors that have href AND target
private string[] DeniedTags = new[] { "a[!href]", "script", "style" };
private string[] DeniedAttrs = new[] { "class", "id", "title" };
}DeniedTagsandDeniedAttributesapply in both KeepFormat and Clean Format modes, but not whenPlainText = true(plain text already has no tags).
---
Allowed Style Properties
Restrict which CSS properties survive when KeepFormat = true:
<SfRichTextEditor>
<RichTextEditorPasteCleanupSettings
KeepFormat="true"
AllowedStyleProperties="@AllowedStyles" />
</SfRichTextEditor>
@code {
// Only colour and font-size will be preserved; all other inline styles are removed
private string[] AllowedStyles = new[] { "color", "font-size", "font-weight" };
}---
Accessing Pasted Content
Use the AfterPasteCleanup event to inspect or modify the cleaned HTML after it has been sanitised but before it is committed:
<SfRichTextEditor>
<RichTextEditorEvents AfterPasteCleanup="@OnPasted" />
</SfRichTextEditor>
@code {
private void OnPasted(PasteCleanupArgs args)
{
// args.Value holds the sanitised HTML string
Console.WriteLine("Pasted HTML: " + args.Value);
}
}---
Pasting Large Content (SignalR Buffer)
Pasting large blocks of text over SignalR can trigger a reconnect warning. Increase the maximum receive message size in Program.cs:
// Blazor Server (Program.cs)
builder.Services.AddSignalR(options =>
{
options.MaximumReceiveMessageSize = 1_024_000_000; // ~1 GB
});// Blazor WebAssembly (Program.cs)
builder.Services.AddSignalR(options =>
{
options.MaximumReceiveMessageSize = 1_024_000_000;
});
await builder.Build().RunAsync();---
Enter Key Behaviour
Customise the HTML tag inserted when Enter or Shift+Enter is pressed:
| Property | Default | Options | Description |
|---|---|---|---|
EnterKey | EnterKeyTag.P | P, DIV, BR | Tag created on Enter |
ShiftEnterKey | ShiftEnterKeyTag.BR | BR, P, DIV | Tag created on Shift+Enter |
<SfRichTextEditor EnterKey="EnterKeyTag.DIV" ShiftEnterKey="ShiftEnterKeyTag.P">
<div>Pressing Enter inserts a DIV; Shift+Enter inserts a P.</div>
</SfRichTextEditor>Inside a<pre>(code block) tag, Enter always inserts<br>regardless ofEnterKey. Press Enter twice to exit the<pre>block.
---
Undo / Redo Manager
Configure Steps and Timer
<SfRichTextEditor UndoRedoSteps="50" UndoRedoTimer="400">
<!-- Keeps 50 undo steps, records every 400 ms -->
</SfRichTextEditor>| Property | Default | Description |
|---|---|---|
UndoRedoSteps | 30 | Number of undo/redo history entries to retain; set to 0 to disable |
UndoRedoTimer | 300 | Interval (ms) between undo history snapshots |
Clear the Stack Programmatically
<SfRichTextEditor @ref="Rte">
<p>Editor content here.</p>
</SfRichTextEditor>
<button @onclick="ClearHistory">Clear History</button>
@code {
private SfRichTextEditor Rte = default!;
private async Task ClearHistory()
{
await Rte.ClearUndoRedoAsync();
}
}Track Custom Tool Actions in Undo Stack
Pass ExecuteCommandOption { Undo = true } to include programmatic insertions in the undo history:
@code {
private async Task InsertTemplate()
{
await Rte.ExecuteCommandAsync(
CommandName.InsertHTML,
"<p><strong>Template text</strong></p>",
new ExecuteCommandOption { Undo = true });
}
}````markdown
SfRichTextEditor – Properties Reference
Table of Contents
- Content & Value
- Editor Behaviour
- Appearance & Layout
- Security & Sanitization
- Keyboard & Shortcuts
- Persistence & Auto-Save
- Undo / Redo
- Full Property Summary Table
---
Content & Value
Value — string? — default: null
Current HTML (or Markdown) content of the editor. Use @bind-Value for two-way binding.
<SfRichTextEditor @bind-Value="@HtmlContent" />
@code {
private string HtmlContent { get; set; } = "<p>Start editing…</p>";
}Placeholder — string? — default: ""
Text shown when the editor has no content. Disappears on focus.
<SfRichTextEditor Placeholder="Start to type…" />Readonly — bool — default: false
When true, the editor content cannot be changed by user interaction. You can still update Value programmatically.
<SfRichTextEditor Value="@HtmlContent" Readonly="true">
<RichTextEditorToolbarSettings Enable="false" />
</SfRichTextEditor>Enabled — bool — default: true
When false, the entire editor is disabled and non-interactive.
MaxLength — int — default: -1 (no limit)
Maximum characters allowed. Excess content is truncated on paste. Pair with ShowCharCount to give visual feedback.
<SfRichTextEditor MaxLength="2000" ShowCharCount="true" />ShowCharCount — bool — default: false
Displays a character counter at the bottom of the editor.
ChildContent — RenderFragment? — default: null
Embed child components (toolbar settings, events, image settings, etc.) as nested Razor tags.
---
Editor Behaviour
EditorMode — EditorMode — default: EditorMode.HTML
Switches between HTML WYSIWYG mode and Markdown editing mode.
<!-- Markdown mode -->
<SfRichTextEditor EditorMode="EditorMode.Markdown" @bind-Value="@MarkdownContent" />| Value | Behaviour |
|---|---|
HTML | WYSIWYG HTML editing (default) |
Markdown | Raw Markdown editing with syntax support |
EnterKey — EnterKeyTag — default: EnterKeyTag.P
HTML tag inserted when Enter is pressed.
| Value | Tag inserted |
|---|---|
P (default) | <p> |
DIV | <div> |
BR | <br> |
ShiftEnterKey — ShiftEnterKeyTag — default: ShiftEnterKeyTag.BR
HTML tag inserted when Shift + Enter is pressed.
| Value | Tag inserted |
|---|---|
BR (default) | <br> |
P | <p> |
DIV | <div> |
EnableTabKey — bool — default: false
When true, pressing Tab inserts a tab space inside the content instead of moving focus.
EnableAutoUrl — bool — default: false
When false (default), typed relative URLs are auto-prefixed with https://. Set to true to accept URLs as-is without validation.
EnableMarkdownAutoFormat — bool — default: true
Auto-converts Markdown shortcodes (e.g., **text** → bold) during typing and paste in Markdown mode.
EnableClipboardCleanup — bool — default: true
Intercepts copy and cut operations to strip unwanted inline styles from clipboard content.
EnableXhtml — bool — default: false
Enforces XHTML-valid output. Use GetXhtmlAsync() to retrieve the validated content.
EnableHtmlEncode — bool — default: false
Displays source code in HTML-encoded format (applies to HTML mode only).
EnableResize — bool — default: false
Enables a resize handle on the editor content area.
---
Child Component Settings
RichTextEditorIFrameSettings — child component
Renders the editor content area inside a sandboxed <iframe>, isolating it from the host page's global CSS and scripts. Nest this component directly inside <SfRichTextEditor>.
⚠️ Do NOT use `EnableIFrame="true"` on `SfRichTextEditor` — that attribute does not exist. IFrame mode is configured exclusively through <RichTextEditorIFrameSettings>.Basic usage:
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" />
</SfRichTextEditor>Properties of `RichTextEditorIFrameSettings`:
| Property | Type | Default | Description |
|---|---|---|---|
Enable | bool | false | Activates iframe editing mode |
Attributes | Dictionary<string, object>? | null | Additional HTML attributes applied to the iframe <body> element |
Resources | ResourcesModel? | null | External CSS/JS files to inject into the iframe document |
`ResourcesModel` properties:
| Property | Type | Description |
|---|---|---|
Styles | string[] | Paths to external CSS files (resolved from app root) |
Scripts | string[] | Paths to external JS files (resolved from app root) |
With custom body attributes:
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" Attributes="@IframeAttributes" />
</SfRichTextEditor>
@code {
private Dictionary<string, object> IframeAttributes = new()
{
{ "style", "background: lightgray;" }
};
}With injected styles and scripts:
<SfRichTextEditor>
<RichTextEditorIFrameSettings Enable="true" Resources="@Resources" />
</SfRichTextEditor>
@code {
private ResourcesModel Resources { get; set; } = new ResourcesModel()
{
Styles = new string[] { "/editor-content.css" },
Scripts = new string[] { "/editor-extensions.js" }
};
}---
Appearance & Layout
Height — string — default: "auto"
Sets the editor height in pixels or percentage.
<SfRichTextEditor Height="400px" />
<SfRichTextEditor Height="60%" />Width — string — default: "100%"
Sets the editor width.
<SfRichTextEditor Width="800px" />CssClass — string? — default: ""
One or more custom CSS classes (space-separated) for styling the editor container.
ShowTooltip — bool — default: true
Controls whether tooltips are shown for toolbar and inline toolbar items.
FloatingToolbarOffset — double — default: 0
Top offset (px) to preserve the floating toolbar position during page scroll.
---
Security & Sanitization
EnableHtmlSanitizer — bool — default: true
Sanitizes editor content to prevent XSS attacks. Keep true in production.
AdditionalSanitizeAttributes — List<SanitizeAttribute>?
Specify additional element+attribute pairs to be removed during sanitization.
<SfRichTextEditor EnableHtmlSanitizer="true"
AdditionalSanitizeAttributes="@sanitizeAttrs" />
@code {
private List<SanitizeAttribute> sanitizeAttrs = new()
{
new SanitizeAttribute { Selector = "span", Attribute = "style" }
};
}`SanitizeAttribute` properties:
| Property | Type | Description |
|---|---|---|
Selector | string? | CSS selector for the target elements |
Attribute | string? | Attribute name to be removed from matched elements |
AdditionalSanitizeTags — string[]?
Extra tag names to add to the block list (prevent insertion).
<SfRichTextEditor AdditionalSanitizeTags="@(new[] { "script", "style" })" />DeniedSanitizeSelectors — string[]?
Remove selectors from the default sanitization list to allow them in content.
<!-- Allow iframes from known sources -->
<SfRichTextEditor DeniedSanitizeSelectors="@(new[] { "iframe[src]" })" />Default sanitized selectors include: script, iframe[src], link[href*="javascript:"], and several others.
---
Keyboard & Shortcuts
KeyConfigure — ShortcutKeys?
Customize keyboard shortcuts for editor operations.
<SfRichTextEditor KeyConfigure="@shortcutKeys" />
@code {
ShortcutKeys shortcutKeys = new() { Bold = "ctrl+d", Italic = "ctrl+m" };
}`ShortcutKeys` default bindings (key selections):
| Property | Default |
|---|---|
Bold | ctrl+b |
Italic | ctrl+i |
Underline | ctrl+u |
Undo | ctrl+z |
Redo | ctrl+y |
InsertLink | ctrl+k |
InsertImage | ctrl+shift+i |
InsertTable | ctrl+shift+e |
FullScreen | ctrl+shift+f |
HtmlSource | ctrl+shift+h |
FormatCopy | alt+shift+c |
FormatPaste | alt+shift+v |
ToolbarFocus | alt+f10 |
All 28 shortcut keys can be overridden. See property.md for the full list.
ID — string?
Unique identifier for the component. Required when using multiple editors on one page.
HttpClientInstance — HttpClient? — default: null
Custom HttpClient for all upload/import/export requests. Configure headers (e.g., Authorization) on the injected instance.
@inject HttpClient httpClient
<SfRichTextEditor HttpClientInstance="@httpClient">
<RichTextEditorImageSettings SaveUrl="https://api.example.com/upload" />
</SfRichTextEditor>---
Persistence & Auto-Save
EnablePersistence — bool — default: false
Saves Value to browser localStorage and restores it on page reload.
SaveInterval — double — default: 10000 (ms)
Interval in milliseconds after which ValueChange fires if content was modified. Used with AutoSaveOnIdle.
AutoSaveOnIdle — bool — default: false
When true, triggers a save after the editor has been idle for SaveInterval ms.
<!-- Auto-save every 5s of idle time -->
<SfRichTextEditor SaveInterval="5000" AutoSaveOnIdle="true">
<RichTextEditorEvents ValueChange="@OnSave" />
</SfRichTextEditor>---
Undo / Redo
UndoRedoSteps — int — default: 30
Maximum number of undo/redo history steps retained.
<SfRichTextEditor UndoRedoSteps="50" />UndoRedoTimer — int — default: 300 (ms)
Idle time in milliseconds after typing stops before a new undo checkpoint is created.
<!-- Capture undo points faster while typing -->
<SfRichTextEditor UndoRedoTimer="150" />---
Full Property Summary Table
| # | Property | Type | Default |
|---|---|---|---|
| 1 | AdditionalSanitizeAttributes | List<SanitizeAttribute>? | empty list |
| 2 | AdditionalSanitizeTags | string[]? | empty array |
| 3 | AutoSaveOnIdle | bool | false |
| 4 | ChildContent | RenderFragment? | null |
| 5 | CssClass | string? | "" |
| 6 | DeniedSanitizeSelectors | string[]? | empty array |
| 7 | EditorMode | EditorMode | HTML |
| 8 | EnableAutoUrl | bool | false |
| 9 | EnableClipboardCleanup | bool | true |
| 10 | EnableHtmlEncode | bool | false |
| 11 | EnableHtmlSanitizer | bool | true |
| 12 | EnableMarkdownAutoFormat | bool | true |
| 13 | EnablePersistence | bool | false |
| 14 | EnableResize | bool | false |
| 15 | EnableRtl | bool | false |
| 16 | EnableTabKey | bool | false |
| 17 | EnableXhtml | bool | false |
| 18 | Enabled | bool | true |
| 19 | EnterKey | EnterKeyTag | P |
| 20 | FloatingToolbarOffset | double | 0 |
| 21 | Height | string | "auto" |
| 22 | HttpClientInstance | HttpClient? | null |
| 23 | ID | string? | "" |
| 24 | KeyConfigure | ShortcutKeys? | built-in defaults |
| 25 | MaxLength | int | -1 |
| 26 | Placeholder | string? | "" |
| 27 | Readonly | bool | false |
| 28 | RichTextEditorIFrameSettings | child component | Enable=false — see ## Child Component Settings |
| 29 | SaveInterval | double | 10000 ms |
| 30 | ShiftEnterKey | ShiftEnterKeyTag | BR |
| 31 | ShowCharCount | bool | false |
| 32 | ShowTooltip | bool | true |
| 33 | UndoRedoSteps | int | 30 |
| 34 | UndoRedoTimer | int | 300 ms |
| 35 | Value | string? | — |
| 36 | ValueChanged | EventCallback<string?> | — |
| 37 | ValueExpression | Expression<Func<string?>>? | — |
| 38 | Width | string | "100%" |
````
Toolbar Configuration in Blazor Rich Text Editor
Table of Contents
- Enabling / Disabling the Toolbar
- Toolbar Types
- Floating Toolbar
- Toolbar Position
- Configuring Toolbar Items
---
Enabling / Disabling the Toolbar
Enable — bool — default: true
Specifies whether to render the toolbar in the Rich Text Editor. When set to false, the toolbar is hidden entirely and no editing controls are displayed.
Hide the toolbar (render editor without any toolbar):
<SfRichTextEditor>
<RichTextEditorToolbarSettings Enable="false" />
</SfRichTextEditor>Show the toolbar (default behaviour — no need to set explicitly):
<SfRichTextEditor>
<RichTextEditorToolbarSettings Enable="true" />
</SfRichTextEditor>Tip: UseEnable="false"for read-only display scenarios. For a fully non-interactive editor, combine withReadonly="true"onSfRichTextEditor.
<!-- Read-only editor with no toolbar -->
<SfRichTextEditor Value="@HtmlContent" Readonly="true">
<RichTextEditorToolbarSettings Enable="false" />
</SfRichTextEditor>---
Toolbar Types
Set the toolbar layout using RichTextEditorToolbarSettings.Type. Four types are available:
Expand (default)
Overflowing items are hidden and revealed via an expand arrow:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Type="ToolbarType.Expand" />
</SfRichTextEditor>MultiRow
All items always visible across multiple rows:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Type="ToolbarType.MultiRow" />
</SfRichTextEditor>Scrollable
Single row with horizontal scrolling for overflow items:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Type="ToolbarType.Scrollable" />
</SfRichTextEditor>Popup
Items overflow into a popup container — good for limited screen space:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Type="ToolbarType.Popup" />
</SfRichTextEditor>Choosing a type: UseExpandfor most apps. UseMultiRowwhen you want all tools always visible. UseScrollableon mobile-friendly layouts. UsePopupfor very compact UIs.
---
Floating Toolbar
By default, the toolbar floats (stays visible) when scrolling through a tall editor. Control this with EnableFloating and FloatingToolbarOffset.
Disable floating (toolbar scrolls away with content):
<SfRichTextEditor Height="800px">
<RichTextEditorToolbarSettings EnableFloating="false" />
</SfRichTextEditor>Float with offset from top of viewport (e.g., to clear a fixed header):
<SfRichTextEditor Height="800px">
<RichTextEditorToolbarSettings EnableFloating="true" />
<!-- FloatingToolbarOffset is a property on SfRichTextEditor, not toolbar settings -->
</SfRichTextEditor><SfRichTextEditor Height="800px" FloatingToolbarOffset="60">
<RichTextEditorToolbarSettings EnableFloating="true" />
</SfRichTextEditor>Set FloatingToolbarOffset to match your fixed header height (in pixels) to prevent toolbar overlap.---
Toolbar Position
Place the toolbar above or below the content area:
Bottom toolbar:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Position="ToolbarPosition.Bottom" />
</SfRichTextEditor>Top toolbar (default):
<SfRichTextEditor>
<RichTextEditorToolbarSettings Position="ToolbarPosition.Top" />
</SfRichTextEditor>Bottom toolbar is useful for chat-style or mobile editors where the content should lead.
---
Configuring Toolbar Items
Use RichTextEditorToolbarSettings.Items to define which tools appear and in what order. Each item is a ToolbarItemModel.
Standard item:
new ToolbarItemModel() { Command = ToolbarCommand.Bold }Separator (visual divider between groups):
new ToolbarItemModel() { Command = ToolbarCommand.Separator }Full example with grouped items:
<SfRichTextEditor>
<RichTextEditorToolbarSettings Items="@Tools" />
</SfRichTextEditor>
@code {
private List<ToolbarItemModel> Tools = new()
{
// Text formatting group
new() { Command = ToolbarCommand.Bold },
new() { Command = ToolbarCommand.Italic },
new() { Command = ToolbarCommand.Underline },
new() { Command = ToolbarCommand.Separator },
// Font group
new() { Command = ToolbarCommand.FontName },
new() { Command = ToolbarCommand.FontSize },
new() { Command = ToolbarCommand.FontColor },
new() { Command = ToolbarCommand.BackgroundColor },
new() { Command = ToolbarCommand.Separator },
// Block group
new() { Command = ToolbarCommand.Formats },
new() { Command = ToolbarCommand.Alignments },
new() { Command = ToolbarCommand.OrderedList },
new() { Command = ToolbarCommand.UnorderedList },
new() { Command = ToolbarCommand.Separator },
// Insert group
new() { Command = ToolbarCommand.CreateLink },
new() { Command = ToolbarCommand.Image },
new() { Command = ToolbarCommand.CreateTable },
new() { Command = ToolbarCommand.Separator },
// Utility group
new() { Command = ToolbarCommand.SourceCode },
new() { Command = ToolbarCommand.FullScreen },
new() { Command = ToolbarCommand.Separator },
new() { Command = ToolbarCommand.Undo },
new() { Command = ToolbarCommand.Redo }
};
}Adding a custom toolbar item
Custom items use the Name property and require a matching RichTextEditorCustomToolbarItem:
<SfRichTextEditor @ref="RteObj">
<RichTextEditorToolbarSettings Items="@Tools">
<RichTextEditorCustomToolbarItems>
<RichTextEditorCustomToolbarItem Name="MyTool">
<Template>
<button @onclick="OnMyToolClick">★ Star</button>
</Template>
</RichTextEditorCustomToolbarItem>
</RichTextEditorCustomToolbarItems>
</RichTextEditorToolbarSettings>
</SfRichTextEditor>
@code {
private SfRichTextEditor RteObj;
private List<ToolbarItemModel> Tools = new()
{
new() { Command = ToolbarCommand.Bold },
new() { Name = "MyTool", TooltipText = "Insert Star" }
};
private async Task OnMyToolClick()
{
await RteObj.ExecuteCommandAsync(CommandName.InsertText, "★",
new ExecuteCommandOption { Undo = true });
}
}Enable/disable toolbar items programmatically
// Enable an item
await RteObj.EnableToolbarItemAsync(new List<ToolbarItemModel>
{
new() { Command = ToolbarCommand.Bold }
});
// Disable an item
await RteObj.DisableToolbarItemAsync(new List<ToolbarItemModel>
{
new() { Command = ToolbarCommand.Bold }
});Add Command = ToolbarCommand.Custom to include custom toolbar items in enable/disable operations.