All articles
Copilot

Ditching WordPress: Migrating My Blog to Azure Static Web Apps & Azure DNS

When you see so many people revert back to the old days of hosting their own blog, you eventually ask yourself: do I really need a full backend database and an admin dashboard just to display text and images? For me, the answer was a clear no. I wanted a fast webpage, lower hosting costs, and a little throwback to the original start of what got me interested in tech in secondary school: good, old, trusty HTML.

Here is how I migrated my blog off WordPress at Strato to an Azure Static Web App (SWA) with Azure DNS, using GitHub Copilot to build both the migration engine and a custom editorial publishing skill. With a bit of understanding of how these services and pages work, you can do this too! Took a weekend of chatting to GitHub Copilot and looking things up, but it worked.

1. Defining the Scope: Less Overhead, Same Content

The goal wasn't to rebuild WordPress; it was to keep what actually mattered and drop everything else. That meant keeping all articles, navigation, category indexing, search, RSS, and sitemap intact while eliminating database calls, runtime security vulnerabilities, and database (no, not all webspace hosts update those for you).

2. Building the Migration Engine & Copilot Skill

Working alongside GitHub Copilot, I set up a lightweight, repeatable local migration pipeline rather than relying on live API calls during generation.

  • Local Data Snapshots: I dumped all posts and categories directly via the WordPress REST API into raw JSON files. Keeping source data local made generation instant, repeatable, and completely offline. I did install the WordPress MCP server, but I couldn’t get that to export the content.
  • Dependency-Free Static Site Generator: Copilot helped me write a Node.js script that reads the JSON snapshots and generates the homepage (showing the latest 5 posts), an article archive (holding all 45), seven category archives, individual article pages, RSS feed, sitemap, and robots.txt.
  • Content Cleaning: The generator strips out legacy WordPress markup, localises images, fixes internal link structures, and gracefully handles missing media assets (like catching dead legacy URLs without breaking the build).
  • UX & Theme Switching: Built client-side search, category filters, responsive navigation, and a clean light/dark theme toggle. The theme script executes in the document head before stylesheets load to prevent any flash of unstyled content.

3. Azure SWA & GitHub Actions Deployment

By default, Azure Static Web Apps tries to use Oryx to build incoming projects. Because the Node script already produces pre-rendered, valid HTML files directly in the repository root, there was nothing for Oryx to compile. That kept giving errors in GitHub Actions and was something I didn’t expect to go wrong right from the get-go. :D

4. Domain Delegation to Azure DNS

Moving the website code was only half the job; the domain management needed to shift to Azure DNS so I could bind custom apex records while preserving Microsoft 365 services. Also, I prefer keeping as much in the same place as possible.

The Nameserver Pitfall & Solution

When connecting domains to M365, it's easy to accidentally point registrar NS records to *.bdm.microsoftonline.com. However, M365's default domain management doesn't allow custom apex alias records for Azure Static Web Apps. The correct approach is delegating the domain entirely to an Azure DNS Zone. Something I had to look up as I never did this before. My sysadmin days never followed on Azure.

  1. Pre-Stage Records: Create the Azure DNS zone and replicate all existing M365 records (MX, SPF, DKIM selectors, Autodiscover) alongside the new SWA apex A-alias record before changing delegation. It was quite easy to just download the zone file and import it.
  2. Update Registrar Delegation: Switch to your own nameservers.
  3. Verify Propagation: Clear your local DNS cache with ipconfig /flushdns and query public resolvers using nslookup -type=NS yourdomain.com to verify cutover.

Key Lessons Learned

  • Codify Your Publishing Workflow: Building a publishing skill saves you from having to write out an entire prompt each time you want to publish a blog post.
  • Separate Site & Domain Migration: Site generation, deployment, and DNS delegation are distinct phases. Pre-stage all DNS records inside Azure before changing registry delegation to avoid mail flow or site downtime. It was a quiet weekend for email.
  • Treat the AI as your assistant: Be very clear in what you expect your finished product to look like. Start building it up bit by bit. Basically, take an agile approach. Get the barebones product and then start adding and fine-tuning features.
  • Validate locally, validate often: Test locally if your iterations worked out as you expected after each refinement. Do this locally to save time; your HTML pages work just fine on a localhost. 😉

Written by Edine Olijve. I write about what I learn while working with Microsoft 365.

About me