← All case studies WordPress → Astro

Michaël Hompus mirrored 15 years of WordPress before converting it to Astro

He kept a wget copy of the live site, exported Markdown with Jekyll Exporter, and rebuilt the blog as static Astro on Azure's free tier. The exporter needed cleanup, and plugin features had to be rewritten.

Michaël Hompus ran his blog on WordPress for 15 years. In January 2025 he wrote up the content move to Astro. This is his own series, not a vendor page.

The week before, he listed the reasons: the WordPress community fight, the 24/7 VM, and the Azure bill. The new site is a static Astro app on Azure Static Web Apps.

If you are looking at the same route, start with the WordPress → Astro playbook. Michaël’s posts are the field report. The playbook is the WXR-and-backup path.

Why he left

He liked the WordPress editor. He did not like keeping a virtual machine up 24/7 for a blog he did not update every week.

He first thought about generating static pages on publish, then shutting the VM down. Colleagues at Info Support had rebuilt their Knowledge Center with Astro. That is when he decided to rethink the whole blog.

The WordPress community fight pushed him over the edge. Automatic plugin updates used to feel convenient. Then The Register covered WordPress.org forking WP Engine’s ACF plugin and shipping the fork through auto-updates. A few days before his post, The Register reported that Matt Mullenweg deactivated five WordPress.org accounts, including Joost de Valk’s. Michaël had met Joost at Yoast events and had spoken at WordCamp Nijmegen in 2018. He no longer wanted production code that could change without him.

Astro can keep WordPress as a headless CMS through the REST API. He looked at that and skipped it, because that still needs a running WordPress backend. He wanted Markdown files.

How he moved it

He followed Greg Slepak’s okTurtles conversion guide and cloned okTurtles/wordpress-to-astro.

First he mirrored the live site with wget. Media lived on a second host, so he allowed both domains:

wget -m -k -p -E https://blog.hompus.nl -D static.hompus.nl,blog.hompus.nl -H

GNU wget’s man page matches those flags. -m is a recursive mirror. -k rewrites links for local viewing. -p grabs page assets. -E fixes extensions. -H follows other hosts, and -D limits which hosts that is.

He says the mirror was not perfect. It still gave him a local copy he could compare against. The okTurtles guide wants that copy for two jobs: a fallback if the conversion goes wrong, and the HTML and CSS you need if you want the new site to look like the old one.

Comments had been off for a long time. He skipped that export.

Posts went through the Jekyll Exporter plugin, now listed as Static Site Exporter. It writes Markdown plus YAML front matter into a zip. He says the output was not perfect. It was enough to import.

He cloned wordpress-to-astro so he had a working Astro app with those posts loaded. The template wants Markdown in src/posts/ and the mirrored wp-content folder under public/. It also keeps WordPress permalinks from the permalink front matter, plus author, category, and tag routes. He did not publish a URL-by-URL check. Astro file routes are how you keep those paths if you build the mapping yourself.

Then he rebuilt the layouts, styles, and structure. He kept the look of the old blog. The old markup was valid XHTML 1.1. He moved to HTML5 and CSS3 and used that pass to improve accessibility.

The playbook starts from WordPress’s Tools → Export WXR file plus a database and file backup. Michaël used wget plus Jekyll Exporter. I would still take the WXR and the database dump. A wget tree is HTML as rendered, so it is not a restore of WordPress.

What he gained

The WordPress Azure bill was €28.91 a month for a Standard B2ls v2 VM and €11.21 a month for storage and networking. That is €481.44 a year. WP Rocket was about €59 a year for minify, gzip, and cache.

The new site runs on Azure Static Web Apps Free. Microsoft’s pricing page includes hosting, an SSL certificate, and a custom domain on that plan. Free has no SLA. A site that goes over 100 GB of bandwidth in a month stops serving. He was hosting a personal blog, so those limits were acceptable.

He dropped WP Rocket. Azure Static Web Apps compresses HTML, CSS, and JS with gzip or Brotli when the client asks. Astro minifies CSS in production.

He reported a Google Lighthouse score of 4 × 100, as long as he skips YouTube embeds. That is his measurement. I did not re-run it.

He also estimated the old VM at 50 W, 438 kWh a year, and 208.05 kg of CO₂ using 0.475 kg CO₂/kWh as a Dutch average. Those are his numbers, not a metered reading. The shape is still useful: a 24/7 VM plus storage, network, and backups, versus compute only when he builds.

Editing moved to Visual Studio Code. npx astro dev runs the blog on his laptop. The source is on GitHub.

What broke or got rewritten

Plugin features did not travel. He rebuilt them in later posts.

Acronyms 2, Add Meta Tags, and Better Tag Cloud became a rehype plugin, a BaseHead.astro layout, and a tag cloud in the sidebar from content collections.

Enlighter, Recent Post Widget Extended, and WP External Links became Expressive Code, a recent-posts loop, and rehype-external-links.

On 10 February 2025 he said a later post would cover paging and related posts. The series page still ends at those four posts. I did not find the follow-up.

The WordPress theme is a loss the playbook already names. He kept the visual character and rewrote the stack.

He does not describe a broken URL, a missing image, or a rollback. The gaps he names are the imperfect wget, the imperfect Markdown export, and the plugin work.

Astro’s own WordPress migration page says the same thing in generic form. You edit in a code editor. Plugin and theme markets do not come along. You rebuild the features you still want.

What I would copy

Mirror the live site before you convert anything. Keep wget output as a comparison copy, not as the only backup. Then take a WXR, a database dump, and wp-content/uploads.

If media sits on another hostname, add that host to wget the way he did with static.hompus.nl. Otherwise the Markdown will still point at a CDN you plan to shut down.

Treat Jekyll Exporter as a starting zip. Budget time to clean Markdown and to rebuild plugins, which is most of the work he wrote about after the import.

Skip headless WordPress if the point of the move is turning the PHP server off.

Run the WordPress → Astro playbook. Use Michaël’s posts for the wget plus exporter path. The reverse route is Astro → WordPress if you need a way back.