Medium export ZIP to VeloCMS — full walkthrough
Medium's export gives you HTML files for every story you've written. The VeloCMS migration CLI converts them to the block AST format and re-uploads your images to R2 in one pass.
Medium's export is a ZIP file containing one HTML file per story you've published. Unlike Substack (which gives you a structured CSV for subscribers), Medium has no subscriber export — you're migrating content only. The HTML files include all your stories, drafts, and responses, with embedded images pointing to Medium's CDN.
Step 1 — Download your Medium export
Go to medium.com, click your avatar, Settings, Security and apps, Download your information. Medium emails you a download link within 24 hours (usually much faster). The ZIP contains a posts/ directory with one HTML file per story. Extract the ZIP locally.
Step 2 — Convert Medium HTML to VeloCMS format
velocms-migrate medium-to-json \
--input ./medium-export/posts/ \
--output posts.json \
--download-imagesThe --download-images flag instructs the converter to fetch each image from Medium's CDN and upload it to your VeloCMS R2 bucket. Without this flag, images remain pointing to Medium's CDN — they'll work initially but break if Medium removes them. The conversion takes about 5 seconds per story.
Medium's export includes draft stories and responses (comments on other people's posts). The converter marks drafts as draft status and skips responses by default. Pass --include-responses to import responses as posts if you want them.
What the converter handles automatically
Medium uses a custom HTML structure with specific class names and data attributes. The converter handles: kicker text (the little label above the title), subtitle (maps to the excerpt field), pull quotes (converted to callout blocks), gists (converted to code blocks with the gist content fetched from GitHub's API), and native Medium images with captions (converted to image blocks with the caption text preserved).
Step 3 — Import and set up canonical URLs
Import the posts.json in Admin Tools Import. After import, consider setting canonical URLs on your VeloCMS posts pointing back to the original Medium URLs. This tells Google that your new blog is the definitive source and Medium is a syndication, which transfers ranking authority to your domain over time. In the VeloCMS post editor, the SEO panel has a Canonical URL field — set it to the original medium.com/post-slug URL during the transition period, then remove it once your new domain has established enough authority.