Messages
Lab Available in release assets
Render an ordered, linkable, server-owned message transcript that tolerates realtime append and replay.
Messages primary example
<ol class="thin-messages" id="message-list" aria-label="Conversation messages">
<li id="message-101">
<article>
<header>
<strong>Ryan</strong>
<a href="/conversations/support/messages/101"><time datetime="2026-08-01T19:30:00Z">2:30 PM</time></a>
</header>
<p>A long server-rendered message wraps without changing its durable identifier or authored reading order.</p>
</article>
</li>
</ol>Show code
<ol class="thin-messages" id="message-list" aria-label="Conversation messages">
<li id="message-101">
<article>
<header>
<strong>Ryan</strong>
<a href="/conversations/support/messages/101"><time datetime="2026-08-01T19:30:00Z">2:30 PM</time></a>
</header>
<p>A long server-rendered message wraps without changing its durable identifier or authored reading order.</p>
</article>
</li>
</ol>Anatomy
- Stable conversation or transcript region
- Ordered server-owned message list
- Durable message IDs and permalinks
- Named native message form
- Server status/error response
Variants and sizes
- Chronological transcript
- Paginated history
- System message
Gallery coverage: No structured variant fixtures are published yet; the primary example above is the only verified production markup.
States and difficult content
Rendered fixtures exercise authored content and constrained layouts with the same production assets.
- Initial history
- Pending send
- Sent
- Validation error
- Send failure
- Disconnected
- Reconnecting
- Duplicate replay
- Long message
- Empty conversation
- Permission revoked
Structured state fixtures are not published for this item yet.
Interaction and keyboard behavior
Messages are rendered and ordered by the server with stable IDs. Realtime patches append unseen IDs, update delivery state only from server truth, and preserve the reader's scroll/focus position. Older-history links remain durable.
Accessibility
Use an ordered transcript with authors and machine-readable times, a labelled textarea, text errors, and a real submit button. Announce only newly appended messages after initial load; do not replay the whole transcript. Keep focus in the composer after a successful send, move it to an error only when useful, and never steal focus for incoming messages.
- Contract
LIVE- Basis
- Native labelled list and form with status/error content; not an APG Feed claim until feed loading, article relationships, and focus/scroll rules exist
- Evidence
tests/unit/library/chat-messages.test.ts
API
Use .thin-messages on an ol with stable identified list items. Provide authors, time elements, message permalinks, and server cursors outside the design-system contract.
Behavior tier: datastar-required
Structured host, property, and example tables are not authored for this item yet. Use the summary above and the primary example.
Fallback
The server-rendered transcript, message permalinks, and ordinary submitted message form remain complete without Datastar, SSE, or JavaScript.
Assets and dependencies
/labs.css
Dependencies: datastar@1.0.2
Source: packages/ui/src/items/chat/style.ts
Composition
Derived from the examples and style specs, not authored.