Displays a single chat message (user or assistant) with markdown support.
Overview
The ChatMessage component provides:
- Message display (user or assistant)
- Markdown rendering for assistant messages
- Copy button for assistant messages
- Timestamp display
- Different styling for user vs assistant
Basic Usage
import ChatMessage from "@/components/ai/ChatMessage";
export default function MessageList() {
const messages = [
{ role: "user", content: "Hello!", timestamp: new Date() },
{ role: "assistant", content: "Hi there! How can I help?", timestamp: new Date() },
];
return (
<div>
{messages.map((msg, idx) => (
<ChatMessage
key={idx}
role={msg.role}
content={msg.content}
timestamp={msg.timestamp}
/>
))}
</div>
);
}
Props
interface ChatMessageProps {
role: "user" | "assistant" | "system";
content: string;
timestamp?: Date;
id?: string;
}
Features
Markdown Rendering
Assistant messages automatically render markdown:
<ChatMessage
role="assistant"
content="# Hello\n\nThis is **bold** and this is *italic*."
/>
Uses react-markdown for safe markdown rendering.
Copy Functionality
Assistant messages include a copy button:
// Automatically included for assistant messages
<button onClick={handleCopy}>Copy</button>
Role-Based Styling
- User messages - Right-aligned, primary color background
- Assistant messages - Left-aligned, base-200 background
- System messages - Hidden by default (can be customized)
Examples
Basic Message
<ChatMessage
role="user"
content="What is TypeScript?"
timestamp={new Date()}
/>
Assistant Message with Markdown
<ChatMessage
role="assistant"
content="# TypeScript\n\nTypeScript is a typed superset of JavaScript..."
timestamp={new Date()}
/>
Message List
{messages.map((message) => (
<ChatMessage
key={message.id}
role={message.role}
content={message.content}
timestamp={message.timestamp}
id={message.id}
/>
))}
Styling
The component uses DaisyUI classes:
User Messages
className="bg-primary text-primary-content" // Primary color background
Assistant Messages
className="bg-base-200 text-base-content" // Base color background
Markdown Styling
Uses Tailwind prose classes:
className="prose prose-sm max-w-none dark:prose-invert"
Customization
Custom Message Styling
<ChatMessage
role="assistant"
content="Hello!"
className="custom-message-class"
/>
Custom Copy Button
The copy button can be customized by modifying the component:
// In ChatMessage.tsx
<button
onClick={handleCopy}
className="mt-2 text-xs opacity-70 hover:opacity-100 transition-opacity"
title="Copy message"
>
📋 Copy
</button>
Hide Timestamps
<ChatMessage
role="user"
content="Hello!"
// Omit timestamp prop to hide
/>
Integration with ChatInterface
The ChatMessage component is used internally by ChatInterface:
// ChatInterface automatically uses ChatMessage
<ChatInterface
messages={[
{ role: "user", content: "Hello" },
{ role: "assistant", content: "Hi there!" },
]}
/>
Message Format
Messages should follow this structure:
interface Message {
role: "user" | "assistant" | "system";
content: string;
timestamp?: Date;
id?: string;
}
Markdown Support
The component supports standard markdown:
- Headers -
# H1,## H2, etc. - Bold -
**bold** - Italic -
*italic* - Code -
`code` - Code blocks -
```code``` - Links -
[text](url) - Lists -
- itemor1. item
Accessibility
- ARIA labels - Proper labels for screen readers
- Keyboard navigation - Copy button is keyboard accessible
- Color contrast - Meets WCAG AA standards
- Focus management - Proper focus indicators
Best Practices
- Always provide role - Required for proper styling
- Include timestamps - Helps users understand conversation flow
- Use unique IDs - For React key props
- Sanitize content - Markdown is automatically sanitized
- Handle long messages - Component handles overflow gracefully
Performance
- React Markdown - Efficient markdown parsing
- Memoization - Consider memoizing if rendering many messages
- Virtual scrolling - For long conversation histories
Next Steps
- Learn about Chat Interface which uses this component
- Explore Chat Sidebar for conversation management
- Check out Typing Indicator for loading states