Skip to content

feat(app): add PNG export — copy to clipboard and save to Downloads#53

Open
breadoncee wants to merge 2 commits intoexcalidraw:mainfrom
breadoncee:feat/export-png
Open

feat(app): add PNG export — copy to clipboard and save to Downloads#53
breadoncee wants to merge 2 commits intoexcalidraw:mainfrom
breadoncee:feat/export-png

Conversation

@breadoncee
Copy link
Copy Markdown

@breadoncee breadoncee commented Mar 21, 2026

excalidraw_export_png.mp4

Summary

  • Adds Copy PNG button that exports the diagram as a PNG blob and copies it to the clipboard via the Clipboard API
  • Adds Download PNG button that uploads the PNG to a server-side store (PngStore) and returns a download URL, with button state feedback (idle → saving → saved with path)
  • New PngStore abstraction with memory and Redis (Upstash KV) implementations, 5-minute TTL, and MAX_PNG_BYTES size guard
  • Vercel download endpoint (api/download/[id].ts) serves stored PNGs with proper Content-Disposition headers

Test plan

  • Create a diagram, click Copy PNG — paste into another app and verify image content
  • Click Download PNG — verify file appears in Downloads with correct diagram content
  • Verify button states transition: idle → saving → saved (with file path shown)
  • Test in fullscreen mode — both buttons should remain functional
  • Test with a large diagram to verify MAX_PNG_BYTES limit is enforced
  • Test immediately after streaming completes to verify no race with final render

Closes #31

…xcalidraw#31)

- Copy PNG: clipboard copy via navigator.clipboard.write (pure client-side)
- Save PNG: upload_png server tool saves to ~/Downloads (stdio) or serves
  via /download/:id endpoint (HTTP/Vercel)
- PNG store with memory (local) and Redis (Vercel) backends, 5-min TTL
- Buttons in both inline and fullscreen toolbars with state feedback
- Make PngStore interface fully async — await Redis save before returning
  download URL, fixing Vercel serverless freeze issue
- Remove instanceof/loadAsync abstraction leak in download endpoint
- Bump MAX_PNG_BYTES from 2MB to 4MB (under Vercel's 4.5MB limit)
- Fix Safari clipboard: pass blob promise to ClipboardItem to retain
  user-activation context
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 21, 2026

@breadoncee is attempting to deploy a commit to the Excalidraw Team on Vercel.

A member of the Team first needs to authorize it.

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.

export as png

1 participant