@richscripts/richtexteditor
v2.4.0
Published
A full-featured JavaScript rich text editor (WYSIWYG) with toolbar, plugins, i18n support, a built-in AI Toolkit (Ask AI, AI Chat, AI Review drawer, BYOK resolver), structured content APIs (JSON/Markdown), and an optional collaboration / review stack: sla
Maintainers
Keywords
Readme
Rich Text Editor
Rich Text Editor is a browser-based WYSIWYG editor with toolbar customization, plugins, localization, image editing, PDF export, and classic HTML APIs.
What's in v2.2
A full collaborative-document workspace, not just a textarea replacement:
- AI Toolkit — in-editor proofread / rewrite / summarize / translate / chat, with streaming responses, an inline preview drawer, and a persistent accept/reject review ledger. Bring your own provider (OpenAI / Anthropic / Azure OpenAI / Groq / Ollama / custom) via
editor.aiToolkit.setResolver()or the server-sideIRichTextBoxAiResolverinterface. - Per-node Yjs CRDT engine (new in 2.2) —
editor.collab.attach({ doc, provider, textSync: "crdt" })activates character-level concurrent typing on the same paragraph with deterministic merge resolution, presence cursors viaY.RelativePosition-encoded awareness, and per-authorY.UndoManager(Ctrl-Z undoes only your edits). Pairs with any Yjs provider you self-host. Ships in the base license. - Slash commands & mentions —
/at the start of a line opens a command palette;@and#open mention pickers viaeditor.slashCommands.register()andeditor.mentions.register(). - Comments & tracked changes — threaded inline comments on text selections and block/media content such as images or tables (
editor.comments.add/reply/resolve), tracked-changes mode, per-author colors and labels. - Comments-only review mode — set
commentsOnly: trueor calleditor.setCommentsOnly(true)to lock document edits while still allowing inline comments and review discussion. - Restricted editing templates — set
restrictedEditingMode: trueto lock the document except for spans taggeddata-rte-editable="true". Mark fillable regions at runtime witheditor.restrictedEditing.markSelection(); toggle the lock viaeditor.restrictedEditing.enable()/disable()/goToNext(). Use it for forms, contracts, fillable templates — only the marked regions accept input. - Revision history — named snapshots, diff view, restore (
editor.revisionHistory.snapshot/diff/restore). - Dictation — Web Speech API integration (
editor.dictation.toggle()) with multi-language support. - DOCX import + export — import Word documents through
editor.aiToolkit.importDocx({ file?, mode? })and generate deterministic HTML → .docx viaeditor.aiToolkit.exportDocx({ filename }); preserves headings, lists, tables, images. - Structured content bridge —
editor.getJSON()/setJSON(),fromMarkdown()/toMarkdown(),renderHTML(),validateStructuredContent()— for SSR, JSON storage, and Markdown round-trip. The packaged schema now preserves merge fields, ordered-list marker styles (A/a/I/i), table-of-contents blocks, footnotes, and editor page breaks instead of collapsing them into opaque HTML. - Accessibility audit helper —
RichTextEditor.auditAccessibility()/auditAccessibility()catches empty headings, skipped heading levels, missing image alt text, and tables without header cells in browser or Node workflows. - In-editor accessibility repair panel — the packaged
accessibilitycheckerplugin adds a side panel (editor.accessibilityChecker.open/close/toggle/run/repair) with focused fixes for missing image alt text, empty headings, skipped heading levels, and headerless tables. UseaccessibilityCheckerAutoOpento keep the workflow visible during review passes. - Restricted editing templates — the packaged
restrictededitingplugin lets apps lock the document root while keeping marked islands editable (editor.restrictedEditing.enable/disable/toggle/list/goToNext/goToPrevious). Mark reusable fields withdata-rte-editablein template HTML or calleditor.restrictedEditing.markSelection({ label })while authoring. - Document outline + TOC helpers —
RichTextEditor.getDocumentOutline()/getDocumentOutline()extracts a flat heading outline (id,text,level,path), whilegetTableOfContents()returns a nested tree andsyncTableOfContents()repopulates packaged TOC blocks from live headings. The same TOC helpers can also persist TinyMCE-style display settings such asordered,orderedListType, andincludeTitlefor numbered or titleless navigation blocks. TOC items can also expose optionalitemIndex/indexLabelmetadata viaindexMode: "linear" | "hierarchical"so custom sidebars can mirror Tiptap-style numbered navigation without reparsing headings twice. - Footnote extraction helper —
RichTextEditor.getFootnotes()/getFootnotes()returns sorted{ id, number, refId, text, path }metadata from HTML or structured JSON so review sidebars and DOCX import screens can inspect Word-style citations without reparsing the document. - Live document outline panel — the packaged
documentoutlineplugin adds a toggleable browser-side heading sidebar (editor.documentOutline.open/close/toggle/list/refresh) so long documents get CKEditor-style section navigation without custom app code. UsedocumentOutlineAutoOpen,documentOutlineMinLevel, anddocumentOutlineMaxLevelto tune the panel. - Packaged content minimap — the packaged
contentminimapplugin adds a TinyMCE/CKEditor-style miniature document preview (editor.contentMinimap.open/close/toggle/refresh/isOpen) with click-and-drag viewport navigation for long documents. UsecontentMinimapAutoOpen,contentMinimapWidth, andcontentMinimapScaleto tune the panel. - Checklist / task-list Markdown —
- [x] doneand- [ ] todoround-trip throughfromMarkdown()/toMarkdown()and render as disabled checkbox lists in HTML / SSR output. - Markdown shortcut helper parity —
getMarkdownShortcutAction()now recognizes headings, quotes, ordered/bullet/task lists, horizontal rules (---) and fenced code blocks (````` /~~~lang) so custom wrappers can mirror the same typing affordances exposed by current editor competitors. - Word + character statistics —
editor.getTextStatistics()/getSelectionStatistics()expose document + selection counts, and the built-in bottom bar can show characters, words, or both. - Case change commands — built-in
ucase,lcase, andtitlecasecommands let toolbars or custom integrations quickly apply Upper Case, Lower Case, or Title Case transforms without leaving the editor. - Document metrics helper —
RichTextEditor.getDocumentMetrics()/getDocumentMetrics()adds paragraph, sentence, heading, image, table, link, and estimated reading-time counts for analytics and publishing workflows. - Document page setup metadata —
RichTextEditor.getDocumentPageSetup()/setDocumentPageSetup()lets apps persist page format, margins, orientation, and export header/footer HTML in the structured-content document for print/PDF workflows. - Framework wrappers — React (
@richscripts/richtexteditor/react), Vue (@richscripts/richtexteditor/vue), Angular (@richscripts/richtexteditor/angular), Blazor wrapper, ASP.NET Core tag helper (<richtextbox>from the sister NuGet package). Framework refs/components also expose the document-workflow helpers needed for outline, TOC, page-setup, metrics, statistics, and accessibility flows without manually round-tripping throughgetJSON(). - AI ghost-text autocomplete (2.3.0) — Copilot / Notion-AI-style inline completion: after a typing pause a greyed suggestion appears after the caret continuing your sentence; Tab accepts, Esc / typing dismisses. Bring-your-own resolver (
config.ghostTextResolver({ before, after, full })→ string | Promise); inert untilconfig.ghostTextand a resolver are set, so no model ships and no network call happens on its own. Serialization-safe (the suggestion is acontenteditable=falsespan the caret stays before;getHTMLCode/getJSONstrip it) and undo-friendly (accept viaexecCommand insertText). API:editor.requestGhostText()/acceptGhostText()/dismissGhostText()/hasGhostText()/setGhostTextResolver(); slash/ai complete. - Local draft autosave & crash recovery (2.3.0) — persists the document to
localStorageas you type and offers to restore the unsaved draft on the next load (Gmail/Notion "never lose your work"). Opt-in viaconfig.localDraft = true(or{ key, intervalMs, ttlMs, promptRestore }). The draft is never auto-applied (server content shows until the user clicks Restore); stale drafts are pruned; saves onbeforeunload. API:editor.saveLocalDraft()/hasLocalDraft()/getLocalDraft()/restoreLocalDraft()/clearLocalDraft(). - Copy / Download as Markdown (2.3.0) — Notion-style export surfacing the core
toMarkdown()engine: slash/copy as markdown+/download as markdown, oreditor.getMarkdown()/editor.copyAsMarkdown()(clipboard, execCommand fallback) /editor.downloadMarkdown(name?)(saves a.mdfile, filename derived from the first heading). Read-only; disable withconfig.markdownExportEnabled = false. - Typewriter & focus writing modes (2.3.0) — two distraction-free modes. Typewriter mode pins the caret line to a fixed vertical anchor and scrolls the editable as you type (iA Writer / Typora / Ulysses style); focus mode dims every block except the one the caret is in (Notion / iA Writer style). Toggle independently via slash
/typewriter+/focus modeoreditor.toggleTypewriterMode()/editor.toggleFocusMode()(plusset…/is…). Both off by default (config.typewriterModeEnabled,config.focusModeEnabled, anchor viaconfig.typewriterAnchor). Serialization-safe: purely presentational — focus state is runtime-only CSS classes, stripped aroundgetHTMLCode/getJSON; typewriter mode only scrolls. - Foldable headings (2.3.0) — Obsidian/Notion/Word-style section folding: hover a heading and click the gutter chevron (or
editor.toggleHeadingFold(h)/editor.foldAtCaret()/editor.unfoldAll(), slash/fold section) to collapse every block beneath it, up to the next heading of the same or higher level. Serialization-safe: fold state is runtime-only CSS classes (the chevron is a CSS::before), andgetHTMLCode/getJSONare wrapped to strip them — saved markup stays clean and folded content is never lost. Caret-safe. Disable withconfig.foldHeadingsEnabled = false. - Auto-embed media URLs on paste (2.3.0) — paste a bare YouTube or Vimeo URL on its own line and it becomes a responsive 16:9 embed (Notion/Medium style); also available as
editor.embedUrl(url). Injection-safe by construction: the iframesrcis rebuilt from a sanitized video id, never the raw input. Mid-paragraph and text-selected pastes stay links. Add providers viaconfig.autoEmbedResolver(url); disable withconfig.autoEmbedEnabled = false. - Interactive to-do / task lists (2.3.0) —
editor.execCommand("inserttodolist")(slash/to-do, toolbar) inserts a checklist whose items each have a clickable checkbox; clicking toggles open/done (check + strike-through), Notion/GitHub style. The done state lives indata-checkedand round-trips throughgetHTMLCode/getJSON; checkboxes arecontenteditable="false"spans (no fragile<input>s) and re-bind on load via event delegation. Enter-created items are auto-normalized to stay well-formed. - Emoji
:shortcode:autocomplete (2.3.0) — GitHub/Slack/Discord-style inline emoji entry: type a complete:shortcode:and it becomes the emoji (:fire:→ 🔥,:+1:→ 👍,:tada:→ 🎉), or type:+ a partial query for a keyboard-navigable popup (↑/↓, Enter/Tab, Esc). ~140 curated codes built in; extend or replace viaconfig.emojiShortcodes. Word-boundary gated (sopath:fire:is ignored) and inert inside code. Complements the emoji picker with fast keyboard-only entry. Disable withconfig.emojiAutocompleteEnabled = false. - Read-aloud / text-to-speech (2.3.0) —
editor.execCommand("readaloud")(slash/read aloud) opens a non-modal control bar (play/pause, stop, voice, rate) and reads the selection — or the whole document — aloud, highlighting each sentence as it is spoken (native selection, content untouched). Browser-native via the Web Speech API: no library bundled, no backend, no key. The speech-out complement to dictation; an accessibility win. API:editor.readAloud({rate,voice})/editor.stopReadAloud(); tune withconfig.readAloudRate/config.readAloudHighlight. - Mermaid diagrams (2.3.0) —
editor.execCommand("insertdiagram")(slash/diagram) authors diagrams-as-code (flowchart, sequence, gantt, pie, class, state…) with a live preview and renders to SVG. No renderer bundled — usesconfig.diagramResolver(server-side render like Kroki), else a host-pagewindow.mermaid, else a source<pre>fallback; the Mermaid source round-trips indata-diagramand re-renders viaeditor.renderDiagrams(). Double-click to edit; injection-safecontenteditableblocks. Pairs with the equation editor's same host-supplies-the-renderer model. - Inline Markdown autoformat (2.3.0) — type the closing delimiter and the span converts in place:
**bold**/__bold__→ bold,*italic*/_italic_→ italic,`code`→ inline code,~~strike~~→ strikethrough. Complements the existing block shortcuts (#,>,-,1.,---). Word-boundary gated so math (2*3), globs andsnake_caseare never reformatted; inert inside code/links; fully undoable. Disable withconfig.markdownInlineEnabled = false. - Email inline-style export (2.3.0) —
editor.getEmailHTML()returns email-client-safe HTML: curated computed styles written inline on every element (since Outlook/Gmail strip<style>and classes),class/id/contenteditable/data-rte-*removed,<script>/<style>dropped, content wrapped in a centered max-width table.{ wrap:false }for a bare fragment,{ width:N }for a custom width; tune the inlined set viaconfig.emailInlineProperties.editor.execCommand("emailexport")(slash/emailor toolbar) opens a copy-ready dialog. - Smart chips (2.3.0) — Google-Docs-style inline chips:
editor.execCommand("insertdatechip")drops an interactive date pill (picker + machine-readable value);insertchipopens a Date/Person/Link menu. Person/Link chips use the optionalconfig.chipResolver(query, type)for rich data, with a plain-input fallback. Atomic, injection-safe, round-trips throughgetHTMLCode. - Block drag-handles (2.3.0) — Notion-style ⋮⋮ handle on hover lets you drag-reorder top-level blocks. On by default; disable with
config.blockDragHandles = false. The handle never enters the saved content. - Spell check (2.3.0) —
editor.execCommand("spellcheck"). Native browser spell-check by default (zero infra); wireconfig.spellCheckResolver(text) => Promise<[{word, suggestions}]>(LanguageTool / server / LLM) for a review panel with click-to-replace suggestions. Insert from the slash menu (/spellcheck) or toolbar. - Web-bookmark preview cards (2.3.0) —
editor.execCommand("insertbookmark")turns a URL into a rich link-preview card (favicon + title + description + domain). Works with zero backend (basic card from URL + favicon) or wireconfig.bookmarkResolver(url) => Promise<{title,description,image,favicon}>for full unfurled previews. Insert from the slash menu (/bookmark) or toolbar;http(s)-only with escaped metadata andrel="noopener". - Equation editor (2.3.0) —
editor.execCommand("insertmath")opens a TeX/LaTeX dialog with a live KaTeX/MathJax preview and edit-in-place support; emits stable.rte-math-inlinemarkup that renders via whatever math renderer the host page loads. Insert from the slash menu (/equation) or toolbar. - Modern block types (2.3.0) — callouts (info / success / warning / danger / note admonition boxes), multi-column layouts (2–4 responsive columns), and toggle / collapsible blocks (native
<details>). Insert from the slash menu (/) or the toolbar; customize callout variants viaconfig.calloutTypes. Editor-native (no server), round-trips throughgetHTMLCode/getJSON. Closes the Notion / Google Docs / CKEditor block-type gap. - Paste-pipeline hardening (2.2.4) — Word lists pre-converted before the attribute scrubber strips the metadata; TOC / PAGEREF / HYPERLINK / SEQ / STYLEREF / NOTEREF / REF / FORMTEXT / FORMCHECKBOX / DATE / TIME / FILENAME / AUTHOR / TITLE / SUBJECT / INDEX / MERGEFIELD field instructions stripped even when scrubbed-bare; instruction text split across continuation
<span>runs caught with false-positive-safe guards;<style>/<script>/<head>/<meta>defense-in-depth; tool-specific class +data-*strip for Notion (notion-*,data-block-id), CKEditor (cke_*,data-cke-*), TinyMCE (mce_*,data-mce-*), Atlassian (confluence-*,data-confluence-*), and Google Docs (docs-internal-*,data-google-*); cleanup of empty<span></span>/<p></p>debris; smart-paste source toast detects Word / Google Docs / LibreOffice / Notion / Excel / Confluence. Opt-out viasmartPasteToast: false. - Smart link paste (2.2.4) — pasting a URL or email while text is selected wraps the selection in
<a href>instead of replacing it. Matches Google Docs / Notion / TipTap / ProseMirror behavior. Opt-out viasmartLinkPaste: false. - Mobile toolbar mode, classic toolbar customization, plugins, localization, image editing, PDF export, paste-from-Word fidelity, find & replace, autosave, draft recovery.
- Configurable empty-editor placeholders — set
placeholder,placeholderShowOnlyWhenEditable, andplaceholderColorto match the guided empty-state UX offered by current Tiptap and TinyMCE setups. - TypeScript declarations — 487-line
index.d.tswith typed signatures for all 31 documented editor instance methods, theRichTextEditorCommandstring-literal union (50+ built-in commands), event-handler signatures, and theRichTextEditorConfiginterface.
The structured content bridge now returns a semantic document model while still carrying compatibility HTML and plain text:
{
"type": "doc",
"version": 2,
"format": "richtexteditor-json",
"html": "<p>Hello world</p>",
"text": "Hello world",
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Hello world" }
]
}
]
}Asset setup
Serve the richtexteditor/ folder from your app. The React and Vue wrappers default to loading assets from /richtexteditor.
Markdown, validation, and static rendering
import {
auditAccessibility,
createStructuredContent,
fromMarkdown,
getDocumentPageSetup,
getDocumentMetrics,
getDocumentOutline,
getTableOfContents,
getTextStatistics,
renderHTML,
repairAccessibilityIssue,
setDocumentPageSetup,
syncTableOfContents,
toMarkdown,
validateStructuredContent
} from "@richscripts/richtexteditor/integrations/shared";
const documentModel = fromMarkdown("## Hello\n\nThis now round-trips through **Markdown**.");
const html = renderHTML(documentModel);
const markdown = toMarkdown(documentModel);
const pagedDocument = setDocumentPageSetup(documentModel, {
format: "Letter",
margins: { top: "1in", right: "0.75in", bottom: "1in", left: "0.75in" }
});
const pageSetup = getDocumentPageSetup(pagedDocument);
const metrics = getDocumentMetrics(documentModel);
const outline = getDocumentOutline(documentModel);
const toc = getTableOfContents(documentModel, {
minLevel: 2,
maxLevel: 4,
indexMode: "hierarchical"
});
const stats = getTextStatistics(documentModel);
const accessibility = auditAccessibility(documentModel);
const repairedDocument = repairAccessibilityIssue(documentModel, accessibility.issues[0], {
altText: "Hero illustration"
});
const validation = validateStructuredContent(documentModel);
const syncedTocDocument = syncTableOfContents(documentModel, {
ordered: true,
orderedListType: "I",
includeTitle: false
});Structured content can also preserve document-automation nodes emitted by the editor UI:
const documentModel = createStructuredContent(
'<p>Hello <span data-rte-merge-field="Customer.Name">Customer Name</span><sup data-rte-footnote-ref="1"><a href="#note-1">[1]</a></sup></p>' +
'<div data-rte-footnotes="true"><div>Footnotes</div><ol><li id="note-1" data-rte-footnote-item="1">Imported from a template. <a href="#ref-1">↩</a></li></ol></div>'
);
console.log(documentModel.content[0].content[1].type); // "mergeField"
console.log(toMarkdown(documentModel)); // includes {{Customer.Name}} and [^1]These helpers can now also run in Node for server-side rendering and content conversion without requiring a browser DOM.
const {
auditAccessibility,
createStructuredContent,
getDocumentMetrics,
getDocumentPageSetup,
getDocumentOutline,
getTableOfContents,
getTextStatistics,
renderHTML,
repairAccessibilityIssue,
setDocumentPageSetup,
syncTableOfContents,
toMarkdown,
validateStructuredContent
} = require("@richscripts/richtexteditor/server");
const documentModel = createStructuredContent("<div data-rte-toc=\"true\"><div>Contents</div></div><h2>Hello</h2><p><strong>Server</strong> render</p>");
const html = renderHTML(documentModel);
const markdown = toMarkdown(documentModel);
const pagedDocument = setDocumentPageSetup(documentModel, {
format: "A4",
orientation: "portrait",
margins: { top: "20mm", right: "16mm", bottom: "20mm", left: "16mm" }
});
const pageSetup = getDocumentPageSetup(pagedDocument);
const metrics = getDocumentMetrics(documentModel);
const outline = getDocumentOutline(documentModel);
const toc = getTableOfContents(documentModel, {
minLevel: 2,
maxLevel: 4,
indexMode: "hierarchical"
});
const synced = syncTableOfContents(documentModel, {
ordered: true,
orderedListType: "A",
includeTitle: false
});
const stats = getTextStatistics(documentModel);
const accessibility = auditAccessibility(documentModel);
const repairedDocument = repairAccessibilityIssue(documentModel, accessibility.issues[0], {
altText: "Server-rendered architecture diagram"
});
const validation = validateStructuredContent(documentModel);Use @richscripts/richtexteditor/server when you only need conversion and rendering on the server. Use @richscripts/richtexteditor/integrations/shared when you also need browser asset loading and editor bootstrapping helpers.
The same server/shared helpers also expose getTextStatistics(value) for consistent word and character counts outside the browser. The React, Vue, and Angular package entry points re-export this same helper family so framework apps can import editor components and document-workflow utilities from one place.
DOCX import
Current competitors like CKEditor, TinyMCE, and Tiptap all market Word/DOCX import alongside export. Rich Text Editor now ships a matching browser helper for the client side of that flow:
await editor.aiToolkit.importDocx({
url: "/richtextbox/import/docx",
mode: "replace"
});Pass file to skip the built-in file picker, or use mode: "insert" to insert the converted HTML at the current caret instead of replacing the whole document. The helper expects the server endpoint to return either raw HTML or JSON with an html field.
React
import { useState } from "react";
import { RichTextEditorReact } from "@richscripts/richtexteditor/react";
export default function EditorPage() {
const [html, setHtml] = useState("<p>Hello world</p>");
return (
<RichTextEditorReact
value={html}
onChange={setHtml}
assetBasePath="/richtexteditor"
style={{ minHeight: 360 }}
/>
);
}Vue
import { createApp, ref } from "vue";
import { RichTextEditorVue } from "@richscripts/richtexteditor/vue";
const app = createApp({
components: { RichTextEditorVue },
setup() {
const documentModel = ref({
type: "doc",
version: 2,
format: "richtexteditor-json",
content: [
{
type: "paragraph",
content: [{ type: "text", text: "Hello world" }]
}
]
});
return { documentModel };
}
});<RichTextEditorVue
v-model="documentModel"
value-format="json"
asset-base-path="/richtexteditor"
style="min-height: 360px"
/>Angular
Angular apps can now use the packaged standalone wrapper component:
import { Component } from "@angular/core";
import { RichTextEditorAngularComponent } from "@richscripts/richtexteditor/angular";
@Component({
selector: "app-root",
standalone: true,
imports: [RichTextEditorAngularComponent],
template: `
<rich-text-editor
[assetBasePath]="'/assets/richtexteditor'"
[value]="documentModel"
[valueFormat]="'json'"
(change)="handleChange($event.value)"
/>
`
})
export class AppComponent {
documentModel = {
type: "doc",
version: 2,
format: "richtexteditor-json",
content: [
{
type: "paragraph",
content: [{ type: "text", text: "Hello from Angular" }]
}
]
};
handleChange(value: unknown) {
this.documentModel = value as typeof this.documentModel;
}
}The Angular wrapper exposes the same JSON bridge and convenience instance methods as the React and Vue wrappers: focus(), getEditor(), getHTMLCode(), getJSON(), setHTMLCode(), setJSON(), and plugin accessors such as getAiToolkit() / getCollab() / getComments().
The repo also includes a full Angular starter in Demos/rte-ng-ts/ that uses the same wrapper pattern.
Classic usage
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>
<!-- Production: swap the line above for the minified bundle (~56% smaller, identical behaviour):
<script src="/richtexteditor/plugins/all_plugins.min.js"></script> -->
<div id="editor"></div>
<script>
var editor = new RichTextEditor("#editor", {
placeholder: "Write something...",
placeholderShowOnlyWhenEditable: true,
commentsOnly: false,
restrictedEditingMode: false,
accessibilityCheckerAutoOpen: false,
documentOutlineAutoOpen: false,
documentOutlineMinLevel: 1,
documentOutlineMaxLevel: 3
});
editor.setHTMLCode("<p>Hello world</p>");
console.log(editor.getJSON());
</script>Restricted editing is meant for contract, intake, and mail-merge style templates:
<p>Hello <span data-rte-editable="true" data-rte-editable-label="Customer Name">Customer Name</span>,</p>
<p>Your case number is <span data-rte-editable="true" data-rte-editable-label="Case ID">0000</span>.</p>editor.setHTMLCode(templateHtml);
editor.restrictedEditing.enable();
editor.restrictedEditing.goToNext();Template authors can also mark regions interactively before switching modes:
editor.restrictedEditing.markSelection({ label: "Account manager" });
editor.restrictedEditing.markSelection({ block: true, label: "Custom notes" });
editor.restrictedEditing.enable();In order to start using Rich Text Editor, configure or customize it further, please visit the documentation.
License
For licensing information please read Licensing Info.
