Integrate Mention component into the Angular Rich Text Editor
6 Feb 202617 minutes to read
The Mention component enables tagging within the Rich Text Editor by linking its suggestion list to the editor’s editable area. It leverages the Syncfusion Mention component to offer inline suggestions and insert the chosen tags.
Prerequisites
Before proceeding, complete the base Rich Text Editor setup described in the Getting Started guide. The guide covers Angular CLI setup, package installation, CSS imports, module injection, and basic editor markup: Getting Started with Angular Rich Text Editor.
Key features
- Provides inline mention suggestions directly inside editable area.
- Supports both local arrays and remote data sources for loading mention suggestions.
- Allows customizing the popup appearance using item templates and display templates.
- Offers flexible configuration options such as minLength, suggestionCount, and allowSpaces to control search behavior and suggestion filtering.
Set up the Mention component
Install the Syncfusion Mention package using the following command:
npm install @syncfusion/ej2-angular-dropdownsConfigure Mention Component for the Rich Text Editor
Follow the steps below to set up the Mention component inside the Syncfusion Angular Rich Text Editor.
Step 1: Configure Mention Target
Link the Mention component to the Rich Text Editor’s editable area by setting the target property.
The Rich Text Editor automatically appends _rte-edit-view to its editable element ID.
This ensures that the Mention popup appears at the correct cursor position inside the editor.
<ejs-mention target="#YourRTEID_rte-edit-view"></ejs-mention>Step 2: Configure Data Source
Provide the list of items that should appear in the suggestion popup.
public userData = [
{ id: 1, name: 'Andrew Fuller' },
{ id: 2, name: 'Anne Dodsworth' }
];Bind the data source to the Mention component:
<ejs-mention [dataSource]="userData"></ejs-mention>Step 3: Configure Fields
Map your data model fields to define how items are displayed and what value is inserted into the editor content.
public fields = { text: 'name', value: 'id' };<ejs-mention [fields]="fields"></ejs-mention>Step 4: Configure Item Template
Use the itemTemplate to customize how each suggestion item is displayed in the Mention popup. This allows you to show additional details such as avatar initials, name, and email in a structured layout.
<ejs-mention #editorMention>
<ng-template #itemTemplate let-data>
<div class="editor-mention-item-template">
<div class="em-header">
<div class="em-avatar" [ngStyle]="{ 'background-color': data.bgColor, 'color': data.color}">
<div class="em-initial"></div>
</div>
</div>
<div class="em-content">
<div class="em-name"></div>
<div class="em-email"></div>
</div>
</div>
</ng-template>
</ejs-mention>Step 5: Configure Display Template
Use displayTemplate to customize how the selected mention appears when inserted into the Rich Text Editor content.
<ng-template #displayTemplate let-data>
<a href=mailto: title=>@</a>
</ng-template>Step 6: Configure suffixText
It is suggested to use the suffixText property to add a space after the inserted mention, which helps maintain a smooth typing flow in the Rich Text Editor.
<ejs-mention suffixText=" "></ejs-mention>Example: Integrate with syncfusion Rich Text Editor (app.ts)
import { MentionModule } from '@syncfusion/ej2-angular-dropdowns';
import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { RichTextEditorModule, ToolbarService, HtmlEditorService, ImageService, LinkService, QuickToolbarService, TableService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
import { NgStyle } from '@angular/common';
@Component({
imports: [RichTextEditorModule, MentionModule, NgStyle],
standalone: true,
selector: 'app-root',
styleUrl: 'app.css',
encapsulation: ViewEncapsulation.None,
template: `
<div>
<ejs-richtexteditor
id="mention_integration"
placeholder="Type @ and tag the name"
>
<ng-template #valueTemplate>
<p>
Hello
<span contenteditable="false" class="e-mention-chip"
><a href="mailto:[email protected]" title="[email protected]"
>Maria</a
></span
>​
</p>
<p>
The suggestion list displays only 5 items when typing the @ character, as the data source contains a large set of entries
</p>
</ng-template>
</ejs-richtexteditor>
</div>
<div>
<ejs-mention #editorMention [dataSource]='data' [fields]='fieldsData' [allowSpaces]="true"
popupWidth='250px' popupHeight='200px' sortOrder='Ascending' target='#mention_integration_rte-edit-view' [suffixText]=' '>
<ng-template #displayTemplate let-data>
<a href=mailto: title=>@</a>
</ng-template>
<ng-template #itemTemplate let-data>
<div class="editor-mention-item-template">
<div class="em-header">
<div class="em-avatar" [ngStyle]="{ 'background-color': data.bgColor, 'color': data.color}">
<div class="em-initial"></div>
</div>
</div>
<div class="em-content">
<div class="em-name"></div>
<div class="em-email"></div>
</div>
</div>
</ng-template>
</ejs-mention>
</div>
`,
providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService, NgStyle]
})
export class App {
public data: { [key: string]: Object }[] = [
{ name: "Selma Rose", initial: 'SR', email: "[email protected]", color: '#FAFDFF', bgColor: '#01579B' },
{ name: "Maria", initial: 'MA', email: "[email protected]", color: '#004378', bgColor: '#ADDBFF' },
{ name: "Russo Kay", initial: 'RK', email: "[email protected]", color: '#F9DEDC', bgColor: '#8C1D18' },
{ name: "Robert", initial: 'RO', email: "[email protected]", color: '#FFD6F7', bgColor: '#37003A' },
{ name: "Camden Kate", initial: 'CK', email: "[email protected]", color: '#FFFFFF', bgColor: '#464ECF' },
{ name: "Garth", initial: 'GA', email: "[email protected]", color: '#FFFFFF', bgColor: '#008861' },
{ name: "Andrew James", initial: 'AJ', email: "[email protected]", color: '#FFFFFF', bgColor: '#53CA17' },
{ name: "Olivia", initial: 'OL', email: "[email protected]", color: '#FFFFFF', bgColor: '#8C1D18' },
{ name: "Sophia", initial: 'SO', email: "[email protected]", color: '#000000', bgColor: '#D0BCFF' },
{ name: "Margaret", initial: 'MA', email: "[email protected]", color: '#000000', bgColor: '#F2B8B5' },
{ name: "Ursula Ann", initial: 'UA', email: "[email protected]", color: '#000000', bgColor: '#47ACFB' },
{ name: "Laura Grace", initial: 'LG', email: "[email protected]", color: '#000000', bgColor: '#FFE088' },
{ name: "Albert", initial: 'AL', email: "[email protected]", color: '#FFFFFF', bgColor: '#00335B' },
{ name: "William", initial: 'WA', email: "[email protected]", color: '#FFFFFF', bgColor: '#163E02' }
];
public fieldsData: { [key: string]: string } = { text: 'name' };
}import { bootstrapApplication } from '@angular/platform-browser';
import { App } from './app.component';
import 'zone.js';
bootstrapApplication(App).catch((err) => console.error(err));/** Mention template styles **/
.editor-mention-item-template {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
.em-content {
display: flex;
flex-direction: column;
justify-content: center;
}
.em-avatar {
width: 32px;
height: 32px;
text-align: center;
border-radius: 50%;
font-size: 12px;
font-weight: 500;
text-indent: 0px;
line-height: 13px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.em-name {
color: rgb(16, 24, 40);
font-size: 14px;
font-weight: 400;
line-height: 14px;
margin-bottom: 5px;
}
.em-email {
color: gray;
font-size: 12px;
font-weight: 400;
line-height: 14px;
}
#mention_integration_rte-edit-view_options li {
padding: 10px;
height: 60px;
}@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-richtexteditor/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css';Using remote data with Mention in Rich Text Editor
You can bind Mention to a remote data source so suggestions are fetched from your server as the user types. Use Syncfusion’s DataManager + Query (with a suitable adaptor such as WebApiAdaptor) as the Mention dataSource.
Install the DataManager package used for remote data operations:
Install the Syncfusion Data package required for remote data binding:
npm install @syncfusion/ej2-dataThen import the required classes in your component:
import { DataManager, Query, WebApiAdaptor } from '@syncfusion/ej2-data';Example: Integrate remote data with syncfusion Rich Text Editor (app.ts)
Note: When using DataManager with WebApiAdaptor, the server must return a JSON object containing:
result – an array of data items (paged or filtered)
count – the total number of records before paging
Example response returned from the backend:
{
"result": [
{ "id": 1, "name": "John Doe", "email": "[email protected]" },
{ "id": 2, "name": "Jane Smith", "email": "[email protected]" }
],
"count": 25
}This structure is required because WebApiAdaptor expects the data array in result and the total record count in count to properly handle paging, searching, and filtering.
Backend payload reference
var payload = new
{
result = filtered.Skip(Math.Max(skip, 0)).Take(Math.Max(top, 0)),
count = filtered.Count
};
return Ok(payload);import { MentionModule } from '@syncfusion/ej2-angular-dropdowns';
import { Component } from '@angular/core';
import { RichTextEditorModule, ToolbarService, HtmlEditorService, ImageService, LinkService, QuickToolbarService, TableService, PasteCleanupService } from '@syncfusion/ej2-angular-richtexteditor';
import { NgStyle } from '@angular/common';
import { DataManager, Query, WebApiAdaptor } from '@syncfusion/ej2-data';
@Component({
imports: [RichTextEditorModule, MentionModule],
standalone: true,
selector: 'app-root',
template: `
<div>
<ejs-richtexteditor
id="mention_integration"
placeholder="Type @ and tag the name"
>
<ng-template #valueTemplate>
<p>
Hello
<span contenteditable="false" class="e-mention-chip"
><a href="mailto:[email protected]" title="[email protected]"
>Maria</a
></span
>​
</p>
<p>
The suggestion list displays only 5 items when typing the @ character, as the data source contains a large set of entries
</p>
</ng-template>
</ejs-richtexteditor>
</div>
<div>
<ejs-mention [dataSource]='searchData' [query]='query' [fields]='fields' popupWidth='250px' target='#mention_integration_rte-edit-view'></ejs-mention>
</div>
`,
providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, TableService, PasteCleanupService, NgStyle]
})
export class App {
public searchData: DataManager = new DataManager({
url: 'https://services.syncfusion.com/angular/production/api/Employees',
adaptor: new WebApiAdaptor,
crossDomain: true,
offline: true // for local querying
});
public query: Query = new Query().select(['FirstName', 'EmployeeID']).take(7).requiresCount();
public fields: Object = { text: 'FirstName', value: 'EmployeeID' };
}import { bootstrapApplication } from '@angular/platform-browser';
import { App } from './app.component';
import 'zone.js';
bootstrapApplication(App).catch((err) => console.error(err));@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-richtexteditor/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css';Additional resources
- GitHub Repository: Angular Rich Text Editor integrations samples
- Syncfusion Mention getting started: https://ej2.syncfusion.com/angular/documentation/mention/getting-started/
- Syncfusion Mention API: https://ej2.syncfusion.com/angular/documentation/api/mention/
- Syncfusion Rich Text Editor API: https://ej2.syncfusion.com/angular/documentation/api/rich-text-editor/