How I Moved From an Eleventy Static Site to Ghost

This is a very long post that will be interesting if you enjoy the meta commentary behind choosing blogging software.

How I Moved From an Eleventy Static Site to Ghost

I'm still in a bit of shock that it seems to have actually worked. For a bit of context, I've been picking away at trying to move my site for months. Every so often I'd get inspired to try to figure out how to move the 1,600+ blog posts I have on this site into a more portable format.

What I've Been Using to Power My Blog

For the last few years, I've had my personal site hosted at Netlify running on a static site generator called Eleventy. Prior to that I was on a self hosted WordPress blog. And way, way back I started my blog on MovableType—which apparently released a new update this year?

Static site generators use some form of flat files—Markdown in my case—which should make my site very portable and movable. Except for a half-nerd-dev like me. 99% of the tutorials are about moving to static site generators (SSG), or at best, from one SSG to another, because that's what the devs are doing. It's fairly rare for a power user dev to move back to WordPress or Ghost once they've got a custom coded solution that enables them to spend hours per week fiddling with instead of actually writing. (Sorry - snark only intended for the man in the mirror pretending to be a dev.)

Why I'm Moving Off Eleventy

To be clear: there's nothing wrong with Eleventy as a platform or host, if you're nerdy enough to be able to manage it. I know enough to be dangerous with it, not enough to relax using it. So any issues with Eleventy or static site generators in general are more of a me issue than the software.

I've been wanting to be able to post quickly and easily, and for my purposes, that means software with a nice user interface, no GitHub commits, and definitely not having to venture to the command line to update my blog if something breaks. And while I love how powerful CSS in laying out content on the web, I also only really know enough to be dangerous with it and don't want to have to figure out how to use CSS to lay out a gallery of images if I'm wanting that on a blog post.

In short: I wasn't blogging as much because the tools were getting in the way of me blogging.

Why Ghost?

I've used Ghost for a few clients who podcast, as well as kept an eye on it while I've been over in WordPress land for all these years. No CMS is perfect and it may be that the grass looks greener over here just because it's a fresh (to me) interface, but I do find that WordPress' UI has gotten so cluttered with stuff that it can get in the way of simply posting.

I also haven't been a fan of the benevolent dictator model of leadership that Matt Mullenweg, founding developer of WordPress, has been running Automattic with (the company behind / beside WordPress), combined with the company's creepy willingness to allegedly sell user data to AI farms made me want to explore other options.

It didn't hurt that John O'Nolan, Founder/CEO of Ghost, made it clear that they has no intention of selling user data to AI farms:

John O’Nolan (@johnonolan@mastodon.xyz)
@DavidDarnes@mastodon.design @ichris@mastodon.social @thibaultmol@en.osm.town @johnonolan *clears throat* We’ll never sell your stuff to AI

I've also watched Matt Haughey's move from WordPress to Ghost and appreciated his enjoyment of the platform:

Matt Haughey 🦣 (@mathowie@xoxo.zone)
@ichris@mastodon.social it’s mostly good. The posting UI is a bit too skewed towards email newsletters, I haven’t found a template I really love and I kind of get annoyed with their template system, but it’s still fun and breezy and easy to use and makes me write more, so a big win after a few weeks of use.

A Brief Side-Quest Into RSS

Why do so few blog CMS' offer the ability to import from an RSS feed? It works amazing when transferring your podcast to the best possible podcast host on the web, Transistor.fm. (Seriously if you host with another podcast host, you're missing out on the best possible podcast CMS experience. IMHO Ghost should buy or integrate directly with Transistor and become the mega uber of CMS platforms.)

An RSS feed from a blog has all the metadata you need to import blog posts (date, title, content, image URLs to scrape and import, embed codes, categories and / or tags even) and virtually every blogging platform has an RSS feed to pull from.

I'd argue that if you want your CMS to be the most popular in blogging town, importing via RSS should be option number one. Or maybe number two after WordPress since it's so ubiquitous.

But seriously. If a podcast host CMS can do it—and they all do—blogging CMS' should be able to as well.

How Did I Move 1,600+ Markdown Files Into Ghost?

tl;dr version:

  • I manually copied over the last 3 years of posts by simply viewing them on the web, highlighting all the text and images, and then pasting them into Ghost's editor. And that worked! Images and YouTube embeds included. The web is amazing!
  • I created a JSON file of all my Markdown posts using GitHub CoPilot to help me write the JavaScript? (I think that's what this code is?) But in the end didn't need to use the JSON file and instead used the feed.xml file generated by my Eleventy install.
  • I imported that into a temporary WordPress install.
  • I exported the WordPress XML file.
  • I converted that to Ghost's MobileDoc format in two chunks.
  • I imported those two zip files into Ghost.

I won't write it all out step by step since it's specific to my workflow. But if you stumble on this post in the future because you need to convert Markdown files into something Ghost will import, feel free to comment below and I'll do my best to explain in more detail.

Sources of Help in Trying to Convert My Blog Posts

WordPress Import and Export

I used Local to run a temporary copy of WordPress. I installed the free version of the WP All Import WordPress plugin to get the XML file of all my blog posts into WordPress. and then the built in WordPress XML export to generate a WordPress style version of the XML file which I knew Ghost could probably import since WordPress to Ghost is a much more common workflow than Eleventy to Ghost. 😄

Turns out, it's not quite that easy if you're not on Ghost's Creator (currently $25USD/month)

Ghost's Command-Line Tool in Matt's post:

Matt referenced the Ghost command-line tools which I hadn't stumbled across yet:

I contacted the support team at Ghost, and they gave me tips on how to DIY it myself using their command-line tools. After some configuration on my own Mac (I hadn't yet installed node or any dev tools so that took a bit), I got Ghost's XML Wordpress importer to work on my Wordpress export if I fed each XML file into it one at a time.

That was helpful, even though it seemed like it wasn't really working because the last thing I saw was an error message reading Error: ENOENT: no such file or directory and so I assumed it was broken, but it actually had created a MobileDoc file for me.

In order to not overload the Ghost migrate tool with all my posts, I broke up the posts into before and after a date like this:

migrate wp-xml --postsAfter "January 1 2018" --pathToFile farawaysoclose.WordPress.2024-04-08.xml

migrate wp-xml --postsBefore "January 1 2018" --pathToFile farawaysoclose.WordPress.2024-04-08.xml

January 1, 2018 and after January 1, 2018 was just a random point in time I picked not expecting it to work. Also learn from my mistake that the words --pathToFile in the Ghost command line tool need to stay there, they're not where you should put the path. 🤦‍♂️

Possible Issues

  • Images? The Ghost migrate tool seemed to pull down images, and the zip files it created definitely have images in them. But when I look through posts inside my Ghost blog, images aren't there as far as I can tell. I'm not losing any sleep at this point.
  • SEO? Ghost has redirect tooling built in, but I don't know if it's as good as WordPress in finding the right blog post even if the URL structure isn't 100% right in the link. So I might lose a bit of SEO juice in the transition process to Ghost. This isn't anywhere near my main source of income or client traffic so I'm not too worried. But it is something to be aware of if you're thinking of making the move.
  • Categories and tags? None of the categories or tags I'd used got moved over. I'm sure I could've done it somehow? I love metadata so I'm sad that they didn't. But I'll also take the opportunity to slowly retag old posts and build out the nifty tag pages Ghost builds, like this Apple one for example.
  • Newsletter? I have been using Buttondown to send out an email newsletter. Ghost has this ability built in... sort of? Every blog post potentially becomes an email newsletter. I think you can tag certain posts to be included and not others? Or something? For now I'll hold off moving my 20's 😏 of subscribers over and think about how to do it in a sustainable way.
  • Mobile publishing? WordPress has come a long way in developing a mobile app that works really well on the go. While I can log in to the editor in Ghost in Safari on my iPhone, it's not quite the same as a dedicated app imho. But not a deal breaker for me.

I guess if you're reading this on my actual domain, chrisenns.com, then it all worked. I'm going to go flip the DNS switch shortly and see what happens!