ULTRV

Importing Markdown files in bulk

A zip of .md files, whatever wrote them.

The bulk Markdown connector is the escape hatch for everything the other four do not cover: static site generators, note-taking apps, and the small platforms that have no importer of their own. It takes a zip of.md or.markdown files, reads YAML front matter where it finds it, and falls back to filenames where it does not.

It is also the connector with the sharpest edges, so this page spends more time than the others on what to fix before you upload.

Getting Markdown out of where it lives

  • Hugo, Jekyll, Eleventy, Astro, Zola. You already have the files. Zip the content directory — content/posts, _posts, src/content/blog — and upload that.
  • Obsidian. Zip the vault, or the folder inside it that holds the posts. Wiki-style [[links]] are not Markdown links and will import as literal text, so convert them first if they matter.
  • Mataroa. Its export page offers all blog posts as .md files in a zip. That archive uploads as-is.
  • Micro.blog. Export as a folder of Markdown files rather than the Blog Archive Format, then zip it. (Checked August 2026.)
  • Bear Blog. There is no folder of Markdown files to download — Bear Blog's export is a CSV. Either convert it into one .md file per post yourself, or paste posts into the editor one at a time. The Bear Blog comparison is upfront that this migration is manual.

Fix these before you zip

Two things are worth ten minutes of find-and-replace, because they are much harder to repair afterwards.

Image paths. ULTRV downloads and re-hosts any image referenced by a full http orhttps URL. A relative path like/images/lichen.png is left exactly as written and will point at nothing. If your old site is still up, rewrite image links to its absolute URLs before zipping and every picture comes across in one pass.

Markdown extensions. ULTRV converts your files with standard CommonMark plus front matter, and nothing else. Tables, footnotes, strikethrough, task lists, and bare-URL autolinking are not part of that standard, so they arrive as the literal characters you typed. Headings, paragraphs, lists, links, images, blockquotes, code fences, and emphasis all convert correctly.

Uploading

Open your blog's Settings → Import and choose the Bulk Markdown tab, last in the row. This connector has one control the others do not:Import as, which decides whether the whole archive lands as Posts or asPages. It applies to every file in the zip, so if you have both, import the posts first and the pages in a second upload. Uploads are capped at 50 MB, which is a great deal of prose.

What ULTRV reads from each file

Front matter, where it exists:

  • title and slug
  • excerpt, or description, or summary
  • date, or pubDate, or published, or publishedAt
  • draft, author, and tags or categories
  • cover, or cover_image, or image, used as the featured image

And the filename, where front matter is missing:

  • A Jekyll-style 2024-03-11-on-lichen.md gives both the publication date and the slug on-lichen.
  • Any other name becomes the slug, and a title is derived from it if the file has none.
  • Anything in a _drafts/ folder, or carrying draft: true, arrives as a draft with no date.
  • Slug collisions are resolved by appending a number, so two files never overwrite each other.

The one thing this connector cannot do

It cannot recognise its own work. The other four importers stamp each item with an id from the source platform, which is what makes a second run safe. Markdown files have no such id, so theIf a post was already imported setting has nothing to match on: importing the same zip twice gives you two copies of every post, the second set with numbers appended to their slugs.

The fix is the rollback in the import history. Roll the batch back — it removes the posts, pages, images, and tags that import created — correct the zip, and upload it again. Get into that habit early and a Markdown migration becomes iterative rather than nerve-racking.

After the import

  1. Open a post with images and check they resolved. If they did not, they were relative paths; roll back, rewrite them, re-import.
  2. Look for stray front-matter keys rendered as text at the top of a post — a sign the delimiters were malformed in that file.
  3. Check the drafts, and the dates on anything without a date prefix.
  4. Pick a theme and set up feeds. If you came from a static site generator, this is the part you no longer have to build.

If you would rather keep writing in Markdown files locally, you can: the terminal client publishes from the shell, and the REST API underneath it will take posts from whatever script you already have. Bulk Markdown moves the archive across once; those two are how you keep working afterwards.

Your old URLs

ULTRV serves posts at /slug, with no date segment and no section prefix. A Hugo site at/posts/on-lichen/ or a Jekyll site at/2024/03/11/on-lichen.html will not match, and ULTRV does not serve redirects for the old paths. Since you control the old site, set the redirects there before youmove the domain — it is a one-line rule in most hosting configurations, and it is the difference between a migration nobody notices and a pile of dead links.

Frequently asked questions

Which folders work with the bulk Markdown importer?

A zip of .md or .markdown files, in any folder layout. Hugo content directories, Jekyll _posts folders, an Astro content collection, and an Obsidian vault all work as they are. Files that are not Markdown are ignored, hidden files are skipped, and nested folders are fine — ULTRV walks the whole archive.

What front matter does ULTRV read?

Title, slug, excerpt (or description, or summary), date (or pubDate, published, publishedAt), draft, author, cover (or cover_image, or image), and tags (or categories). Anything else is ignored rather than rejected. Files with no front matter still import: the filename becomes the slug, and a Jekyll-style date prefix becomes the publication date.

Why did my images break after a Markdown import?

Because they were relative paths. ULTRV fetches and re-hosts images referenced by a full http or https URL; a link like /images/lichen.png points at a folder that does not exist on ULTRV and is left exactly as written. Rewrite image links to absolute URLs on your old site before zipping, and the importer will pull them across.

Can I re-run a Markdown import the way I can with WordPress?

No. Markdown files carry no id from a source platform, so ULTRV cannot tell a re-import from a new post — a second run creates a second copy of everything, with -2 appended to the slugs. Roll the batch back from the import history first, then import the corrected zip.

Start your blog →

Free, no credit card. Try a zip of ten posts first, look at the result, roll it back, then do the whole archive.