Getting Started
Components
- Agent Status
- Agent Template Card
- API Key Card
- Audio Player
- Bar Visualizer
- Channel Status Card
- Chat Composer
- Code Editor
- Condition Builder
- Confirm Dialog
- Conversation
- Conversation Bar
- Dataset Card
- Document Status Badge
- Extraction Strategy Select
- File Icon
- File Upload
- Indexing Progress
- Live Waveform
- Matrix
- Message
- Mic Selector
- Model Diff View
- Model Selector
- Model Type Filter
- Node Catalog
- Option Editor
- Orb
- Output Variables View
- Package Card
- Prompt Editor
- Provider Status Card
- Radio Card
- Resource Card
- Resource Sidebar
- Response
- Run Node List
- Scrub Bar
- Segment Card
- Shimmering Text
- Speech Input
- Token Trend Chart
- Tool Call Card
- Transcript Viewer
- Usage Stat Card
- Variable Binding Editor
- Variable Selector
- Voice Button
- Voice Picker
- Waveform
- Workflow Node Card
- Workspace Selector
"use client"
import { useEffect, useState } from "react"
import { Message, MessageContent } from "@/components/ui/message"
import { Response } from "@/components/ui/response"
const assistantMessageTokens = [
"To",
" create",
" a",
" new",
" agent",
" with",
" **",
"ZGI",
" Agents",
"**",
",",
" head",
" to",
" this",
" link",
":",
" ",
"[",
"https://zgi.ai/agents",
"](",
"https://zgi.ai/agents",
")",
".",
"\n\n",
"1.",
" Sign",
" in",
" to",
" your",
" ZGI",
" account",
".",
"\n",
"2.",
" Click",
" **New",
" Agent**",
" to",
" start",
".",
"\n",
"3.",
" Give",
" your",
" agent",
" a",
" name",
" and",
" description",
".",
"\n",
"4.",
" Configure",
" its",
" behavior",
",",
" knowledge",
" sources",
",",
" and",
" voice",
".",
"\n",
"5.",
" Save",
" it",
" —",
" and",
" your",
" agent",
" is",
" ready",
" to",
" use",
".",
]
function ZgiMark({ className }: { className?: string }) {
return (
<svg
viewBox="0 0 64 64"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
className={className}
>
<rect width="64" height="64" rx="18" fill="#0052FF" />
<path
d="M20 17h24v6.5l-15.5 21H44V51H19v-6l15.2-21.5H20V17z"
fill="white"
/>
</svg>
)
}
const Example = () => {
const [content, setContent] = useState("\u200B")
useEffect(() => {
let currentContent = ""
let index = 0
const interval = setInterval(() => {
if (index < assistantMessageTokens.length) {
currentContent += assistantMessageTokens[index]
setContent(currentContent)
index++
} else {
clearInterval(interval)
}
}, 100)
return () => {
clearInterval(interval)
}
}, [])
return (
<>
<style jsx global>{`
.message-demo-lists ol,
.message-demo-lists ul {
padding-left: 1.25rem !important;
}
.message-demo-lists li {
margin-left: 0 !important;
}
`}</style>
<div className="flex h-full max-h-[400px] w-full max-w-2xl flex-col overflow-hidden">
<div className="flex flex-col gap-4 overflow-y-auto px-4 py-4">
<div className="flex-shrink-0">
<Message from="user">
<MessageContent>
<Response>How do I create an agent?</Response>
</MessageContent>
</Message>
</div>
<div className="message-demo-lists flex-shrink-0">
<Message from="assistant">
<MessageContent>
<Response>{content}</Response>
</MessageContent>
<div className="ring-border bg-background flex size-8 items-center justify-center overflow-hidden rounded-full ring-1">
<ZgiMark className="size-7" />
</div>
</Message>
</div>
</div>
</div>
</>
)
}
export Example
Installation
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/message.json
Usage
import { Message, MessageAvatar, MessageContent } from "@/components/ui/message"Basic Message
<Message from="user">
<MessageAvatar src="/user-avatar.jpg" name="Ari" />
<MessageContent>Can ZGI summarize this workflow?</MessageContent>
</Message>
<Message from="assistant">
<MessageAvatar src="/assistant-avatar.jpg" name="ZGI" />
<MessageContent>Yes. I can extract the key steps and open decisions.</MessageContent>
</Message>Message Variants
The MessageContent component supports two variants:
import { Message, MessageAvatar, MessageContent } from "@/components/ui/message"
export default () => (
<>
{/* Contained variant - default, has background and padding */}
<Message from="user">
<MessageAvatar src="/user-avatar.jpg" />
<MessageContent variant="contained">
This is a contained message with background
</MessageContent>
</Message>
{/* Flat variant - no background for assistant, minimal styling */}
<Message from="assistant">
<MessageAvatar src="/assistant-avatar.jpg" />
<MessageContent variant="flat">
This is a flat message with minimal styling
</MessageContent>
</Message>
</>
)In a Conversation
import { Conversation, ConversationContent } from "@/components/ui/conversation"
import { Message, MessageAvatar, MessageContent } from "@/components/ui/message"
export default ({ messages }) => (
<Conversation>
<ConversationContent>
{messages.map((message) => (
<Message key={message.id} from={message.from}>
<MessageAvatar src={message.avatarUrl} name={message.name} />
<MessageContent>{message.content}</MessageContent>
</Message>
))}
</ConversationContent>
</Conversation>
)API Reference
Message
The main container component that handles layout and alignment based on message sender.
Props
| Prop | Type | Description |
|---|---|---|
| from | "user" | "assistant" | Required. Determines alignment and styling |
| className | string | Optional CSS classes |
| ...props | HTMLDivElement | All standard div element props |
MessageContent
Container for message text and content with variant styling.
Props
| Prop | Type | Description |
|---|---|---|
| variant | "contained" | "flat" | Visual style variant (default: "contained") |
| className | string | Optional CSS classes |
| children | ReactNode | Message content |
| ...props | HTMLDivElement | All standard div element props |
MessageAvatar
Avatar component for displaying user or assistant profile images.
Props
| Prop | Type | Description |
|---|---|---|
| src | string | Required. Avatar image URL |
| name | string | Name for fallback (shows first 2 chars if no image) |
| className | string | Optional CSS classes |
| ...props | AvatarProps | All standard Avatar component props |
Notes
- Uses CSS group selectors for context-aware styling based on
fromprop - User messages align to the right, assistant messages to the left
- Contained variant provides background colors that differ for user/assistant
- Flat variant is useful for assistant messages in a minimal design
- Avatar has a subtle ring border and fallback text support
- Works seamlessly with the Conversation component
- This component is inspired by Vercel's AI SDK Message component with modifications for ZGI UI
Deploy and Scale Agents with ZGI
ZGI delivers the infrastructure and developer experience you need to ship reliable audio & agent applications at scale.
Talk to an expert