zParacha.

Effective Programming Tips

← Home

Why I Rebuilt My 15-Year-Old Blog in Astro

September 6, 2026

I launched zparacha.com in 2007 to blog about Java programming, then other commitments pulled me away, and I stopped publishing in 2018. For years, it just sat there with WordPress, a Themify theme, and 152 posts slowly drifting further from anything I’d write today.

This is how I rebuilt the site, including the challenges I encountered.

The audit brought an unexpected discovery

Before making any changes, I checked the site’s actual numbers using the WordPress REST API and sitemap instead of guessing. My first pass got it wrong — a quick skim of the page listings suggested 260 posts. The API said 152. Always check the API, not the pagination.

An even bigger surprise was what those 152 posts were actually about. I thought most would focus on Java and algorithms, but that wasn’t true:

Category Posts
Blogging 41
Java 37
Programming 21
Best Sites 18
Javascript 16

The largest category was Blogging, specifically 2007-2010-era “how to grow your blog” advice, rather than the programming content the site is known for. This, rather than the few Cricket and Pakistan-news posts I expected to be problematic, was the main source of content dilution.

Retain 70 posts, archive 82 — avoid delete-and-redirect

It might seem logical to remove off-topic content and redirect everything to the homepage, but I decided against it. Too many redirects to the homepage can look like soft-404 errors to Google, which could lower crawl trust for the whole site, not just the redirected pages.

So instead: 70 posts from the technical categories (Java, Programming, Algorithms, Web Development, CSS, Ajax, JavaScript, Spring, Best Software) shipped on the main site at their original slugs. The other 82 moved to /archive/<slug> — real pages, out of navigation, with the old URL 301’d to its new archive location. Nothing got deleted. No 404s.

The stack, and why

I chose Astro because it doesn’t include any JavaScript by default and supports Markdown-based content collections with schema validation. For page design, I used Tailwind CSS with the official Typography plugin, and I picked Cloudflare Pages for hosting.

I didn’t use any client-side framework. The two interactive features, the dark/light toggle and the code-block copy button, are handled with about 40 lines of plain script. For a blog with so little interactivity, a component framework just isn’t needed.

Migrating content: turndown, and a plugin I’d forgotten existed

I wrote a Node script to pull each post’s full HTML from the WordPress REST API and convert it to Markdown using Turndown. There was a complication: many posts used the EnlighterJS syntax-highlighter plugin, which wraps code in <pre class="EnlighterJSRAW" data-enlighter-language="java">. Most HTML-to-Markdown converters don’t recognize this as a code block, so I added a custom Turndown rule to convert it into a proper fenced code block with the correct language tag.

After this change, Astro’s built-in Shiki syntax highlighting picked up the language tags automatically. Now, every migrated code sample shows the right syntax coloring without needing any extra highlighting code.

The images were already broken

At first, I thought moving images would just mean copying the wp-content/uploads folder into the public directory. But a meaningful chunk of them were already dead — some returning connection-refused, some caught in an actual redirect loop, on the live site, today. 48 images across 39 posts pointed at either the current WordPress media library or a raw fallback IP address that no longer resolves at all.

Recovering images was hit or miss. Some still loaded from the live site, while others had to be pulled from Wayback Machine snapshots. I downloaded all 48 images and hosted them locally. While doing this, I also found and fixed about 14 dead links in those posts: old attachment-page links, and cross-references to other posts on the same blog where the slug had drifted over the years. A handful had no reasonable destination left at all, so I stripped those down to plain text rather than ship them as dead links.

The bug that undid my own plan

The plan was simple: keep the 70 posts at the site root with their original slugs, so no redirects would be needed. But I later realized they had been published at /posts/<slug> instead of the root, so the “zero redirects needed” idea didn’t work out.

This problem also caused a bug: two catch-all routes lived under /posts/, one for individual posts and one for pagination. Sometimes, this made Astro’s development server return a 404 error for valid posts. Moving the 70 posts to root-level routes fixed both the URL mismatch and the routing confusion. Now the URLs match the original WordPress permalinks, and the routes no longer overlap.

What’s next

The content plan going forward is focused on modern Java and Spring, plus related topics: application security and DevSecOps, backend/systems concerns like CI/CD and observability, and AI-integrated development workflows.