Chat Bubble
A chat bubble renders a single message in a conversation thread. Received messages sit left with a neutral fill; sent messages sit right with the primary fill.
Hi there! How can I assist you today?
I accidentally deleted some important files. Can they be recovered?
I'm sorry to hear that. Let me guide you through the process to resolve it.
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
SenderName: "Penguin UI",
Message: "Hi there! How can I assist you today?",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Sent,
Message: "I accidentally deleted some important files. Can they be recovered?",
})With Timestamp
Set Timestamp (e.g. "11:32 AM") to show the send time next to the sender. It surfaces in the header line, so pair it with a SenderName.
Did the deploy finish?
Just went green a minute ago.
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
SenderName: "Ada",
Timestamp: "11:32 AM",
Message: "Did the deploy finish?",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Sent,
SenderName: "You",
Timestamp: "11:33 AM",
Message: "Just went green a minute ago.",
})With Avatar
Set ShowAvatar: true to render the avatar column. Provide AvatarInitials + AvatarVariant for a colored fallback, or AvatarSrc for an image. The avatar flips to the correct side automatically for sent messages.
Welcome to the team channel!
Thanks, glad to be here.
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
Message: "Welcome to the team channel!",
ShowAvatar: true,
AvatarInitials: "AL",
AvatarVariant: "info",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Sent,
Message: "Thanks, glad to be here.",
ShowAvatar: true,
AvatarSrc: "/assets/avatar.jpg",
})Sender Name & Status
SenderName labels a received message; Status (Sending / Delivered / Seen) renders under your own sent bubbles to convey delivery state.
Pushed the fix — can you review?
On it now.
LGTM, approved.
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
SenderName: "Grace",
Message: "Pushed the fix — can you review?",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Sent,
Message: "On it now.",
Status: chatbubble.StatusDelivered,
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Sent,
Message: "LGTM, approved.",
Status: chatbubble.StatusSeen,
})Grouped (Consecutive)
Set Grouped: true on consecutive messages from the same sender. Grouped bubbles tighten the spacing and suppress the avatar + name so a run of messages reads as one block.
I split the work into three slices.
Taking the first one myself.
Can you grab the second?
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
SenderName: "Ada",
ShowAvatar: true,
AvatarInitials: "AL",
AvatarVariant: "info",
Message: "I split the work into three slices.",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
Grouped: true,
Message: "Taking the first one myself.",
})
@chatbubble.ChatBubble(chatbubble.Config{
Side: chatbubble.Received,
Grouped: true,
Message: "Can you grab the second?",
})Typing Indicator
@chatbubble.TypingIndicator renders a received-style row with three animated dots and no text — show it while a sender composes a reply.
@chatbubble.TypingIndicator(chatbubble.Config{
ShowAvatar: true,
AvatarInitials: "AL",
AvatarVariant: "info",
})API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
Side | Side | "received" | Alignment + color: Received (left/neutral), Sent (right/primary), or Auto (resolved client-side via data-mine). |
Message | string | "" | The bubble text. |
SenderName | string | "" | Name shown bold inside the bubble, above the message (hidden on own/Sent bubbles and when Grouped). |
Timestamp | string | "" | Send time shown next to the sender name, e.g. "11:32 AM". |
Status | Status | StatusNone | Delivery state under a sent bubble: StatusSending, StatusDelivered, or StatusSeen. |
AvatarSrc | string | "" | Optional avatar image URL; takes precedence over initials. |
AvatarInitials | string | "" | Initials fallback shown when no AvatarSrc is set. |
AvatarVariant | string | "" | avatar.Variant token for the initials fallback color, e.g. "info". |
ShowAvatar | bool | false | Render the avatar column (suppressed when Grouped). |
Grouped | bool | false | Mark a consecutive message: tighten spacing, hide avatar + name. |
Sender | string | "" | For Side=Auto, emitted as data-sender for client mine-detection. |
IsBot | bool | false | Render a small BOT badge beside the sender name. |
RootClass | string | "" | Extra CSS classes appended to the row element. |
RootAttrs | templ.Attributes | nil | Arbitrary HTML attributes on the row element (e.g. hx-*). |