This content originally appeared on DEV Community and was authored by Aleix Nguyen
I originally built my Assetto Corsa mod-sharing site using Hugo. It was blazing fast, simple to host via Cloudflare Pages, and easy to manage — as long as I only had a few dozen posts.
But when the content grew past 900 posts, it hit a wall:
- Markdown got painful to manage
- Hugo couldn’t handle dynamic filters or AJAX search
- Cloudflare build limits became a blocker
- There was no CMS, no backend, no future scalability
So I migrated everything to WordPress.
No PHP experience. No front-end background.\
Just system thinking, debugging skills, and actual product need.
Why Hugo Fell Short
- No dynamic features (search, rating, filtering)
- Markdown hard to manage at scale (~900 posts)
- Static build quota exceeded daily on Cloudflare Pages
- No real CMS backend for future editors or monetization
The Migration Approach
Rebuilding the Theme (Without PHP Knowledge)
- Reused TailwindCSS and custom CSS from Hugo
- Structured the theme using standard WordPress templates (
header.php
,index.php
, etc.) - Modularized parts like post card, filters, search form
- Replicated ~90–100% of the original Hugo design
- Added Swiper.js sliders for gallery-like single posts
// With AI support, I built PHP logic step by step:
// - Template hierarchy
// - WP loop
// - Hook functions
Markdown to ACF Field Mapping
- Parsed frontmatter from all
.md
files using a custom PHP script - Mapped: title, date, tags, category, thumbnail → native WP fields + ACF fields
- Script executed via Composer CLI
- Iterated 7–8 times to fix import bugs
- Final pass: 850+ posts imported cleanly, ~40 had minor date issues (acceptable)
- During this migration, I also refined the content structure:
- Removed outdated or non-compliant posts to align with long-term goals (performance, SEO, monetization)
- Trimmed frontmatter fields down to essential metadata only (e.g. version, source, author)
- Normalized inconsistent fields for cleaner ACF mapping and easier template logic
Dynamic Features Implemented
AJAX Search, Filter, Sort & Pagination
- Custom admin-ajax.php endpoints
- PushState navigation
- Slight delay (~200ms) to improve UX smoothness
- WP_Query dynamically filtered via JS
Auto-scroll to top after pagination was planned but not implemented due to AWS account suspension.
Star Rating System
- Stored as post meta
- One vote per cookie/session
- Average + total rating shown live
Swiper Slider
- Built from ACF repeater fields
- Responsive gallery inside single post
Security
- All AJAX calls nonce-verified
- Output escaped (
esc_html
,esc_attr
) - XML-RPC disabled
- Login URL hidden
- No security plugin used — manual best practices applied
Testing
- Lighthouse score: 95+
- Pingdom (SF): 95
- AJAX response: 100–150ms
- Tested on Chrome, Firefox, Safari, Edge
- Mobile-friendly (DevTools + real devices)
What I Learned
I didn’t know PHP or AJAX when I started.\
But I knew how to think in systems.
- I broke every challenge into sub-problems
- Used AI like a debugging assistant, not a crutch
- Validated everything manually — request by request
- Built like a backend/infrastructure person would: by owning the logic
- Migration wasn’t just technical — I had to rethink what content was worth keeping, and how to structure it for long-term scalability and compliance
Final Result
- Fully custom WordPress theme (no commercial theme/plugin)
- Dynamic features integrated: search, rating, slider
- 900+ posts migrated, structured via ACF
- SEO, schema, cookie consent — AdSense-ready
“I didn’t clone a theme. I engineered one — as an infra guy who just needed a better frontend.”
Screenshots & GIFs
See the full repo below for all before/after images, GIFs, and admin views.
GitHub Repo
github.com/aleixnguyen-vn/hugo-to-wordpress-migration
Bonus: Live Deployment Case
This WordPress site was later deployed using:
- LiteSpeed + Redis
- On a \$0 AWS Free Tier instance
- Serving 250 concurrent users at ~189ms response time
Check out the full infra case study →
This content originally appeared on DEV Community and was authored by Aleix Nguyen