Skip to main content
RapidDev - Software Development Agency
bubble-tutorial

How to Build a Chat System with Emoji Support in Bubble

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.

What you'll learn

  • How to structure chat Data Types for messages and conversations
  • How to integrate an emoji picker into the chat input
  • How to display messages in real time with emojis rendered
  • How to implement read receipts for conversations
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read25-30 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

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

1

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.

2

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.

3

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.

Emoji grid HTML
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.

4

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.

5

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

Workflow summary
1CHAT WITH EMOJIS WORKFLOW SUMMARY
2=====================================
3
4DATA 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)
10
11SEND MESSAGE:
12 Event: Send button clicked
13 Step 1: Create Message
14 content = Input's value (includes emoji chars)
15 sender = Current User, timestamp = now
16 Step 2: Update Conversation
17 last_message = content, last_message_time = now
18 increment other user's unread_count
19 Step 3: Reset input
20
21MARK AS READ:
22 Event: Page loaded / conversation displayed
23 Search: Messages where conversation = this,
24 sender != Current User, is_read = no
25 Action: Make changes to list is_read = yes
26 Action: Reset unread_count to 0
27
28EMOJI PICKER:
29 Toggle popup with emoji grid
30 On emoji click: append character to input
31 Emojis render natively in text elements
32
33MESSAGE DISPLAY:
34 Repeating Group: Messages sorted by timestamp
35 Conditionals:
36 sender = Current User right-aligned, blue
37 sender != Current User left-aligned, grey
38 Read indicator: show checkmark when is_read = yes

Common 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.

ChatGPT Prompt

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?

Bubble Prompt

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.