Message content

Free · MIT

A message's blocks, in order. Build them from text with plainBlocks(text) for a person's words (newlines kept, no markdown) and markdownBlocks(text) for an agent's answer, both from safe-markdown, which installs with this item. Import them from there: they run on the server too. A model's links show as text, never as clickable links.

Markdown

Preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/message-content

Brings in: attachment-preview, card-registry, chat, citation, degraded-panel, entity-chip, locale, payload, safe-markdown, terms, tool-call, tooltip, utils

Usage

TSX · The example above
"use client"

import { MessageContent } from "@/components/message-content"

export default function Example() {
  return (
    <MessageContent
      className="max-w-lg"
      blocks={[
        { kind: "paragraph", nodes: [{ kind: "text", text: "Three orders are delayed. " }, { kind: "strong", text: "Two" }, { kind: "text", text: " are waiting on the same carrier." }] },
        { kind: "list", items: [[{ kind: "code", text: "#4821" }, { kind: "text", text: " — carrier delay" }], [{ kind: "code", text: "#4830" }, { kind: "text", text: " — carrier delay" }], [{ kind: "code", text: "#4833" }, { kind: "text", text: " — out of stock" }]] },
        { kind: "paragraph", nodes: [{ kind: "provisional", nodes: [{ kind: "text", text: "The carrier expects to catch up by Friday." }], reason: "From the carrier’s status page; not confirmed." }] },
      ]}
    />
  )
}

<MessageContent>

PropTypeDefaultDescription
blocksrequiredMessageBlock[]—The reply as typed blocks: paragraphs, lists, payloads, tool calls, cards, attachments.
sourcesMessageSource[] | undefined[]Sources the blocks cite by marker.
onOpenEntity((entity: EntityRef) => void) | undefined—Makes entity chips open their thing.
onNavigate((to: string) => void) | undefined—Follows in-app links; links from a model are never rendered.
onOpenAttachment((attachment: Attachment) => void) | undefined—Makes attachment tiles buttons that open their file.
bareCodeboolean | undefined—Code and other payload blocks without their frame and title bar (Payload's `bare`).
classNamestring | undefined—Extra classes for the outer element.

<Inline>

Inline nodes. Every string here may come from a model or the user's system, so it is only ever rendered as a React text child: no markdown parsing, no HTML.

PropTypeDefaultDescription
nodesrequiredInlineNode[]—Inline nodes: text, strong, code, entities, citations.

Functions

blocksToText(blocks: MessageBlock[], sources: MessageSource[] = [])

Plain text of a message, for copy. Citations become [n]; entities their API name.

Strings

The fixed words, in English by default. Change any of them under messageContent in <LocaleProvider strings={{ … }}>; the table is exported as messageContentStrings.

KeyEnglish
measuredFrom the {environment}
measuredFromFrom the {environment}: {source}
notVerified (not verified)
provisionalThe agent hasn’t verified this against the {environment}.