For years ianpiggott.com was a WordPress site. I logged into the admin, hit publish, and hoped plugins would not fight each other after the next update. PHP and MySQL did their thing on the host. It worked — until the maintenance started to feel like the main hobby.
In July 2026 I rebuilt it as a static Astro site. The site is just HTML files now. No database on the server. No plugin updates. Upload the build and it loads quickly.
I did not hire anyone. I sat in Cursor with Grok (xAI) — Super Grok when the jobs got big — and we went back and forth until it felt right. I said what I wanted. Grok read the files, wrote the code, ran the build, broke things, fixed them, and waited for the next “almost, but…”. That is basically the whole story.
What I actually wanted
I was not shopping for a trendy stack. I wanted the same site — same posts, same odd mix of drums, tech, whisky, detailing, and silly games — without the WordPress tax. Keep the writing. Keep the URLs where I could. Drop the parts that only existed so WordPress could keep being WordPress.
Keep the content
Years of posts, photos, categories, tags, and dates. Google already knew those addresses. Throwing them away would have been stupid.
No more WordPress runtime
Build once into dist/, upload static files to VentraIP (or anywhere), and stop worrying about core updates and plugin conflicts.
Make it nicer to use
Cleaner layout, mobile nav that works, search, RSS, pagination, tag pages, and a privacy page that matches how the site actually behaves.
Keep some personality
Games, photo lightboxes, social links — built into the project, not bolted on with another plugin that might die next year.
Own how work gets done
Grok does the typing. I decide what “done” looks like. Faster than clicking around wp-admin, and more fun too.
What we used
If you do not live in static-site land, here is the short version of the kit.
| Layer | Choice |
|---|---|
| Framework | Astro 7 — turns the project into HTML at build time. Most pages barely ship any JavaScript, so they feel snappy. |
| Content | Markdown files in src/content/posts/ with a small YAML header. Each post is a file you can open, edit, or diff in git. No database row to hunt for. |
| Styling | One global stylesheet with design tokens (--color-accent and friends) so the black / white / gold look stays consistent without a page builder. |
| Feed / SEO | @astrojs/rss, @astrojs/sitemap, canonical URLs, Open Graph tags — so search engines and social previews still work. |
| Games | Canvas 2D inside normal .astro components. No game engine. Same repo as the blog. |
| IDE + AI | Cursor + Grok. Super Grok when a job touched lots of files and needed the whole thread to stay coherent. |
How it actually went — four phases
We did not try to finish everything on day one. Roughly four chunks of work, in order. Skip redirects or content cleanup and you pay for it later.
Phase 1 · WordPress export → Astro content
WordPress already had the archive. I exported a normal WXR XML file and grabbed the old wp-content/uploads folder. That is the whole pile — text, metadata, images.
Grok wrote scripts/migrate-content.mjs to parse that dump, write one .md file per post, copy uploads into public/, and tidy the HTML along the way. One script run instead of copy-pasting a decade of writing by hand.
URL rewrite
Old image links pointed at ianpiggott.com/wp-content/uploads/…. The script rewrote them to /wp-content/uploads/… so they still work without renaming every file.
AdSense shortcodes
WordPress used [adToAppearHere]. Those became <div data-adsense="true"> markers the new layout can fill.
YouTube
Bare watch links became proper responsive embeds so videos play inside the article.
Cleanup
Broken galleries, contact-form shortcodes, Gutenberg leftovers — stripped. Drum posts that lived under music moved to drums where that made more sense.
Run once
cd site
npm run migrate
End of that phase: dozens of markdown posts with proper frontmatter (title, slug, date, category, tags). src/content.config.ts checks that shape before the site builds. Bad post? The build yells. Better than a silent broken page.
Phase 2 · Layout, routing, and SEO
Having posts on disk is not enough. People (and Google) still type the old addresses. A post that used to live at /music/chad-smiths-drum-and-cymbals-on-bssm/ needs to keep working, or you lose bookmarks and search ranking for free.
So we kept the same pattern: /{category}/{slug}/, built from src/pages/[category]/[slug].astro. Where a category name changed, we added redirects instead of hoping nobody noticed.
Those live in astro.config.mjs and public/_redirects (plus .htaccess on Apache). Treat redirects as part of the migration, not a tidy-up later. Broken old links are a great way to waste years of SEO goodwill in an afternoon.
Phase 3 · Making the text readable again
The export got the words out of WordPress. It did not make them nice to read. Plenty of posts arrived as one giant HTML blob, weird spacing, or shortcodes that only meant something inside wp-admin.
This bit was half scripts, half judgement:
npm run format:posts— tidy HTML across the whole set in one go- Extra care on posts people actually find from search (Chad Smith kit, Tama Superstar ID, Illawarra Awards, and so on)
- Hero images where a homepage or category card needed a face
npm run adsense:markers— up to two in-article ad slots on longer postsnpm run import:youtubeandimport:xfor fresher embeds and social posts at build time
Rule of thumb: let the scripts do the boring repetition. Spend your attention on the pages people land on.
Phase 4 · Features (the fun part)
Once the bones worked — posts, categories, redirects, a homepage — the rest was just conversation. I would type something ordinary in English. Grok would build it, run npm run build, fix the errors, and show me what changed.
- I describe the outcome (“add search in the nav”, “pin two posts on the homepage”, “slow the balloon down”).
- Grok implements and runs the build so we know it compiles.
- I click around, try it on the phone, play the games — the stuff you only notice when you use the site yourself.
- Short feedback. Another pass. Repeat until it feels right.
That loop is why a bunch of extras showed up that were never in the original “migrate WordPress” brief:
Pages that shipped
- Homepage with hero, category pillars, social pills, and an X feed block
- Blog with pagination (24 posts per page)
- Tag archives, About, Contact, Privacy, 404
- Site search with a built index
- Gallery lightbox for photo posts
AdSense
- Markers in post HTML →
AdSense.astroslots at build time - Shared ad units aligned with my other Farming Domains sites
- Article top/footer on every post; in-content markers on longer articles; in-feed units on listing pages
Browser games
- Slice Invaders — Fun section shooter
- Slice Balloon — contact page arcade
- Slice Arcade promo card on the homepage
If you want the balloon story on its own: Building Slice Balloon With AI in Under 10 Minutes.
What Grok did vs what I did
People always ask this. Fair question. Grok had the keyboard most of the time. I had the taste calls.
What Grok had in Cursor
This was not a chatbot in a browser tab next to the editor. It was plugged into the project:
- Full repo context — open any file, search the codebase, follow imports
- Shell access —
npm run build, dev server, migration scripts on Windows PowerShell - Multi-file edits — layout, component, and post in one go when a feature needed it
- Build-fail loops — see the TypeScript or Astro error, patch it, rebuild, without me pasting stack traces
Super Grok is the tier for longer work. Migration scripts, bulk formatting, pagination, tag archives, AdSense marker passes — jobs that touch dozens of files and fall apart if the agent forgets what you asked twenty messages ago. I set the direction. Super Grok ground through the list.
What I did
Grok is quick. It still has no idea what you care about until you say it. My side looked like this:
- Priority — redirects before launch, privacy wording before ads, mobile nav before polish
- Taste — game speed, card copy, which posts get a hero, when a paragraph needs splitting
- Playtesting — canvas games and touch targets are where AI guesses wrong until a human actually taps the screen
- Plain feedback — “the gallery feels cramped on mobile” beats dictating CSS pixels
WordPress gave me wp-admin. This gave me a chat thread and a git diff. For a personal site I still poke at often, that trade is fine.
Dev tip — stale localhost cache
New post 404s locally but the rest of the site is fine?
Astro’s dev server can get stuck after you add posts or change the content config. If the file is sitting in src/content/posts/ and localhost still says 404, start a fresh dev server — it kills the old process, clears .astro/data-store.json, and rebuilds:
npm run dev:fresh
On older Windows PowerShell, && can misbehave — use ; between commands instead.
Where things live in the repo
If you open the project and wonder where to look:
site/
├── src/content/posts/ # migrated + new articles
├── src/components/ # games, gallery, ads, social
├── src/pages/ # routes (blog, contact, fun, rss)
├── public/wp-content/uploads/
├── scripts/migrate-content.mjs
└── dist/ # static output after npm run build
WordPress vs this setup
Day-to-day difference matters more than benchmark bragging.
| WordPress | Astro + Grok | |
|---|---|---|
| Publish | Log into admin → edit → Publish | Edit a .md file or tell Grok what to change → npm run build → upload dist/ |
| Security | PHP, database, plugins, regular updates | Static files on the host — nothing executing server-side for the blog itself |
| Custom features | Plugins, theme hooks, fingers crossed after updates | Components in the same repo — games, lightbox, search, all first-class |
| Performance | Database + PHP on every page view | Pre-built HTML; the host mostly just serves files |
| Who builds | You in wp-admin, or a developer on a invoice | Grok in Cursor, guided by me |
Why this feels like the future
I rebuilt this site by talking to Grok in Cursor while it worked in the terminal — reading files, running builds, patching code, coming back when I said “almost, but…”. That is not a party trick. I think building sites this way — and coding in general — is where a lot of software is headed.
Right now it still looks a bit technical: chat panel, repo, shell, npm run build. I am looking forward to the next step, hopefully soon, when more of this is voice-driven. You describe what you want, the agent ships it, you react in normal language. Less staring at a terminal.
Here is the AI jargon, in plain English, so the pieces join up instead of floating as buzzwords.
How new this really is
Not long ago, “AI helped me code” meant autocomplete — a smarter Tab key that finished the line you were already writing. Handy. Not life-changing.
What changed over the last year or so is agentic development: models that can read a whole project, run commands in the terminal, edit many files in one sitting, recover from build errors, and remember what you asked earlier in the chat. Cursor put that inside a real IDE instead of a copy-paste side panel. Super Grok helped on the multi-step jobs — migration scripts, bulk formatting, pagination — without me babysitting every path.
In short: a model that can reason, tools it can use, and a human steering. That combo is still early. One person with an AI pair-programmer can ship a surprising amount in a weekend if they stay in the seat and keep giving direction.
Why WordPress feels old next to this
WordPress earned its place. It still runs a huge chunk of the web. But after living on this rebuild, a classic WP stack feels like a filing cabinet next to a laptop.
- Runtime — PHP, database, plugins, and update cycles vs HTML files you upload once
- Change speed — admin screens, theme hooks, plugin fights vs “put a game on the contact page” in one conversation
- Attack surface — logins, plugin bugs, cron jobs vs files on a host with nothing running for the pages themselves
- Room to invent — Gutenberg blocks and page builders vs components, canvas games, lightboxes written as real code
A WordPress site can still look modern. Under the hood a lot of them still behave like 2012 with nicer clothes. This rebuild feels current.
Terminal today, voice tomorrow
The interface is hybrid right now. You talk like a person in chat, but the agent still lives in a dev environment and a shell. That is a bridge, not the end state.
The direction is obvious enough: say “make the hero taller”, “slow the balloon”, “add a tech post about the migration”, look at a preview, say yes or no. The repo and build steps fade into plumbing — the same way most people stopped hand-editing raw HTML years ago.
I am keen for voice-driven site building. Until that is normal, Grok in Cursor is already fast enough that I would not go back to wp-admin for a personal site like this.
A simple map of the shift
Three rough layers, if you want a mental model:
Layer 1: AI writes snippets. Autocomplete, “fix this error”, one function at a time. Helpful, but you are still project-managing everything.
Layer 2: AI operates the project under your direction — migration scripts, redirects, games, privacy page, search. You set goals and taste; the agent moves files, runs builds, and iterates. This rebuild lives here.
Layer 3: AI runs more of the loop from speech or chat; you mostly approve outcomes. “Rebuild my site like that one, but with a whisky section” becomes a normal Tuesday. That is when “build a site in an afternoon” starts to sound realistic for people who do not live in an IDE.
Layer 3 is where the labs are racing. Layer 2 is usable now if you are willing to sit in the editor and steer.
Things I would tell myself next time
- Export + script beats copy-paste — an afternoon on
migrate-content.mjsbeat weeks of hand-copying fifty posts. - Redirects are part of the content — get
_redirectsandastro.config.mjsright before you call it live. - AI is fast; you still have to playtest — especially games, mobile layout, and anything with fingers on a screen.
- Static does not mean stuck — RSS, pagination, search, ads, and the arcade games all arrived after the first migration pass.
- Use the workflow you will actually use — for me, Grok + guidance beat wrestling the block editor.
- Chat + terminal is a bridge — voice-first building is the destination; getting used to the conversation model now helps.
Have a look around
The tagline is still My Own Slice of the Web. The stack changed. The voice is still mine. WordPress got me here. Astro, Cursor, and a lot of Grok got me the next version — with me still calling the shots.
