A chat system with emojis in Bubble uses a Message Data Type with sender, recipient, and text content. Emoji support comes from either native Unicode emojis typed directly or an emoji picker plugin embedded via an HTML element. Messages display in a Repeating Group sorted by timestamp, with real-time updates through Bubble's live data. This tutorial covers the full chat setup including emoji rendering and read receipts.
Overview: Chat with Emojis in Bubble
This tutorial walks you through building a real-time messaging system with emoji support. You will create the data model for conversations and messages, build the chat interface with an emoji picker, implement real-time message display, and add read receipt tracking.
Prerequisites
- A Bubble app with user authentication
- Understanding of Repeating Groups and workflows
- Familiarity with custom states and dynamic data
Step-by-step guide
Create the chat data structure
Create the chat data structure
In the Data tab, create 'Conversation' with fields: 'participants' (list of Users), 'last_message' (text), 'last_message_time' (date), 'unread_count_user1' (number), 'unread_count_user2' (number). Create 'Message' with fields: 'conversation' (Conversation), 'sender' (User), 'content' (text), 'timestamp' (date), 'is_read' (yes/no, default no). The content field stores plain text including Unicode emoji characters natively.
Expected result: Data Types for Conversation and Message are created with all fields needed for chat functionality.
Build the chat interface with message list
Build the chat interface with message list
Create a chat page with a Repeating Group for messages. Set the type to 'Message' and data source to 'Do a search for Messages where conversation = current conversation, sorted by timestamp ascending'. Inside each cell, add a Group with conditional formatting: when 'Current cell's Message's sender is Current User', align right with a blue background; otherwise align left with a grey background. Add a Text element showing 'Current cell's Message's content' and another for the timestamp.
Expected result: Messages display in a scrollable list with sender messages on the right and received messages on the left.
Add an emoji picker using an HTML element
Add an emoji picker using an HTML element
Add an HTML element next to your message input. Paste an emoji picker library like emoji-mart or a simpler custom grid of common emojis as clickable spans. When an emoji is clicked, use a JavaScript-to-Bubble plugin bridge to append the emoji character to the message input. Alternatively, use a simpler approach: add a button that toggles a popup containing a grid of emoji characters. Each emoji is a text element that, when clicked, appends its character to the message input's value using a custom state.
1<div id="emoji-grid" style="display:grid;grid-template-columns:repeat(8,1fr);gap:4px;padding:8px;max-height:200px;overflow-y:auto;">2 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>3 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>4 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">❤️</span>5 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>6 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>7 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>8 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>9 <span onclick="appendEmoji(this)" style="cursor:pointer;font-size:24px;">��</span>10</div>Pro tip: Modern browsers natively render Unicode emojis in Bubble text elements, so no special rendering is needed — just store and display the emoji characters directly.
Expected result: An emoji picker appears when the user clicks an emoji button, and selected emojis are inserted into the message input.
Create the send message workflow
Create the send message workflow
On the Send button click, create a workflow. Step 1: Create a new Message with conversation = current conversation, sender = Current User, content = message input's value, timestamp = Current date/time. Step 2: Make changes to the Conversation — set last_message to the input value, last_message_time to Current date/time, and increment the other user's unread count. Step 3: Reset the message input. The Repeating Group auto-updates to show the new message thanks to Bubble's live data.
Expected result: Sent messages appear instantly in the chat and the conversation's last message updates for the conversation list.
Implement read receipts
Implement read receipts
When a user opens a conversation, mark all unread messages from the other person as read. Add a workflow on the chat page's 'Page is loaded' event (or when the conversation is displayed): search for Messages where conversation = current conversation, sender is not Current User, and is_read is no. Use 'Make changes to a list of Things' to set is_read to yes for all results. Also reset the current user's unread_count on the Conversation to 0. Display a small check or 'Read' indicator on sent messages when is_read is yes.
Expected result: Messages show read status indicators, and unread counts reset when the user opens the conversation.
Complete working example
1CHAT WITH EMOJIS — WORKFLOW SUMMARY2=====================================34DATA TYPES:5 Conversation: participants (list of Users),6 last_message (text), last_message_time (date),7 unread_count_user1 (number), unread_count_user2 (number)8 Message: conversation (Conversation), sender (User),9 content (text), timestamp (date), is_read (yes/no)1011SEND MESSAGE:12 Event: Send button clicked13 Step 1: Create Message14 content = Input's value (includes emoji chars)15 sender = Current User, timestamp = now16 Step 2: Update Conversation17 last_message = content, last_message_time = now18 increment other user's unread_count19 Step 3: Reset input2021MARK AS READ:22 Event: Page loaded / conversation displayed23 Search: Messages where conversation = this,24 sender != Current User, is_read = no25 Action: Make changes to list → is_read = yes26 Action: Reset unread_count to 02728EMOJI PICKER:29 Toggle popup with emoji grid30 On emoji click: append character to input31 Emojis render natively in text elements3233MESSAGE DISPLAY:34 Repeating Group: Messages sorted by timestamp35 Conditionals:36 sender = Current User → right-aligned, blue37 sender != Current User → left-aligned, grey38 Read indicator: show checkmark when is_read = yesCommon mistakes when building a Chat System with Emoji Support in Bubble
Why it's a problem: Trying to convert emojis to shortcodes instead of storing Unicode directly
How to avoid: Store emoji characters as plain Unicode text — they render correctly in all Bubble text elements
Why it's a problem: Not sorting messages by timestamp ascending
How to avoid: Set the Repeating Group's sort to 'timestamp ascending' so oldest messages appear at the top
Why it's a problem: Forgetting to update the Conversation's last_message when sending
How to avoid: Always update last_message and last_message_time on the Conversation in the send workflow
Best practices
- Store emojis as native Unicode characters — no special encoding needed
- Update the Conversation record with last_message for efficient conversation list displays
- Mark messages as read when the conversation is opened, not when each message is scrolled into view
- Use Bubble's live data (auto-updating searches) for real-time message display
- Paginate message history with 'items until' to load older messages on scroll
- Add typing indicators using custom states and a timed reset
- Index the Message data type on conversation and timestamp fields for fast queries
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a messaging feature in Bubble.io that supports emojis. I need 1-on-1 chat with real-time updates, an emoji picker, and read receipts. What Data Types and workflows do I need?
Build a chat feature for my app with emoji support. Create Conversation and Message data types. Add a chat interface with messages displayed in real time, an emoji picker button, and read receipts. Messages from the current user should appear on the right in blue.
Frequently asked questions
Do emojis display correctly in all browsers with Bubble?
Yes. Modern browsers render Unicode emojis natively. The appearance varies slightly between operating systems (Apple, Google, Windows emoji styles) but all display correctly.
How do I handle group chats, not just 1-on-1?
Change the Conversation's participants field to a list of Users. Adjust the send workflow to increment unread counts for all participants except the sender. Message display logic remains the same.
Can I add image and file sharing to the chat?
Yes. Add a File Uploader to the chat input area. When a file is sent, create a Message with the file URL stored in an additional 'attachment' (file) field. Display attachments conditionally in the message cell.
How many messages can the Repeating Group handle before performance drops?
Bubble's Repeating Group works well with up to 100-200 items loaded at once. For longer conversations, implement pagination — load the last 50 messages and add a 'Load more' button for history.
Can RapidDev build a full messaging system with notifications in Bubble?
Yes. RapidDev can build complete messaging systems with text, emoji, file sharing, push notifications, typing indicators, and group chat support in Bubble.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation