The replatform from WordPress to Astro was supposed to be the project. It turned out to be the prologue.
Exporting content, rebuilding templates, getting a static site to compile and deploy to Cloudflare Pages took weeks. Then the actual year began: redirects, hreflang, six-locale parity, and a build that outgrew the platform it was deployed to. This is where the time went on wppoland.com - because it did not go where the planning said it would.
The port is the cheap part
Everyone budgets for the visible migration, and the estimate is roughly right. Content out of WordPress, templates in Astro with Tailwind, npm run build, deploy to Cloudflare Pages. A content site of moderate size reaches a working static build in weeks. This is the phase that demos well and convinces everyone the project is nearly done.
It is not nearly done. A working build proves templates render. It proves nothing about whether old URLs resolve, whether locales agree with each other, or whether the build still finishes when content triples.
Surprise 1: the redirect layer
Every URL WordPress ever exposed and Google ever indexed needed a 301 to its new Astro address. On a six-locale site with descriptive slugs that runs into thousands of rules.
Cloudflare Pages has a _redirects file-size cap around 100KB. Past that, rules are silently dropped - no build warning. We learned this months later from 404s in Search Console, long after the migration looked finished. The fix was a Functions middleware layer for overflow rules and explicit monitoring of redirect coverage.
Lesson: the redirect map is not a checklist item. It is a system you operate, with its own failure modes.
Surprise 2: six locales that must agree forever
WordPress, with the right plugins, hides multilingual structure behind an admin. A static build exposes it.
Six language versions of every article have to stay structurally parallel: same section headings in the same order, hreflang links that resolve to real siblings, canonical URLs that match intent, taxonomy URLs aligned across locales. When one locale drifts, the cross-language link graph cracks at the indexing layer while every page still renders fine.
Post-migration, parity stopped being a milestone and became a standing check on every content change. Six locales do not stay aligned on their own - especially when translation tooling touches structural fields.
Surprise 3: the build outgrew Cloudflare's runner
Cloudflare Pages serves a large static site effortlessly. Building one is bounded by memory. The platform build runner tops out around 8GB heap. Our multilingual Astro site with thousands of prerendered pages (locales multiply page count) exceeded that and failed with OOM errors that took time to recognize.
The fix: stop building on the platform. Build locally with a 16GB heap, deploy the finished dist/ with Wrangler. An M-series Mac finishes reliably in minutes where the constrained runner could not finish at all.
Related discipline on images: Astro's asset pipeline optimizes at build time (excellent, memory-hungry). Pre-optimized hero backgrounds live in public/ served as-is; only images that genuinely benefit from pipeline processing stay in the asset folder, kept reasonably sized.
What you rebuild that WordPress gave you free
Leaving WordPress means inheriting checks plugins used to perform invisibly: internal link validation, sitemap freshness, broken reference warnings in the admin.
Over the year we wired validators into deploy: internal-link scans against the real route surface, structured-data shape checks across locales, parity checks comparing language siblings for missing sections, build-time sitemap and hreflang generation. Each replaces something WordPress did silently. More control, more confidence - but real engineering the word migration does not mention.
What the move actually bought
Stated plainly so the year does not read as regret: worth it for this shape of site.
- Pages render from the edge as static files - faster and steadier than request-time PHP
- Attack surface shrank to roughly nothing dynamic
- Crawler access became predictable (important when AI assistants fetch HTML without running your JavaScript)
The honest qualifier: right trade for a content site; wrong trade for a site that lives on dynamic, logged-in functionality where WordPress's ecosystem is the feature.
TL;DR for anyone scoping a similar move
| Phase | Time | What hurts |
|---|---|---|
| Port (templates + content) | Weeks | Underestimated but manageable |
| Redirect map + monitoring | Months | Silent caps, Search Console lag |
| Locale parity | Continuous | Drift is invisible until indexing breaks |
| Build scaling | One hard week | OOM on platform runner; local build + Wrangler |
Budget for the tail, not the port.
We run WPPoland - senior WordPress and Astro engineering from Gdynia, Poland. If you are mid-migration and the redirect map or six-locale parity is where the project stalled, that is usually the work we get called for.
Related on DEV: Read-only MCP server for WooCommerce ยท Wholesaler API sync into WooCommerce
Top comments (0)