Join our Discord Community

React AI Message

Chat interface messages with avatars and role-based styling. Build conversational interfaces with React, Next.js, and TypeScript, featuring flexible content and avatar displays for shadcn/ui applications.

Trying to implement AI Elements?

Join our Discord community for help from other developers.


Chat message containers with role-based styling for user vs assistant messages in conversational AI applications. This free open source React component handles layout, avatars, and content formatting so AI chat applications look professional in Next.js projects.

Message display with avatars

Role-based styling with avatar support:

Loading component...

Automatically adjusts layout based on message role (user messages align right, assistant left) in React applications. Includes avatar support with fallbacks and consistent spacing for TypeScript implementations.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/ai.json
npx shadcn@latest add https://www.shadcn.io/registry/ai.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/ai.json
bunx shadcn@latest add https://www.shadcn.io/registry/ai.json

Usage

import {
  Message,
  MessageContent,
  MessageAvatar
} from '@/components/ai/message';

<Message from="user">
  <MessageAvatar src="/user-avatar.jpg" name="User" />
  <MessageContent>Hello, how can I help you today?</MessageContent>
</Message>

<Message from="assistant">
  <MessageAvatar src="" name="AI" />
  <MessageContent>I'd be happy to help! What do you need assistance with?</MessageContent>
</Message>

Why not just use divs with text-align?

Raw divs look amateur and break on mobile in React applications. Users need visual hierarchy to follow conversations—who said what, when, and in what order in JavaScript frameworks.

Most developers underestimate how much styling affects trust in Next.js projects. Professional-looking messages make AI responses feel more credible in TypeScript implementations.

Usage with Vercel AI SDK

Build chat interfaces using Vercel AI SDK's useChat hook with proper message roles in React applications:

"use client";

import {
  Conversation,
  ConversationContent,
} from "@/components/ai/conversation";
import {
  Message,
  MessageContent,
  MessageAvatar,
} from "@/components/ai/message";
import {
  PromptInput,
  PromptInputTextarea,
  PromptInputSubmit,
} from "@/components/ai/prompt-input";
import { useChat } from "@ai-sdk/react";
import { useState } from "react";

export default function Chat() {
  const [input, setInput] = useState("");
  const { messages, append, status } = useChat();

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (input.trim()) {
      append({ role: "user", content: input });
      setInput("");
    }
  };

  return (
    <div className="flex flex-col h-full">
      <Conversation>
        <ConversationContent>
          {messages.map((message) => (
            <Message from={message.role} key={message.id}>
              <MessageAvatar
                src={message.role === "user" ? "/user.jpg" : ""}
                name={message.role === "user" ? "User" : "AI"}
              />
              <MessageContent>{message.content}</MessageContent>
            </Message>
          ))}
        </ConversationContent>
      </Conversation>

      <PromptInput onSubmit={handleSubmit}>
        <PromptInputTextarea
          value={input}
          placeholder="Type your message..."
          onChange={(e) => setInput(e.currentTarget.value)}
        />
        <PromptInputSubmit status={status} disabled={!input.trim()} />
      </PromptInput>
    </div>
  );
}

Backend route for chat responses:

// app/api/chat/route.ts
import { streamText, convertToModelMessages } from "ai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: "openai/gpt-4o",
    messages: convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}

Features

  • Role-based layout (user right, assistant left, system centered) in React applications
  • Avatar support with automatic initials fallback for TypeScript projects
  • Responsive padding and sizing for mobile in Next.js implementations
  • Content wrapper that handles markdown and rich content in JavaScript frameworks
  • Proper accessibility with ARIA labeling for screen readers
  • Works with any Vercel AI SDK setup and AI chat applications
  • Free open source component designed for conversational AI interfaces and customer support

API Reference

Message

Container component for a single message with role-based styling.

PropTypeDefaultDescription
from"user" | "assistant"-Required - Message sender role
classNamestring-Additional CSS classes
...propsHTMLAttributes<HTMLDivElement>-Standard div attributes

MessageContent

Content wrapper for message text or custom content.

PropTypeDescription
classNamestringAdditional CSS classes
...propsHTMLAttributes<HTMLDivElement>Standard div attributes

MessageAvatar

Avatar display with name-based fallback.

PropTypeDescription
srcstringRequired - Avatar image source URL
namestringName for fallback initials (first 2 characters)
classNamestringAdditional CSS classes
...propsComponentProps<typeof Avatar>Avatar component props

Keyboard interactions

KeyDescription
TabNavigate between interactive message elements

Message layout gotchas

Inconsistent alignment breaks UX: User messages always right, assistant always left in React applications. Don't get creative with this—users expect consistency across JavaScript frameworks.

Missing avatar fallbacks: Not everyone has profile pictures in TypeScript projects. Generate initials or use placeholder icons. Empty avatars look broken in Next.js implementations.

Long messages break mobile: Set max-width constraints in React components. 65ch works for desktop, shorter for mobile. Test with real AI responses that can be 500+ words.

Forgetting loading states: Show typing indicators when AI is generating in JavaScript applications. Dead silence makes users think it crashed in React projects.

Avatar sizing on mobile: Desktop avatars look huge on mobile in Next.js applications. Scale down or your chat will look cramped in TypeScript implementations.

Integration with other components

Works great with Conversation for auto-scrolling chat containers in React applications. Combine with Actions for message-specific operations like copy, regenerate, or edit in Next.js projects. Add PromptInput for complete chat interface. This free open source component integrates seamlessly with modern JavaScript frameworks.

Questions developers actually ask