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 - - item or 1. 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

  1. Always provide role - Required for proper styling
  2. Include timestamps - Helps users understand conversation flow
  3. Use unique IDs - For React key props
  4. Sanitize content - Markdown is automatically sanitized
  5. 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