# Message

> One chat message with sender, time, a bubble, reply quote, preview, attachment, reactions and delivery status.

URL: https://apogee.avaui.dev/docs/message
Last updated: 2026-10-15

One chat message with sender, time, a bubble, reply quote, preview, attachment, reactions and delivery status.

Last updated October 15, 2026

```astro
<ol aria-label="Conversation" class="flex flex-col gap-4">
<Message name="Ana Lima" time="9:41" datetime="2026-10-15T09:41">
  <Avatar slot="avatar" name="Ana Lima" size="small" status="online" />
  Can you check the launch brief before lunch?
</Message>
<Message me time="9:43" datetime="2026-10-15T09:43" status="read">
  <span slot="reply">Can you check the launch brief before lunch?</span>
  On it. The copy section needs one more pass.
</Message>
</ol>
```

## Add

```sh
npx @ava-ui/apogee add message
```

Uses `@lucide/astro` for the status glyphs. Pair with `Avatar` in the `avatar` slot.

## Usage

```astro
---
import Message from '@/components/apogee/Message/Message.astro'
---
<ol aria-label="Conversation">
  <Message name="Ana" time="9:41">Hi!</Message>
  <Message me time="9:42" status="sent">Hello.</Message>
</ol>
```

## Anatomy

-   **Row** — an `<li>` (or `div` with `as="div"`); your own messages (`me`) run end to start.
-   **`avatar`** slot — beside the bubble, aligned to its bottom.
-   **Header** — `<cite>` for the sender and `<time>` for the time.
-   **Bubble** — the text; the corner nearest the sender is square. Holds the `reply` quote above the text, and the `preview` and `attachment` below it.
-   **`reactions`** slot — a row under the bubble.
-   **Status** — a glyph with screen-reader text; failures also show the text.

## API

`@composable` — any other attribute passes through to the row.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` | — | Sender, in `<cite>`. |
| `time` | `string` | — | Shown time. |
| `datetime` | `string` | — | Machine-readable time for `<time datetime>`. |
| `me` | `boolean` | `false` | Your own message: end-aligned, primary bubble. |
| `status` | `'sent' \| 'read' \| 'failed'` | — | Delivery status under the bubble. |
| `typing` | `boolean` | `false` | Three animated dots instead of the text, labelled with the sender, e.g. “Ana Lima is typing”. |
| `as` | `'li' \| 'div'` | `'li'` | Row element. |
| `class` | `string` | — | Extra classes on the row. |

## Variants

Every `status`, a link preview, an attachment and reactions:

```astro
<Message me status="sent">Sent</Message>
<Message me status="read">Read</Message>
<Message me status="failed">Failed</Message>
```

## States

-   **Typing** — three dots, labelled for assistive tech; still under reduced motion.

```astro
<Message name="Ana Lima" typing><Avatar slot="avatar" name="Ana Lima" size="small" /></Message>
```

## Examples

A conversation with a day marker, and a composer under it. Composers are plain forms: a Textarea and a send Button.

```astro
<ol aria-label="Conversation" class="flex flex-col gap-4">
<li><Divider>Today</Divider></li>
<Message …>…</Message>
</ol>
<form class="flex items-end gap-2">
<Textarea label="Message" rows={2} class="flex-1" />
<Button type="submit" iconOnly aria-label="Send"><Send /></Button>
</form>
```

## Accessibility

-   Put Messages in an `<ol>` with an `aria-label`; each row is a list item, so screen readers announce position and count.
-   The sender is `<cite>` and the time is `<time datetime>`.
-   Status glyphs carry screen-reader text (“Sent”, “Read”, “Failed to send”).
-   The typing bubble is an image labelled with the sender, e.g. “Ana Lima is typing”; its dots stop moving under reduced motion.
-   Bubble colours come from the hue tokens and keep AA in both themes.

## Tokens

| Token | Used for |
| --- | --- |
| `--background-neutral-faded` / `--foreground-neutral` | Others’ bubbles |
| `--background-primary` / `--on-primary` | Your bubbles |
| `--border-primary` | Reply quote rule (others) |
| `--foreground-neutral-faded` | Time, status |
| `--foreground-critical` | Failed status |

## Do / Don’t

-   **Do** keep one Message per send; split long thoughts into several.
-   **Do** show `status` only on your own messages.
-   **Don’t** colour bubbles per person; the side and the avatar carry identity.
-   **Don’t** hide actions behind hover only; put them in a menu reachable by keyboard.

## Content

-   Times are short (“9:41”, “Yesterday”); the full date belongs in `datetime`.
-   Day markers in the list (“Today”, “Monday”) use a Divider.

## Related

[

AvatarA user image, with an initials fallback derived from name.

](https://apogee.avaui.dev/docs/avatar)[

TextareaA labeled multiline input, wired the same way as Input — label, hint, and error.

](https://apogee.avaui.dev/docs/textarea)[

DividerA separator between content, horizontal or vertical.

](https://apogee.avaui.dev/docs/divider)[

TimelineA vertical list of events with a connecting line — activity log, history, changelog.

](https://apogee.avaui.dev/docs/timeline)
