---
title: "ChatMessage"
description: "Display a chat message with icon, avatar, and actions."
canonical_url: "https://vinicunca.dev/pohon/components/chat-message"
---
# ChatMessage

> Display a chat message with icon, avatar, and actions.

## Usage

The ChatMessage component renders an `<article>` element for a `user` or `assistant` chat message.

```vue
<template>
  <p-chat-message :avatar="{
    src: 'https://github.com/benjamincanac.png',
    loading: 'lazy'
  }" :parts="[
    {
      type: 'text',
      id: '1',
      text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
    }
  ]" id="1" role="user" side="right" variant="soft" />
</template>
```

> [!TIP]
> See: /pohon/components/chat-messages
> 
> Use the `ChatMessages` component to display a list of chat messages.

### Parts

Use the `parts` prop to display the message content using the AI SDK format.

```vue
<template>
  <PChatMessage :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

> [!NOTE]
> 
> The `parts` prop is the recommended format for the AI SDK. Each part has a `type` (e.g. 'text') and corresponding content. The ChatMessage component also supports the deprecated `content` prop for backward compatibility.

### Side

Use the `side` prop to display the message on the left or right.

```vue
<template>
  <PChatMessage side="right" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

> [!NOTE]
> 
> When using the [`ChatMessages`](https://vinicunca.dev/pohon/components/chat-messages) component, the `side` prop is set to `left` for `assistant` messages and `right` for `user` messages.

### Variant

Use the `variant` prop to change style of the message.

```vue
<template>
  <PChatMessage variant="soft" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

> [!NOTE]
> 
> When using the [`ChatMessages`](https://vinicunca.dev/pohon/components/chat-messages) component, the `variant` prop is set to `naked` for `assistant` messages and `soft` for `user` messages.

### Color

Use the `color` prop to change the color of the message.

```vue
<template>
  <PChatMessage variant="soft" color="primary" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

### Icon

Use the `icon` prop to display an [Icon](https://vinicunca.dev/pohon/components/icon) component next to the message.

```vue
<template>
  <PChatMessage icon="i-lucide-user" variant="soft" side="right" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

### Avatar

Use the `avatar` prop to display an [Avatar](https://vinicunca.dev/pohon/components/avatar) component next to the message.

```vue
<template>
  <PChatMessage :avatar="{
  src: 'https://github.com/benjamincanac.png',
  loading: 'lazy'
}" variant="soft" side="right" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Hello! Tell me more about building AI chatbots with Pohon UI.'
  }
]" role="user" id="1" />
</template>
```

You can also use the `avatar.icon` prop to display an icon as the avatar.

```vue
<template>
  <PChatMessage :avatar="{
  icon: 'i-lucide-bot'
}" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Pohon UI offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the Chat class from AI SDK, implementing proper message styling with variants, and utilizing the built-in actions for message interactions. The components are fully customizable with theming support and responsive design.'
  }
]" role="assistant" id="1" />
</template>
```

### Actions

Use the `actions` prop to display actions below the message that will be displayed when hovering over the message.

```vue
<script setup lang="ts">
import type { ButtonProps } from 'pohon-ui'

const actions = ref<ButtonProps[]>([
  {
    label: "Copy to clipboard",
    icon: "i-lucide-copy"
  }
])
</script>

<template>
  <PChatMessage :actions="actions" :parts="[
  {
    type: 'text',
    id: '1',
    text: 'Pohon UI offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the Chat class from AI SDK, implementing proper message styling with variants, and utilizing the built-in actions for message interactions. The components are fully customizable with theming support and responsive design.'
  }
]" role="user" id="1" />
</template>
```

## Examples

> [!TIP]
> See: /pohon/components/chat
> 
> Check the **Chat** overview page for installation instructions, server setup and usage examples.

## API

### Props

```ts
/**
 * Props for the ChatMessage component
 */
interface ChatMessageProps {
}
```

### Slots

```ts
/**
 * Slots for the ChatMessage component
 */
interface ChatMessageSlots {
}
```

## Theme

```ts [app.config.ts]
export default defineAppConfig({
  ui: {
    chatMessage: {
      slots: {
        root: 'group/message relative w-full',
        header: 'flex mb-1.5',
        container: 'relative flex items-start',
        body: 'min-w-0',
        leading: 'inline-flex items-center justify-center min-h-6',
        leadingIcon: 'shrink-0',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        files: 'flex flex-wrap items-center gap-1.5',
        content: 'relative text-pretty wrap-break-word *:first:mt-0 *:last:mb-0',
        actions: [
          'flex items-center bottom-0 absolute [@media(hover:hover)]:opacity-0 group-hover/message:opacity-100 focus-within:opacity-100',
          'transition-opacity ease-out'
        ]
      },
      variants: {
        variant: {
          solid: '',
          outline: '',
          soft: '',
          subtle: '',
          naked: ''
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        side: {
          left: {},
          right: {
            container: 'justify-end ms-auto max-w-[75%]',
            header: 'justify-end',
            actions: 'end-0'
          }
        },
        leading: {
          true: ''
        },
        actions: {
          true: ''
        },
        compact: {
          true: {
            root: 'scroll-mt-3',
            container: 'gap-1.5 pb-3',
            content: 'space-y-2',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs'
          },
          false: {
            root: 'scroll-mt-4 sm:scroll-mt-6',
            container: 'gap-3 pb-8',
            content: 'space-y-4',
            leadingIcon: 'size-8',
            leadingAvatarSize: 'md'
          }
        }
      },
      compoundVariants: [
        {
          compact: true,
          actions: true,
          class: {
            container: 'pb-8'
          }
        },
        {
          variant: [
            'solid',
            'outline',
            'soft',
            'subtle'
          ],
          compact: false,
          class: {
            content: 'px-4 py-3 rounded-lg min-h-12',
            leading: 'mt-2'
          }
        },
        {
          variant: [
            'solid',
            'outline',
            'soft',
            'subtle'
          ],
          compact: true,
          class: {
            content: 'px-2 py-1 rounded-lg min-h-8',
            leading: 'mt-1'
          }
        },
        {
          variant: 'naked',
          side: 'left',
          class: {
            body: 'w-full',
            content: 'w-full'
          }
        },
        {
          color: 'primary',
          variant: 'solid',
          class: {
            content: 'bg-primary color-primary-foreground'
          }
        },
        {
          color: 'secondary',
          variant: 'solid',
          class: {
            content: 'bg-secondary color-secondary-foreground'
          }
        },
        {
          color: 'success',
          variant: 'solid',
          class: {
            content: 'bg-success color-success-foreground'
          }
        },
        {
          color: 'info',
          variant: 'solid',
          class: {
            content: 'bg-info color-info-foreground'
          }
        },
        {
          color: 'warning',
          variant: 'solid',
          class: {
            content: 'bg-warning color-warning-foreground'
          }
        },
        {
          color: 'error',
          variant: 'solid',
          class: {
            content: 'bg-error color-error-foreground'
          }
        },
        {
          color: 'primary',
          variant: 'outline',
          class: {
            content: 'color-primary ring ring-primary/25'
          }
        },
        {
          color: 'secondary',
          variant: 'outline',
          class: {
            content: 'color-secondary ring ring-secondary/25'
          }
        },
        {
          color: 'success',
          variant: 'outline',
          class: {
            content: 'color-success ring ring-success/25'
          }
        },
        {
          color: 'info',
          variant: 'outline',
          class: {
            content: 'color-info ring ring-info/25'
          }
        },
        {
          color: 'warning',
          variant: 'outline',
          class: {
            content: 'color-warning ring ring-warning/25'
          }
        },
        {
          color: 'error',
          variant: 'outline',
          class: {
            content: 'color-error ring ring-error/25'
          }
        },
        {
          color: 'primary',
          variant: 'soft',
          class: {
            content: 'bg-primary/10 color-primary'
          }
        },
        {
          color: 'secondary',
          variant: 'soft',
          class: {
            content: 'bg-secondary/10 color-secondary'
          }
        },
        {
          color: 'success',
          variant: 'soft',
          class: {
            content: 'bg-success/10 color-success'
          }
        },
        {
          color: 'info',
          variant: 'soft',
          class: {
            content: 'bg-info/10 color-info'
          }
        },
        {
          color: 'warning',
          variant: 'soft',
          class: {
            content: 'bg-warning/10 color-warning'
          }
        },
        {
          color: 'error',
          variant: 'soft',
          class: {
            content: 'bg-error/10 color-error'
          }
        },
        {
          color: 'primary',
          variant: 'subtle',
          class: {
            content: 'bg-primary/10 color-primary ring ring-primary/25'
          }
        },
        {
          color: 'secondary',
          variant: 'subtle',
          class: {
            content: 'bg-secondary/10 color-secondary ring ring-secondary/25'
          }
        },
        {
          color: 'success',
          variant: 'subtle',
          class: {
            content: 'bg-success/10 color-success ring ring-success/25'
          }
        },
        {
          color: 'info',
          variant: 'subtle',
          class: {
            content: 'bg-info/10 color-info ring ring-info/25'
          }
        },
        {
          color: 'warning',
          variant: 'subtle',
          class: {
            content: 'bg-warning/10 color-warning ring ring-warning/25'
          }
        },
        {
          color: 'error',
          variant: 'subtle',
          class: {
            content: 'bg-error/10 color-error ring ring-error/25'
          }
        },
        {
          color: 'primary',
          variant: 'naked',
          class: {
            content: 'color-primary'
          }
        },
        {
          color: 'secondary',
          variant: 'naked',
          class: {
            content: 'color-secondary'
          }
        },
        {
          color: 'success',
          variant: 'naked',
          class: {
            content: 'color-success'
          }
        },
        {
          color: 'info',
          variant: 'naked',
          class: {
            content: 'color-info'
          }
        },
        {
          color: 'warning',
          variant: 'naked',
          class: {
            content: 'color-warning'
          }
        },
        {
          color: 'error',
          variant: 'naked',
          class: {
            content: 'color-error'
          }
        },
        {
          color: 'neutral',
          variant: 'solid',
          class: {
            content: 'bg-background-inverted color-text-inverted'
          }
        },
        {
          color: 'neutral',
          variant: 'outline',
          class: {
            content: 'bg-background ring ring-border'
          }
        },
        {
          color: 'neutral',
          variant: 'soft',
          class: {
            content: 'bg-background-elevated/50'
          }
        },
        {
          color: 'neutral',
          variant: 'subtle',
          class: {
            content: 'bg-background-elevated/50 ring ring-border'
          }
        }
      ],
      defaultVariants: {
        side: 'left',
        variant: 'naked',
        color: 'neutral'
      }
    }
  }
})
```

## Changelog

See commit history for [component](https://github.com/vinicunca/pohon/commits/main/src/runtime/components/ChatMessage.vue) and [theme](https://github.com/vinicunca/pohon/commits/main/src/theme/chat-message.ts).

---

- [GitHub](https://github.com/vinicunca/pohon/blob/main/src/runtime/components/ChatMessage.vue)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
