Skip to content

feat: add download as markdown button to bookmark cards#61

Open
davidorban wants to merge 1 commit intoviperrcrypto:mainfrom
davidorban:feat/download-as-markdown
Open

feat: add download as markdown button to bookmark cards#61
davidorban wants to merge 1 commit intoviperrcrypto:mainfrom
davidorban:feat/download-as-markdown

Conversation

@davidorban
Copy link
Copy Markdown
Contributor

Summary

Adds a FileText button (visible on hover, left of the existing media download button) that exports any bookmark as a .md file with a single click.

What's exported

# Tweet by @handle

**Author:** Name (@handle)
**Date:** Mar 15, 2026
**URL:** https://twitter.com/handle/status/...
**Categories:** AI & Machine Learning, Dev Tools

---

Full tweet text here (URLs preserved so truncated threads
show their continuation link)

> *This tweet may be part of a longer thread. [Read on X ↗](...)*

---

![Image](https://pbs.twimg.com/media/...)

Design decisions

  • Entirely client-side — no new API routes, no new dependencies, no backend changes
  • URLs preserved — unlike the card display which strips t.co links, the export keeps them so truncated threads include the continuation link
  • Thread hint — when the text ends with a t.co URL (sign of a truncated thread), a blockquote note is appended with a direct link to X
  • Photo media embedded as ![Image](url) for inline display in any Markdown viewer; videos/GIFs become links back to the tweet
  • Named tweet-{tweetId}.md for easy identification

Changes

  • components/bookmark-card.tsx — adds FileText import, handleDownloadMarkdown() function, and the hover button (1 file, +62 lines)

Checklist

  • Tested locally
  • npx tsc --noEmit passes
  • No new warnings
  • No new dependencies
  • No new API routes or backend changes

Adds a FileText button (visible on hover, left of the existing media download
button) that exports a bookmark as a Markdown file.

The exported file contains:
- Author, date, tweet URL, and categories as a header
- Full stored tweet text (with URLs preserved, so truncated threads still
  show their t.co continuation link)
- A note when the text appears to be a truncated thread (ends with t.co URL)
- Embedded image links for photo media; video/GIF as linked references

The download is entirely client-side — no new API routes, no new dependencies.
The file is named tweet-{tweetId}.md.

Co-Authored-By: Oz <oz-agent@warp.dev>
Copy link
Copy Markdown

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: Download as Markdown Button

Overall: Clean, focused feature addition. The markdown generation logic is straightforward and handles the common cases well (photos, videos, thread detection via t.co links).

What looks good

  • Good use of FileText icon to distinguish from media download
  • Markdown structure includes author, date, categories, and media
  • Thread detection via TCO_REGEX is a nice UX touch
  • Proper cleanup of object URL after download

Issues to consider

1. Sanitization of bookmark content (security)
The markdown content is generated from user data without escaping. If these fields contain markdown syntax characters, the output may render unexpectedly. Consider escaping markdown metacharacters or documenting that this is as-is export.

2. Filename collision risk
tweet-${bookmark.tweetId}.md could collide if multiple bookmarks reference the same tweet. Consider adding a timestamp or counter.

3. No tests
A simple test verifying the download flow and markdown structure would prevent regression.

Minor suggestions

  • The handleDownload function could be extracted to a utility for easier testing
  • Consider adding charset to the blob type: text/markdown;charset=utf-8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants