Assistant message that streams in word by word with a soft fade, light markdown (bold, inline code, lists, fenced code), code blocks that hold their frame while code arrives, a Stop button while streaming and Copy / Regenerate when done.
Set your access key from API keys as NEXTUI_TOKEN in .env.local and add the @nextui namespace below to components.json once. Then every item installs by name. Each install counts as a copy on a free account.
$pnpm dlx shadcn@latest add @nextui/streaming-message
1{2"registries": {3"@nextui": {4"url": "https://nextui.dev/r/{name}.json",5"headers": { "Authorization": "Bearer ${NEXTUI_TOKEN}" }6}7}8}
1"use client";23import { useChat } from "@ai-sdk/react";4import { StreamingMessage } from "@/components/nextui/streaming-message";56export function Messages() {7const { messages, status, stop, regenerate } = useChat();89return messages.map((message, m) =>10message.role === "assistant"11? message.parts.map((part, i) =>12part.type === "text" ? (13<StreamingMessage14key={`${message.id}-${i}`}15part={part}16onStop={stop}17onRegenerate={m === messages.length - 1 && status === "ready" ? () => regenerate() : undefined}18/>19) : null,20)21: null,22);23}
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | – | Markdown-ish text: paragraphs, **bold**, `code`, "- " lists and ``` fenced code |
| streaming | boolean | false | Tokens are still arriving: shows the caret and the Stop button |
| part | { type: string; text: string; state?: "streaming" | "done" } | – | An AI SDK text part; fills text and streaming |
| onStop | () => void | – | Shows a Stop button while streaming |
| onRegenerate | () => void | – | Shows a Regenerate button once done |
| autoPlay | boolean | false | Play a scripted reply on a loop while on screen, for demos |
| className | string | – | Extra classes on the wrapper |
Sign in to see the code
Preview it freely. A free account copies code and prompts a few times a day.