Topics

Migrating from microCMS to EmDash + Cloudflare

  • column

What is EmDash

A CMS announced by Cloudflare as the spiritual successor to WordPress.
It's a full-stack CMS with a modern architecture using Cloudflare resources (D1/R2/Workers) + Astro—truly the Cloudflare ecosystem CMS!
As an experiment, I migrated a blog previously built with microCMS to EmDash.

The migrated siteYuru Log
For now it's still using the default theme since it's an experimental site. I'll apply custom styling later.

Setup workflow

1. Create a project

Run npm create emdash@latest. The interactive prompt will ask you questions—just select your preferences.

2. Create Cloudflare resources

You can easily set up databases and storage like this, and deployment is simple too.

npx wrangler login
npx wrangler d1 create my-site
npx wrangler r2 bucket create my-site-media
npm run build && npm run deploy

3. Local development

Run npx emdash dev to start your local environment. Access the admin panel at
http://localhost:4321/_emdash/admin to complete setup.

4. Deployment and Initial Configuration

Deploy to Workers with npx wrangler deploy, and your site will be live at https://[name].workers.dev.
Since the local and remote databases are separate, you'll need to complete the initial setup (create an admin account) on the remote admin panel as well.

By connecting your GitHub repository, you can enable automatic deployment on push (Cloudflare dashboard → Workers → Settings → Build → Connect to Git repository).

5. Migrating Content from microCMS

We created a migration script to fetch all articles from the microCMS API, then imported them using the EmDash CLI content create command.

Key Points

  • Convert microCMS rich editor content (HTML) to Markdown during migration
  • Initially migrate images with external URLs, then upload them to R2 and update references
  • Use npx emdash content create instead of npx emdash seed (seed doesn't create revisions, so articles won't display)

Trying it out for real

It's a best-of-both-worlds CMS that combines the ease of setup and implementation you get with a headless CMS and the convenience of controlling everything end-to-end that you get with a full-stack CMS.
What I really liked is that it's Astro-based, so you can leverage your existing knowledge as-is. It seemed like a good fit for small to medium-sized blogs.
However, since the Astro Cloudflare adapter doesn't support the Cache API yet, pages are being generated from D1 on every request, so the speed is slower than I'd like. We'll either need to wait for support or implement custom caching.

Since it's still in beta,

  • Draft preview doesn't work by default (more on this below)
  • Center and right alignment aren't reflected in the WYSIWYG editor
  • Relative paths cause errors when editing items in Menus
  • Custom fields can't be reordered
  • Users can't be invited

and a few other quirks (as of v0.1.0).

Real-world project adoption still seems like it's a ways off.

About draft preview

The edit screen has a "Preview draft" button, but it's not possible to preview articles in draft status.

EmDash has a preview mechanism built in, but it appears to be disabled by default, requiring the following steps.

  1. Set an arbitrary secret key in the environment variable PREVIEW_SECRET (can be generated with npx emdash auth secret)
  2. Use verifyPreviewToken on the article page to retrieve drafts
import { getEmDashEntry, verifyPreviewToken } from "emdash";

const preview = await verifyPreviewToken({
  url: Astro.url,
  secret: import.meta.env.PREVIEW_SECRET,
});

const { entry, isPreview } = await getEmDashEntry("posts", slug, { preview });

With this, you can now view draft articles from the "Preview draft" button in the admin panel.

Summary

This time I implemented it as a full-stack setup following the standard approach, but it looks like a headless CMS-style workflow is also possible where you fetch articles and build them with SSG, so I'd like to try that approach next.

Still in beta, just released. I'm really excited to see how it evolves!

About the author of this article

A "master of technique" who jumped from DTP into the web world and, before he knew it, mastered markup, frontend, direction, and accessibility. Active across multiple domains since Liberogic's early days, he's now a walking encyclopedia within the company. Recently, he's been diving deep into prompt-driven efficiency optimization, wondering "Can we rely more on AI for accessibility compliance?" Both his technology and thinking continue to evolve.

Futa

IAAP Certified Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director

Read this staff member's article

Reliable team structure and responsive project management are our strengths

At Liberogic, our experienced staff actively drive projects forward, earning high praise from clients.
We carefully assign project managers and directors to ensure smooth project execution across all phases. We prevent unnecessary cost increases from over-commitment by deploying resources strategically, and we're known for speed in project understanding, estimation, and delivery.

* Please note that we do not actively pursue on-site SES-style staffing arrangements.

You can use virtually all major project management and chat tools, including Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom, Webex, and more.

For large-scale projects involving SES or offshore resources, do you have concerns or questions about technical challenges and approaches?

Case Studies