Templates in React Chat UI component
28 Aug 202524 minutes to read
Elevate the user experience by fully customizing the Syncfusion React 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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const emptyChatTemplate = () => {
return (
<div className="empty-chat-text">
<h4><span className="e-icons e-comment-show"></span></h4>
<h4>No Messages Yet</h4>
<p>Start a conversation to see your messages here.</p>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent emptyChatTemplate={emptyChatTemplate}></ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const emptyChatTemplate = () => {
return (
<div className="empty-chat-text">
<h4><span className="e-icons e-comment-show"></span></h4>
<h4>No Messages Yet</h4>
<p>Start a conversation to see your messages here.</p>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent emptyChatTemplate={emptyChatTemplate}></ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel = {
id: "user2",
user: "Michale Suyama"
};
const messageTemplate = (context) => {
return (
<div className="message-items e-card">
<div className="message-text">{context.message.text}</div>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="messageTemplate" user={currentUserModel} messageTemplate={messageTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel: UserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel: UserModel = {
id: "user2",
user: "Michale Suyama"
};
const messageTemplate = (context) => {
return (
<div className="message-items e-card">
<div className="message-text">{context.message.text}</div>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="messageTemplate" user={currentUserModel} messageTemplate={messageTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel = {
id: "user2",
user: "Michale Suyama"
};
const timeBreakTemplate = (context) => {
var date = new Date(context.messageDate);
var day = String(date.getDate()).padStart(2, '0');
var month = String(date.getMonth() + 1).padStart(2, '0');
var year = date.getFullYear();
var hours = date.getHours();
var minutes = String(date.getMinutes()).padStart(2, '0');
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12 || 12;
var formattedDate = `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
return (
<div className="timebreak-wrapper">{formattedDate}</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="timeBreakTemplate" user={currentUserModel} showTimeBreak={true} timeBreakTemplate={timeBreakTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} timeStamp={new Date("December 25, 2024 7:30")}></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} timeStamp={new Date("December 25, 2024 8:00")}></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} timeStamp={new Date("December 25, 2024 11:00")}></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel: UserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel: UserModel = {
id: "user2",
user: "Michale Suyama"
};
const timeBreakTemplate = (context) => {
var date = new Date(context.messageDate);
var day = String(date.getDate()).padStart(2, '0');
var month = String(date.getMonth() + 1).padStart(2, '0');
var year = date.getFullYear();
var hours = date.getHours();
var minutes = String(date.getMinutes()).padStart(2, '0');
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12 || 12;
var formattedDate = `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
return (
<div className="timebreak-wrapper">{formattedDate}</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="timeBreakTemplate" user={currentUserModel} showTimeBreak={true} timeBreakTemplate={timeBreakTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} timeStamp={new Date("December 25, 2024 7:30")}></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} timeStamp={new Date("December 25, 2024 8:00")}></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} timeStamp={new Date("December 25, 2024 11:00")}></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel = {
id: "user2",
user: "Michale Suyama"
};
const reenaUserModel = {
id: "user3",
user: "Reena"
};
const typingUsers = [ michaleUserModel, reenaUserModel ];
const typingUsersTemplate = (context) => {
if (!context.users || context.users.length === 0) {
return '';
}
let usersList = context.users.map((user, i) => {
let isLastUser = i === context.users.length - 1;
return `${isLastUser && i > 0 ? 'and ' : ''}<span class="typing-user">${user.user}</span>`;
}).join(' ');
const userTemplate = `${usersList} are typing...`;
return (
<div className="typing-wrapper" dangerouslySetInnerHTML= ></div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent user={currentUserModel} typingUsers={typingUsers} typingUsersTemplate={typingUsersTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel: UserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel: UserModel = {
id: "user2",
user: "Michale Suyama"
};
const reenaUserModel: UserModel = {
id: "user3",
user: "Reena"
};
const typingUsers: UserModel[] = [ michaleUserModel, reenaUserModel ];
const typingUsersTemplate = (context) => {
if (!context.users || context.users.length === 0) {
return '';
}
let usersList = context.users.map((user, i) => {
let isLastUser = i === context.users.length - 1;
return `${isLastUser && i > 0 ? 'and ' : ''}<span class="typing-user">${user.user}</span>`;
}).join(' ');
const userTemplate = `${usersList} are typing...`;
return (
<div className="typing-wrapper" dangerouslySetInnerHTML= ></div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent user={currentUserModel} typingUsers={typingUsers} typingUsersTemplate={typingUsersTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel = {
id: "user2",
user: "Michale Suyama"
};
const suggestions = [ "Okay will check it", "Sounds good!"];
const suggestionTemplate = (context) => {
return (
<div className='suggestion-item active'>
<div className="content">{context.suggestion}</div>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="suggestionTemplate" user={currentUserModel} suggestionTemplate={suggestionTemplate} suggestions={suggestions}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const currentUserModel: UserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel: UserModel = {
id: "user2",
user: "Michale Suyama"
};
const suggestions = [ "Okay will check it", "Sounds good!"];
const suggestionTemplate = (context) => {
return (
<div className='suggestion-item active'>
<div className="content">{context.suggestion}</div>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="suggestionTemplate" user={currentUserModel} suggestionTemplate={suggestionTemplate} suggestions={suggestions}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
Footer template
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 { ChatUIComponent, MessagesDirective, MessageDirective } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const chatInstance = React.useRef(null);
const currentUserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel = {
id: "user2",
user: "Michale Suyama"
};
const sendIconClicked = () => {
const textArea = document.getElementById('chatTextArea');
if (textArea && textArea.value.length > 0) {
let value = textArea.value;
textArea.value = '';
chatInstance.current.addMessage(
{
author: michaleUserModel,
text: value
});
}
};
const footerTemplate = () => {
return (
<div className="custom-footer">
<input id="chatTextArea" className="e-input" placeholder="Type your message..."></input>
<button id="sendMessage" className="e-btn e-primary" onClick={sendIconClicked}>
<span className="e-icons e-send-1"></span>
</button>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="footerTemplate" ref={chatInstance} user={currentUserModel} footerTemplate={footerTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));
import { ChatUIComponent, MessagesDirective, MessageDirective, UserModel } from '@syncfusion/ej2-react-interactive-chat';
import * as React from 'react';
import * as ReactDOM from "react-dom";
function App() {
const chatInstance = React.useRef<ChatUIComponent>(null);
const currentUserModel: UserModel = {
id: "user1",
user: "Albert"
};
const michaleUserModel: UserModel = {
id: "user2",
user: "Michale Suyama"
};
const sendIconClicked = () => {
const textArea = document.getElementById('chatTextArea') as HTMLInputElement;
if (textArea && textArea.value.length > 0) {
let value = textArea.value;
textArea.value = '';
chatInstance.current.addMessage(
{
author: michaleUserModel,
text: value
});
}
};
const footerTemplate = () => {
return (
<div className="custom-footer">
<input id="chatTextArea" className="e-input" placeholder="Type your message..."></input>
<button id="sendMessage" className="e-btn e-primary" onClick={sendIconClicked}>
<span className="e-icons e-send-1"></span>
</button>
</div>
);
};
return (
// specifies the tag for render the Chat UI component
<ChatUIComponent id="footerTemplate" ref={chatInstance} user={currentUserModel} footerTemplate={footerTemplate}>
<MessagesDirective>
<MessageDirective text="Hi Michale, are we on track for the deadline?" author={currentUserModel} ></MessageDirective>
<MessageDirective text="Yes, the design phase is complete." author={michaleUserModel} ></MessageDirective>
<MessageDirective text="I’ll review it and send feedback by today." author={currentUserModel} ></MessageDirective>
</MessagesDirective>
</ChatUIComponent>
);
}
ReactDOM.render(<App />, document.getElementById('container'));