A powerful, fully-configurable Angular wrapper for RichTextEditor.com, built for modern Angular apps. Supports both Reactive & Template-Driven Forms, modals, file uploads, custom toolbars, validation, dynamic content injection, and much more.
π₯ Built for scalability, optimized for performance, and engineered for flexibility.
- π§© Works with
FormControl
,[(ngModel)]
, and standalone forms - π€ Customizable image/file upload
- π§ Preset and dynamic toolbar options
- π± Mobile-friendly toolbar responsiveness
- β Validation with custom messages
- π¬ Full error messaging & touched state integration
- π Public API for dynamic HTML manipulation
- π Easy integration inside components or modals
npm install angular-rich-text-editor
This library depends on assets and runtime scripts from RichTextEditor.com. These must be added manually.
β οΈ Make sure to keep your existing script. Just append the following to the"script"
array in yourangular.json
orproject.json
:
"scripts": [
...
"node_modules/angular-rich-text-editor/src/assets/richtexteditor/rte.js"
]
β οΈ Make sure to keep your existing styles. Just append the following to the"styles"
array in yourangular.json
orproject.json
:
"styles": [
...
"node_modules/angular-rich-text-editor/src/assets/richtexteditor/rte_theme_default.css"
]
π To load the required runtime assets, append the following entry to the
"assets"
array in yourangular.json
orproject.json
.
β Donβt remove your existing asset entries β just add this below them:
"assets": [
...,
{
"glob": "**/*",
"input": "node_modules/angular-rich-text-editor/src/assets/richtexteditor",
"output": "assets/richtexteditor"
}
]
---
## π§± Module Import
### In a regular NgModule:
```ts
import { RichTextEditorModule } from 'angular-rich-text-editor';
@NgModule({
imports: [RichTextEditorModule],
})
export class YourModule {}
@Component({
standalone: true,
imports: [RichTextEditorModule],
...
})
<lib-rich-text-editor [(ngModel)]="content" [rtePreset]="'FULL'" [enableImageUpload]="true" [fileUploadHandler]="handleFileUpload" />
<form [formGroup]="form">
<lib-rich-text-editor formControlName="description" [initialContent]="startingHTML" [enableVideoEmbed]="true" />
</form>
<lib-rich-text-editor [(ngModel)]="content" [fileUploadHandler]="mockUpload" [excludedToolbarItems]="['insertvideo', 'insertcode']" />
<app-shared-rich-text-editor [(ngModel)]="emailBody" [imageToolbarItems]="['imagestyle', 'delete']" [excludedToolbarItems]="['html2pdf']" [fileUploadHandler]="uploadImage" />
Input | Type | Description |
---|---|---|
formControl , formControlName |
FormControl |
Works with reactive forms |
[(ngModel)] |
string |
Supports template-driven forms |
initialContent |
string |
Set initial content as HTML string |
rtePreset |
'BASIC' | 'STANDARD' | 'FULL' | 'MINIMAL' |
Select a toolbar preset configuration |
imageToolbarItems |
Array<'menu_controlsize' | 'imagecaption' | ...> |
Configure image inline toolbar |
excludedToolbarItems |
string[] |
Toolbar buttons to exclude |
fileUploadHandler |
(file, cb, i?, all?) => void |
Custom image/file upload handler |
enableImageUpload |
boolean |
Enable/disable image uploading |
enableVideoEmbed |
boolean |
Enable/disable video embedding |
readonly |
boolean |
Make editor read-only |
errorMessages |
{ [key: string]: string } |
Custom validation error messages |
Output | Type | Description |
---|---|---|
ngModelChange |
EventEmitter<string> |
Emits when HTML content updates |
contentChanged |
EventEmitter<void> |
Emits after any content change |
blurEvent |
EventEmitter<void> |
Emits on blur |
focusEvent |
EventEmitter<void> |
Emits on focus |
Inject in your component:
constructor(private rteService: RichTextEditorService) {}
Method | Description |
---|---|
getContent() |
Get current HTML from the editor |
setContent(html: string) |
Set HTML content programmatically |
clearContent() |
Clears all content |
insertContentAtCursor(html: string) |
Inject HTML at current cursor |
focus() |
Focus the editor |
executeCommand(cmd: string, value?: any) |
Execute RichTextEditor command (bold, link...) |
getCharacterCount() |
Get plain character count |
getWordCount() |
Get plain word count |
getSelectedText() |
Returns currently selected text |
isReadonly() |
Check if editor is read-only |
isAvailable() |
Check if editor is ready |
hideFloatingPanels() |
Hide open floating panels |
removeLastPlaceholderImage() |
Removes latest blob: /data: image inserted |
Supports required
validation with:
- Angular template validation (
required
directive) - Reactive validation (
Validators.required
)
Checks:
- Empty text
- Absence of image or video
You can select a predefined toolbar layout using the rtePreset
input.
Preset | Toolbar Description |
---|---|
BASIC |
Light inline editing options |
STANDARD |
Medium-complexity toolbar |
FULL |
Rich full-featured editing experience |
MINIMAL |
Ultra-compact, minimal formatting buttons |
export type RTEPreset = "BASIC" | "STANDARD" | "FULL" | "MINIMAL";
Customize the image selection toolbar using the supported RTEImageTool
values:
export type RTEImageTool = "menu_controlsize" | "imagecaption" | "controlalt" | "controlinsertlink" | "controleditlink" | "controlopenlink" | "controlunlink" | "menu_controljustify" | "imagestyle" | "delete";
<lib-rich-text-editor [imageToolbarItems]="['menu_controljustify', 'imagestyle', 'delete']" />
Custom uploader example:
handleFileUpload(file: File, cb: (url: string | null) => void) {
uploadToS3(file).then(url => cb(url));
}
Simulate failure:
simulateFailingUpload(file, cb) {
setTimeout(() => cb(null, 'mock-error'), 1000);
}
Ensure that /assets/richtexteditor
is correctly linked in your build config.
Required scripts and styles must be added (see Configuration section above).
- Editor uses an
iframe
, which may needfixture.whenStable()
orsetTimeout()
in tests. - Mock internal methods like
getContent()
for assertions. - Use
zone.run()
to manually trigger change detection if needed.
You can inject globally:
providers: [{ provide: RTE_LICENSE_KEY, useValue: "your-license-key" }];
Or pass directly to the component:
<lib-rich-text-editor [licenseKey]="'your-license-key'"></lib-rich-text-editor>
- Fork or clone the repo
- Run
npm start
(once demo is available) - Add new features or fix issues
- Submit a clean PR with a clear description
- Interactive playground / demo
- Storybook docs
- JSON content support
- Plugin registration API
- Drag & drop blocks / content snippets
- Built on RichTextEditor.com
- Built with β€οΈ and TypeScript
Start a discussion or file an issue:
π https://github.com/manishpatidar028/angular-rich-text-editor