Templates in React Chat UI component

17 Dec 202424 minutes to read

The Chat UI component provides several templates for customizing the appearance of the empty conversation area, messages, typing indicator, and more. These templates provide flexibility for users to create a unique, personalized chat experience.

Empty chat template

You can use the emptyChatTemplate property to customize the chat interface when no messages are displayed. Personalized content, such as welcome messages or images, can be added to create an engaging and inviting experience for users starting a conversation.

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

You can use the messageTemplate property to customize the appearance and styling of each chat message. Modify text styling, layout, and other design elements to ensure a personalized chat experience. The template context includes message and index items.

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

You can use the timeBreakTemplate property to customize how time breaks are displayed with using the template, such as showing “Today,” “Yesterday,” or specific dates. This enhances conversation organization by clearly separating messages based on time, improving readability for the user. The template context includes messageDate.

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

You can use the typingUsersTemplate property to customize the display of users currently typing in the chat. It allows for styling and positioning of the typing indicator, enhancing the user experience. The template context includes 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 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

You can use the suggestionTemplate property to customize the quick reply suggestions that appear above the input field. Templates here can help create visually appealing and functional suggestion layouts. The template context includes suggestion and index items.

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'));

You can use the footerTemplate property to customize the default footer area and manage message send actions with a personalized design. This flexibility allows users to create unique footers that meet their specific needs.

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'));