Migrating From Wagtail To Astro (1): Why Migrate And How I Chose
· 19 min read · Views --
Last updated on

Migrating From Wagtail To Astro (1): Why Migrate And How I Chose

Author: Alex Xiang


Migrating From Wagtail To Astro (1): Why Migrate And How I Chose

This series records the full process of migrating the ZiCode blog from Wagtail, a Django CMS, to an Astro static site. It covers motivation, technology selection, migration phases, daily writing, and deployment. This first article explains why I wanted to migrate and how I chose the new stack.

Why Migrate

Pain Points In The Old Architecture

The site previously used Wagtail as the CMS, with Django + SQLite on the backend, deployed on a single server. After a few years, several pain points became more visible:

  • Operations cost: I had to maintain the Python environment, database, static files, and media files. Django and Wagtail upgrades occasionally introduced compatibility issues.
  • Resource usage: Even with modest traffic, the resident process and database still consumed memory and disk.
  • Publishing flow: Content was edited and published in the admin UI. If I wanted to manage posts with Git or write Markdown locally before publishing, extra workflow glue was needed.
  • Frontend flexibility: Wagtail templates and the frontend stack were relatively fixed. Adding dark mode, site search, or more flexible layouts required more work than I wanted.

So the goal was to move the blog toward a model where content files are the source of truth, and a static site is generated at build time. The migration should preserve existing content while reducing operations work and simplifying publishing.

Migration Goals

  • Content continuity: Preserve historical posts, categories, tags, columns, publication dates, and readable stable URLs as much as possible.
  • Writing workflow: Write new posts in Markdown, keep them in the repository, and manage them together with code.
  • Static output: Build pure static HTML/CSS/JS that can be deployed to any static hosting service or to the existing server.
  • Better reader experience: Add dark mode, site search, better layout, and better hero image presentation.

Choosing A Static Site Generator

Candidate SSGs

I considered several options:

OptionStrengthsConcerns
HugoVery fast, mature ecosystem, many themesGo template syntax does not match the frontend stack I usually use; deeper customization means learning another model
ZolaRust ecosystem, simple configuration, I had written Zola tutorials beforeLess aligned with the React/component-oriented frontend direction I wanted
Next.js static exportFits the React ecosystemFeels heavy for a content-first site; build and deployment are larger than needed
AstroContent-first, native Markdown/MDX, can mix in React and other UI libraries, lightweight outputNewer than Hugo, but documentation and community are already good enough

Why Astro

I eventually chose Astro for several reasons:

  1. Content-first design: Content Collections and Markdown/MDX are first-class features. Frontmatter can be validated with Zod, which fits the idea of managing posts as files.
  2. Zero JS by default: Astro outputs static HTML by default. Interactivity such as search or theme switching is added only when needed, which helps first-page performance and accessibility.
  3. Flexible frontend stack: If a future section needs React or Vue, it can be introduced locally without changing the entire site.
  4. Simple build and deployment: astro build produces a dist/ directory. It can be uploaded with rsync or SCP, or connected to CI/CD.
  5. Compatible with existing assets: Wagtail content and media paths can be exported to Markdown and mapped into the structure Astro expects.

Looking at migration cost, maintenance, and future extensibility together, Astro fits a long-running Chinese technical blog quite well.

Quick Comparison With Other Options

  • Hugo: Extremely fast and has many themes, but customization requires familiarity with Go templates and Hugo content types. If your team mostly works with React or Vue, there is still a learning cost.
  • Zola: Tera templates and simple configuration make it pleasant. I have written a Zola tutorial before. If a site has little interaction, Zola is enough, but Astro’s Content Collections and component model better match modern frontend habits.
  • Next.js static export: output: 'export' can generate a static site, but Next’s default mental model is still closer to an application than a content site. Routing, data fetching, and image handling introduce more configuration than I wanted for a blog.
  • Astro: Its design starts from content and adds interaction only when necessary. Documentation around Markdown, frontmatter, and collections is complete enough to get started quickly.

Things To Decide Before Migration

  • Should URLs stay the same? If the old site already has external links or search engine indexing, keep new post URLs consistent with old ones where possible, such as /blog/<slug>/. If necessary, add 301 redirects in Nginx or the old site.
  • Comments and analytics: If the old site used third-party comments or analytics, reconnect them after migration or choose a new solution such as Giscus or Umami.
  • RSS: Astro can generate RSS. Keep the feed URL stable or add redirects so existing subscribers are not affected.

Series Outline

The remaining articles follow the actual migration order:

Once the technology choice is clear, the next step is to split the migration into stages. The next article explains the main phases, including data sync, content conversion, URL design, and validation checklists.