Topics

Migrated from microCMS to EmDash + Cloudflare

  • column

What is EmDash?

EmDash is a CMS announced by Cloudflare, positioned as the spiritual successor to WordPress.
It is a full-stack CMS built on a modern architecture combining Cloudflare's resources (D1, R2, Workers) with Astro, making it truly an Cloudflare-ecosystem CMS!
As an experiment, I migrated a blog I had built with microCMS over to EmDash.

The migrated site is here → Yuru-log
Since this is an experimental site, it still uses the default theme. We will apply a design later.

Setup Steps

1. Create a project

Run npm create emdash@latest. It asks a series of interactive questions, so make your selections as you go.

2. Create Cloudflare resources

Set up databases and storage this way, and deployment is easy 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 the local environment.
Access the admin panel at http://localhost:4321/_emdash/admin to complete setup.

4. Deployment and initial setup

Run npx wrangler deploy to deploy to Workers, and the site will be published at https://[name].workers.dev.
Because the local and remote databases are independent, you will also need to complete the initial setup (creating an admin account) in the remote admin panel.

If you connect a GitHub repository, automatic deployment on push is also possible (Cloudflare Dashboard → Workers → Settings → Build → Connect Git repository).

5. Migrating articles from microCMS

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

Key points

  • Converted the microCMS rich editor content (HTML) to Markdown before importing.
  • Images were first migrated as external URL references, then later uploaded to R2 and the references were replaced.
  • Use npx emdash content create instead of npx emdash seed (seed does not create revisions, so the article won't appear).

From actual use:

It's a good-of-both-worlds CMS, combining the easy setup-to-implementation experience of a headless CMS with the convenience of end-to-end control found in full-stack CMSs.
Most notably, since it's based on Astro, you can carry over your existing know-how as is. It seems well suited to small to mid-sized blogs.
However, because the Astro Cloudflare adapter does not yet support the Cache API, pages are generated from D1 on every request, which makes it slow. I'd either wait for support or need to implement custom caching.

Since it's still in beta,

  • draft preview does not work by default (see below)
  • Center and right alignment are not reflected in WYSIWYG editing
  • Relative paths cause errors when editing Menus items
  • Custom fields cannot be reordered
  • Users cannot be invited

There are also a few points that caught my attention, such as (as of v0.1.0).

It looks like it will still be a while before we can use it in actual client projects.

About Draft Preview

The editor screen has a "Preview draft" button, but I was unable to preview articles in draft status.

EmDash has a built-in preview mechanism, but it doesn't seem to be enabled by default, so the following steps were required.

  1. Set any secret key in the environment variable PREVIEW_SECRET (you can generate one with npx emdash auth secret)
  2. Update the article page to fetch drafts using verifyPreviewToken
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 screen.

Summary

This time I implemented it as a full-stack app as usual, but it also seems possible to use it in a more "headless CMS" style, where articles are fetched and built with SSG, so I plan to try that out next time.

It's a beta that has just been released. I'm really looking forward to how it evolves!

About the author

Starting out in DTP and moving into the web, he now handles markup, frontend, direction, and accessibility alike. A "master of all trades" who has been versatile since Liberogic's early days and is now a walking encyclopedia of the company. Lately he has been hooked on exploring efficiency through prompts, asking, "Can't we rely more on AI for accessibility work?" Both his skills and his thinking are still evolving.

Ayumu Futamata

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

View this staff member's articles

Reliable team structure and responsive support are our strengths

Liberogic's experienced staff actively drive projects forward, which has earned high praise from our clients.
We make sure to properly assign project managers and directors to keep the entire project running smoothly. Our style of allocating resources to the right people, rather than adding full-time commitment unnecessarily, helps prevent cost increases. We are also known for our speed, from understanding the scope of work to preparing and submitting estimates.

Note: Please be advised that we do not actively engage in SES-style on-site staffing assignments.

We support nearly all major project management and chat tools, including Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom, and Webex.

Are you struggling with technical challenges or how to approach large-scale projects that involve SES or offshore teams?

Case Studies