A community-driven registry for Claude, Cursor, Windsurf, Cline & more. Not affiliated with Anthropic.
Are you the author? Sign in to claim
Claude Chat Exporter is a JavaScript tool that allows you to export your conversations with Claude AI into a well-format
A JavaScript tool that exports Claude.ai conversations with perfect markdown fidelity by leveraging Claude's native copy functionality. Get complete conversations with both human and AI messages including tables, complex formatting, and all elements that Claude supports.
navigator.clipboard.writeTextInstead of manually parsing HTML and converting to markdown (which misses tables and complex elements), this tool uses Claude's own copy button to ensure 100% accurate markdown output for all message types.
❌ Manual HTML Parsing:
- Misses tables and complex elements
- Requires constant updates for new features
- Error-prone formatting conversion
- Maintenance nightmare
✅ Copy Button Method:
- Perfect markdown fidelity
- Automatic support for ALL elements
- Future-proof against new features
- Zero formatting edge cases
claude-chat-exporter.js and paste it into the console.{conversation-title}.md (auto-generated with conversation-title being the Claude conversation title).Because this uses Claude's copy function, it automatically handles:
{conversation-title}.md (from API, falls back to DOM)The output is identical to what you get when copying Claude messages manually, with timestamps added to human message headers:
# Conversation with Claude
## Human (Feb 23, 2026, 10:30 AM):
Can you create a comparison table of sorting algorithms?
---
## Claude:
Here's a comprehensive comparison table of sorting algorithms:
| Algorithm | Best Case | Average Case | Worst Case | Space | Stable |
| ----------- | ---------- | ------------ | ---------- | -------- | ------ |
| Bubble Sort | O(n) | O(n²) | O(n²) | O(1) | Yes |
| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(log n) | No |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes |
**Key advantages:**
- Tables render perfectly ✅
- Math notation preserved ✅
- All formatting maintained ✅
---
Adjust the delay between copy button clicks in the DELAYS object:
const DELAYS = {
copy: 100, // Delay between copy button clicks in ms (increase if messages are missed)
};
Increasing copy can help on slower machines or when the page is under load. Decreasing it speeds up export but may cause clipboard writes to be missed.
If Claude's interface changes, update the SELECTORS object:
const SELECTORS = {
copyButton: 'button[data-testid="action-bar-copy"]',
conversationTitle: '[data-testid="chat-title-button"] .truncate, button[data-testid="chat-title-button"] div.truncate',
messageActionsGroup: '[role="group"][aria-label="Message actions"]',
feedbackButton: 'button[aria-label="Give positive feedback"]'
};
The feedbackButton selector is what distinguishes Claude's action bars from human message action bars — it only appears on Claude's responses.
Requires clipboard API support (available in all modern browsers)
The script shows real-time progress:
Fetching conversation data... - Retrieving title and timestamps from APICopying human messages... - Clicking human message copy buttonsCopying Claude responses... - Clicking Claude response copy buttonsHuman: X | Claude: Y - Live capture counts✅ Downloaded: filename.md - Success!No Messages Captured
Partial Export
Human and Claude message action bars are structurally identical except that Claude's bars include a thumbs-up feedback button. getCopyButtons uses this to filter:
function getCopyButtons(claudeOnly) {
const actionGroups = document.querySelectorAll(SELECTORS.messageActionsGroup);
const buttons = [];
actionGroups.forEach(group => {
const hasFeedback = !!group.querySelector(SELECTORS.feedbackButton);
if (hasFeedback === claudeOnly) {
const copyBtn = group.querySelector(SELECTORS.copyButton);
if (copyBtn) buttons.push(copyBtn);
}
});
return buttons;
}
startExport then runs two sequential phases, switching currentCapture between humanMessages and capturedResponses so the clipboard interceptor routes each write to the right array:
// Phase 1: Human messages
currentCapture = humanMessages;
await triggerCopyButtons(humanButtons);
await waitForClipboardOperations(humanMessages, humanButtons.length);
// Phase 2: Claude responses
currentCapture = capturedResponses;
await triggerCopyButtons(claudeButtons);
await waitForClipboardOperations(capturedResponses, claudeButtons.length);
navigator.clipboard.writeText = function(text) {
if (interceptorActive && text) {
const type = currentCapture === humanMessages ? 'user' : 'claude';
currentCapture.push({ type, content: text });
}
};
Timestamps are fetched from Claude's internal API and stored in a Map<content → timestamp>. Matching by content (rather than by index) ensures correctness even when the API returns hidden or system messages alongside visible ones:
const ts = timestamps?.get(humanMessages[i].content?.trim());
const header = ts ? `## Human (${ts}):` : `## Human:`;
| Method | Accuracy | Speed | Maintenance | Future-Proof |
|---|---|---|---|---|
| This Script | 100% | Fast | Low | Yes |
| Manual Copy/Paste | 100% | Very Slow | N/A | Yes |
| HTML Parsing Scripts | ~80% | Fast | High | No |
Contributions to improve the script or add new features are welcome! Please feel free to submit a pull request or open an issue to discuss potential changes.
This project benefits from:
This project is open source and available under the MIT License.
This script is not officially associated with Anthropic or Claude AI. It is a community-created tool to enhance the user experience. Use it responsibly and in accordance with Anthropic's terms of service.
Perfect Exports. Every Element. Every Time.
Made for the Claude community - if this helps you, give it a ⭐!
干净、强大、属于你的 AI Agent 平台 --AI agents, without the clutter.
Pocket Flow: Codebase to Tutorial
A Comprehensive Benchmark to Evaluate LLMs as Agents (ICLR'24)
Native macOS app to monitor Claude AI usage limits and watch your coding sessions live