Templates in Angular Chat UI component

23 Aug 202521 minutes to read

Elevate the user experience by fully customizing the Syncfusion Angular Chat UI component. With templating support for key areas like the conversation window, messages, and typing indicators, you can create a unique and personalized chat interface that aligns perfectly with your application’s design.

Empty chat template

The emptyChatTemplate property allows you to define custom content for the chat interface when it is empty. Use this template to display welcome messages, branding, or helpful instructions, creating an engaging starting point for users.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="chatui" ejs-chatui>
    <ng-template #emptyChatTemplate>
      <div class="empty-chat-text"><h4><span class="e-icons e-comment-show"></span></h4><h4>No Messages Yet</h4><p>Start a conversation to see your messages here.</p></div>
    </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}

Message template

Customize the appearance of every chat message with the messageTemplate property. This template gives you full control over the layout, styling, and design of messages. The template context provides the message object and its index, allowing you to apply conditional styling or logic based on message content or position.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel, MessageModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
    public currentUserModel: UserModel = { user: 'Albert', id: 'user1' };
    public michaleUserModel: UserModel = { user: 'Michale Suyama', id: 'user2' };
    public chatMessages: MessageModel[] = [
        {
            author: this.currentUserModel,
            text: "Hi Michale, are we on track for the deadline?"
        },
        {
            author: this.michaleUserModel,
            text: "Yes, the design phase is complete."
        },
        {
            author: this.currentUserModel,
            text: "I’ll review it and send feedback by today."
        }
    ];
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="messageTemplate" ejs-chatui [user]="currentUserModel" [messages]="chatMessages">
    <ng-template #messageTemplate let-data>
        <div class="message-items e-card">
            <div class="message-text"></div>
        </div>
    </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}

Time Break template

Improve conversation organization with the timeBreakTemplate property. This template lets you customize the time-based separators that appear between messages, such as “Today,” “Yesterday,” or specific dates, enhancing readability. The context includes the messageDate for precise formatting.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
    public currentUserModel: UserModel = { user: 'Albert', id: 'user1' };
    public michaleUserModel: UserModel = { user: 'Michale Suyama', id: 'user2' };
    public timeStamp1: Date = new Date("December 25, 2024 7:30");
    public timeStamp2: Date = new Date("December 25, 2024 8:00");
    public timeStamp3: Date = new Date("December 25, 2024 11:00");
    public formatDate(context: any): string {
        const date: Date = new Date(context);
        const day: string = String(date.getDate()).padStart(2, '0');
        const month: string = String(date.getMonth() + 1).padStart(2, '0');
        const year: number = date.getFullYear();
        let hours: number = date.getHours();
        const minutes: string = String(date.getMinutes()).padStart(2, '0');
        const ampm: string = hours >= 12 ? 'PM' : 'AM';
        hours = hours % 12 || 12;
        const formattedDate: string = `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
        return formattedDate;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="timeBreakTemplate" ejs-chatui [user]="currentUserModel" [showTimeBreak]="true">
    <e-messages>
        <e-message text="Hi Michale, are we on track for the deadline?" [author]="currentUserModel" [timeStamp]="timeStamp1"></e-message>
        <e-message text="Yes, the design phase is complete." [author]="michaleUserModel" [timeStamp]="timeStamp2"></e-message>
        <e-message text="I’ll review it and send feedback by today." [author]="currentUserModel" [timeStamp]="timeStamp3"></e-message>
    </e-messages>
    <ng-template #timeBreakTemplate let-data>
      <div class="timebreak-wrapper">
        
      </div>
    </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}

Typing users template

Enhance user experience by customizing the typing indicator with the typingUsersTemplate property. You can modify its appearance and positioning to provide clear, real-time feedback. The template’s context includes a list of users, so you can display who is currently typing.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
    public currentUserModel: UserModel = { user: 'Albert', id: 'user1' };
    public michaleUserModel: UserModel = { user: 'Michale Suyama', id: 'user2' };
    public reenaUserModel: UserModel = { user: 'Reena', id: 'user3' };
    public typingUsers: UserModel[] = [this.michaleUserModel, this.reenaUserModel];
    public getUserTemplate(context: any): string {
        if (!context.users || context.users.length === 0) {
            return '';
        }
    
        const usersList = context.users.map((user: any, i: number) => {
            const isLastUser: boolean = i === context.users.length - 1;
            return `${isLastUser && i > 0 ? 'and ' : ''}<span class="typing-user">${user.user}</span>`;
        }).join(' ');
    
        return `
            <div class="typing-wrapper">
                ${usersList} are typing...
            </div>
        `;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="typingUsersTemplate" ejs-chatui [user]="currentUserModel" [typingUsers]="typingUsers">
  <e-messages>
      <e-message text="Hi Michale, are we on track for the deadline?" [author]="currentUserModel"></e-message>
      <e-message text="Yes, the design phase is complete." [author]="michaleUserModel"></e-message>
      <e-message text="I’ll review it and send feedback by today." [author]="currentUserModel"></e-message>
  </e-messages>
  <ng-template #typingUsersTemplate let-data>
    <div [innerHTML] = 'getUserTemplate(data)'></div>
  </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}

Suggestion template

Create visually engaging and functional quick replies using the suggestionTemplate property. This template allows you to customize the layout and styling of suggestion items. The context includes the suggestion data and its index, enabling you to create dynamic and interactive suggestion buttons.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
    public currentUserModel: UserModel = { user: 'Albert', id: 'user1' };
    public michaleUserModel: UserModel = { user: 'Michale Suyama', id: 'user2' };
    public suggestions: string[] = [ "Okay will check it", "Sounds good!"];
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="suggestionTemplate" ejs-chatui [user]="currentUserModel" [suggestions]="suggestions">
  <e-messages>
      <e-message text="Hi Michale, are we on track for the deadline?" [author]="currentUserModel"></e-message>
      <e-message text="Yes, the design phase is complete." [author]="michaleUserModel"></e-message>
  </e-messages>
  <ng-template #suggestionTemplate let-data>
    <div class='suggestion-item active'>
      <div class="content"></div>
    </div>
  </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}

Take control of the chat input area by defining a custom footerTemplate. This allows you to replace the default footer, giving you the flexibility to add custom buttons, integrate additional functionality, and manage message sending actions with a personalized design.

import { NgModule, ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChatUIModule, ChatUIComponent } from '@syncfusion/ej2-angular-interactive-chat';
import { UserModel } from '@syncfusion/ej2-interactive-chat';
import { Component } from '@angular/core';


@Component({
    imports: [ FormsModule, ReactiveFormsModule, ChatUIModule ],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {
    @ViewChild('chatUIComponent')
    public chatUIComponent!: ChatUIComponent;
    public currentUserModel: UserModel = { user: 'Albert', id: 'user1' };
    public michaleUserModel: UserModel = { user: 'Michale Suyama', id: 'user2' };
    public buttonClick = () => {
        const textArea = document.getElementById('chatTextArea') as HTMLTextAreaElement;
        if (textArea && textArea.value.length > 0) {
          let value: string = textArea.value;
          textArea.value = '';
          this.chatUIComponent.addMessage(
            {
                author: this.michaleUserModel,
                text: value
            }
          );
        }
    };
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="footerTemplate" #chatUIComponent ejs-chatui [user]="currentUserModel">
  <e-messages>
      <e-message text="Hi Michale, are we on track for the deadline?" [author]="currentUserModel"></e-message>
      <e-message text="Yes, the design phase is complete." [author]="michaleUserModel"></e-message>
      <e-message text="I’ll review it and send feedback by today." [author]="currentUserModel"></e-message>
  </e-messages>
  <ng-template #footerTemplate let-data>
    <div class="custom-footer">
      <input id="chatTextArea" class="e-input" placeholder="Type your message..."/>
      <button id="sendMessage" class="e-btn e-primary" (click)="buttonClick()"><span class="e-icons e-send-1"></span></button>
    </div>
  </ng-template>
</div>
#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  top: 45%;
  left: 45%;
}