Blog
Portfolio Devlog/3 minutes read

I Left microCMS And Migrated To EmDash

A record of wanting to leave microCMS and rebuilding my portfolio with Astro and EmDash.

I’ve migrated the blog section of this website from microCMS to EmDash, so I’m just going to write whatever comes to mind. This is probably the most off-the-cuff post on this site.

Originally, the setup was Next.js + microCMS, but I felt a bit uneasy about not having the data on my own server, so I started wondering if there was a CMS that would let me manage the data myself.

So I thought about it for a bit, and—bingo! Come to think of it, Cloudflare—which I absolutely love—had released something. That something is EmDash. It’s Astro-based, has an admin panel, comes with a built-in MCP, and apparently bills itself as the successor to WordPress. And of course, it integrates seamlessly with the Cloudflare ecosystem.

So I figured, “Why not give it a try?”

Astro←❓️

One concern I had about using EmDash was Astro. I’d never worked with Astro before. I heard you have to explicitly declare JavaScript??? I didn’t want to redo the parts of the site other than the blog section—I’d put a lot of effort into them—and I was worried I wouldn’t be able to recreate the design if I did.

So, I decided to set it up as a monorepo for now and split the portfolio and EmDash into separate projects. The plan was to manage articles in EmDash and have the portfolio call its API.

After finishing, I started thinking, “Wouldn’t it be better to build the portfolio with Astro too?” Mono-repos are a hassle. Since I was using EmDash anyway, I figured it would be more fun to try out Astro—which I’d never used before—rather than keeping Next.js.

After doing a little research, I was happy to find that there was a React integration. It didn’t look like I’d have to throw away all my existing components.

So I started the process of removing Next.js and migrating to Astro.

Well

Of course, it didn’t work on the first try.

First, I got an error with a React hook: “Invalid hook call”—what???

Apparently, when running React components on Astro, simply loading them as usual doesn’t match the React runtime environment. In the end, I set it up to run as a React island by explicitly specifying client:only=“react”. This might be a deprecated implementation, but since I’m new to Astro, I figured it’d be fine. Let me know if this isn’t the best approach.

Next up was fetching data from EmDash. Since I decided to manage both EmDash and my portfolio within the same app, I switched to directly using EmDash’s collection fetching feature as planned.

The next thing I got stuck on was images.

I had included the image ID in the content, so when I sent a request using that, I got a 404 error for the image.

It turns out the API actually accepts meta.storageKey.

/_emdash/api/media/file/{id} returns a 404; apparently, the correct URL is

/_emdash/api/media/file/{storageKey}. Baffling.

It’s my fault for giving the Codex arbitrary instructions without reading the docs.

Result

In the end, the setup became much cleaner.

Next.js is gone, and my portfolio is now entirely built with Astro. For the blog, I’m using EmDash’s native setup, so I can edit directly from the page—it feels a lot like WordPress. I’m satisfied.

There might still be some fine-tuning needed, but it’s up and running for now, so I’m super excited.


Translated with DeepL.com (free version)