A modern AI reboot for my website and blog
- #astro
- #ai
- #meta
The last time I updated this site was 2017. It’s been running on Drupal and slowly collecting dust for nearly a decade. There was just never time to try and do something with it with all I had going on in my life. I didn’t want to lose the old content, and I didn’t want to do a bunch of migration work either. It only took an AI revolution in development for me to finally have the time to get it done.
The new stack is Astro with Tailwind CSS, hosted on Netlify. All 110+ blog posts are now stored as Markdown files in the repo — no database, no CMS, no server-side anything. Old root-level Drupal URLs redirect to the new nested /blog routes so nothing breaks. The whole thing builds to static HTML, and I can update the site anywhere with Claude Code - both content and code.
What I’m most excited about is how the migration actually happened. The majority of the planning and scaffolding was done from my phone, in the tub. I used the Claude app on my phone to build and run plans to scaffold the new Astro+Tailwind site and migrate over all the old posts from Drupal. I did it all from my phone - pulling SQL backups, providing them to Claude to source content from, setting up the new Github project, and the Netlify environments - all of it from the phone. Shout out to Github, Hostinger, Netlify, and Claude for supporting mobile (reasonably) well.
Once I had all the content ported over, back at my laptop I referenced the repo from Claude Design, iterated on the design, and reincorporated its work back into the Astro codebase where I used Claude CLI for further UI and content updates. I think it all turned out great.
Results
Before pulling the plug on the legacy Drupal install, I ran baseline scans with PageSpeed Insights (mobile and desktop), Mozilla Observatory, securityheaders.com, and Chrome DevTools — then re-ran the same scans post-launch against the new Astro site at the same domain.
PageSpeed Insights
The desktop numbers were already strong on Drupal (the site was static content), so the real story lives in the mobile rows.
| Drupal | Astro | Δ | |
|---|---|---|---|
| Mobile — Performance | 72 | 98 | +26 |
| Mobile — Accessibility | 78 | 100 | +22 |
| Mobile — Best Practices | 69 | 100 | +31 |
| Mobile — SEO | 92 | 100 | +8 |
| Mobile — LCP | 5.1 s | 1.8 s | −3.3 s |
| Mobile — FCP | 3.3 s | 1.1 s | −2.2 s |
| Desktop — Performance | 99 | 100 | +1 |
| Desktop — Accessibility | 76 | 100 | +24 |
| Desktop — Best Practices | 73 | 100 | +27 |
| Desktop — SEO | 92 | 100 | +8 |
I’ve honestly never seen a mobile PSI score this low (98). A lot of that lift comes from Astro’s static output that doesn’t require React and its Image component (WebP, lazy-loading, explicit dimensions).
Security
| Drupal | Astro | |
|---|---|---|
| Mozilla Observatory | D (35 / 100) | B+ (80 / 100) |
| securityheaders.com | R | A |
The Drupal install was on PHP 5.6 (end-of-life since 2018) and Drupal 7 (end-of-life January 2025) — so on top of the missing headers, it hadn’t received an upstream security patch in over a year. I also found where some bot had compromised the site and put links to buy shoes online at the bottom of a number of my posts 🤯.
Everything else
| Drupal | Astro | |
|---|---|---|
| Modern image formats | raw PNG / JPG uploads | WebP via Astro Image component |
| Homepage page weight | 2.1 MB · 60 requests | 1.3 MB · 46 requests |
| Blog post page weight | 2.1 MB · 47 requests | 1.2 MB · 47 requests |
| Custom 404 page | No | Yes |
| Structured data (JSON-LD) | No | Yes |
| OpenGraph tags | 5 basic, shared 250×250 logo | per-page + 1200×630 social card |
| Twitter Card | No | Yes |
I expected the AI workflow to be the headline of this rebuild. The numbers turned out to be a pretty good headline too.
This same workflow has been revitalizing my work on other projects as well. I’ve been using it to reboot Line Diet as a modern web app, and I’ve also started work on a new product called ChurchBells. I hope to share more about both (and some AI ramblings) soon.
More posts to come. Good to be back!