Conversation export
Downloads a Markdown snapshot from explicit message text, attachments, and structured tool results.
Preview
In action
Keep a Markdown snapshot
When to use
Use it for
- Pass explicit message data to serializeConversation or ConversationDownload. No rendered DOM is scraped.
- Use serializePart for application-specific export formatting. The download owns and releases its object URLs.
Avoid
- Coercing arbitrary message objects into strings or claiming persistence from a local download.
Install
React package
npm install @noorddev/vlak-react
Load the stylesheet once at your app root, then import the components you use.
import "@noorddev/vlak-react/css";
import { ConversationDownload } from "@noorddev/vlak-react";Per-component imports are available at @noorddev/vlak-react/components/conversation-export.
Copy the source
npx @noorddev/vlak-cli add conversation-export
Adds the component and its dependencies to components/vlak/. Follow the StyleX setup to compile the source in your application.
shadcn registry
npx shadcn add https://vlak.dev/r/conversation-export.json
Installs the same source through the shadcn CLI.
React
import { ConversationDownload } from "@noorddev/vlak-react";
<ConversationDownload title="Project review" messages={[{ role: "user", content: "Review the brief" }, { role: "assistant", parts: [{ type: "text", text: "Two owners are missing." }] }]} />See the integration example to compose these components with your application's model and data.
Props
ConversationDownload
Downloads a Markdown snapshot using supplied message data, without reading rendered DOM.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "ghost" | "subtle" | Solid ink primary, hairline ghost, or borderless subtle. One primary per view. | |
size | "default" | "sm" | "icon" | Icon buttons stay square at every breakpoint. Supply an accessible name. | |
grouped | boolean | Flush into a ButtonGroup: no own stroke, one ink seam. | |
serializePart | (part: ConversationExportPart, message: ConversationExportMessage) => string | ||
messagesrequired | readonly ConversationExportMessage[] | ||
filename | string | "conversation.md" | |
onError | (error: unknown) => void |
Also accepts ButtonHTMLAttributes<HTMLButtonElement>.
The ref reaches HTMLButtonElement.
serializeConversation (function)
Serializes explicit text, file and tool parts; unsupported application objects are never stringified as messages.
Keyboard
| Keys | Does |
|---|---|
| Tab | Moves through the supplied native controls in reading order |
| Enter, Space | Activates focused buttons and disclosure summaries |
Accessibility
- Native attributes, className, style, and the forwarded ref reach the outer element.
- Interactive content requires accessible names; progress text is not announced for every streamed token.
Markup
The same styles are available as CSS. Native HTML provides the static presentation; React or application code supplies state updates and actions.
npm install @noorddev/vlak
import "@noorddev/vlak/css";
<button class="rs-btn-subtle" type="button">Download conversation</button>