The Challenge: A Decade of Content at Risk
Migration projects are usually straightforward—until the tools break.
Recently, a large EdTech client approached me with a critical deadline. They were moving their 10-year-old Joomla platform (let's call it old-platform.org) to a modern SaaS solution: LearnWorlds.
The content migration was ready, the design was sleek, but there was a massive elephant in the room: SEO.
The site had over 10,000 indexed pages on Google. If we simply shut down the old server without a plan, every single one of those links would hit a 404 Error. The client’s search ranking—built painstakingly over a decade—would vanish overnight.
We needed a redirection strategy. And to save on hosting costs, we needed it to be Serverless.
The Roadblock: When Free Tools Fail
The industry-standard solution for this is Cloudflare. It handles DNS and routing at the edge, making it faster than any plugin.
We planned to use Cloudflare’s "Bulk Redirects" feature (Free Tier), which officially supports up to 10,000 rules. It seemed like the perfect fit.
But 24 hours before the launch, we hit a wall. Due to a provisioning glitch affecting many free accounts, our Bulk Redirect list was stuck at a hard limit of 20 items.
We had 2,116 specific URLs to map 1-to-1, plus 8,500 category pages. We couldn't wait for support to fix the glitch. We needed a workaround, and we needed it immediately.
The Solution: Cloudflare Workers + Google Sheets
Instead of buying an enterprise plan or setting up a dedicated server just for redirects, I decided to engineer a custom redirect engine using Cloudflare Workers.
Workers allow you to run JavaScript code at the "Edge" (before the request even hits a server). They are free, incredibly fast, and crucially, they have no "20 item" limit.
Here is how I engineered the solution using the tools I had at hand: Google Sheets and JavaScript.
Step 1: Turning Spreadsheets into Code
The client provided the URL mapping in spreadsheets. The data was messy—duplicates, root domain conflicts, and empty rows.
I didn't need a complex Python environment to clean this. I stuck to the tool that allowed me to visualize the conflicts instantly: Google Sheets.
I used Conditional Formatting to spot duplicate URL conflicts that would break the code. Then, instead of manually writing the JavaScript map, I used a simple spreadsheet formula to generate the code for me:
=" [""" & A2 & """, """ & B2 & """],"
In seconds, I transformed 2,000 rows of raw CSV data into a perfect, syntax-ready JavaScript Map.
Step 2: The "Waterfall" Logic
Redirecting 10,000 URLs isn't just about a list; it's about priority. If I treated every URL equally, the script might slow down. I wrote the Worker script using a Waterfall Logic:
- Priority 1: Specific Matches. If the visitor requests a specific article (e.g., /old-article-123), the script checks the Map and sends them to the exact new location immediately.
- Priority 2: The Homepage. I forced the root domain to the new landing page. This was critical because LearnWorlds often auto-redirects the root URL to a generic "Course Catalogue" if not handled explicitly.
- Priority 3: Category Patterns. Instead of writing 8,500 individual rules for the archives, I used Regex-style pattern matching. Any URL containing /news/ is automatically swept to the new News feed.
- Priority 4: Fallback. Anything else goes to the new Homepage to ensure zero 404 errors.
Step 3: The Code
Here is the core logic of the Worker script used in production:
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname + url.search;
// 1. Check Specific Map (Generated from Google Sheets)
// We check our Map for an exact match
let target = redirects.get(path);
// Smart Check: Handle trailing slashes automatically
if (!target && path.endsWith('/')) {
target = redirects.get(path.slice(0, -1));
}
if (target) {
return Response.redirect(target, 301);
}
// 2. Pattern Matching (Handling thousands of files with 1 line)
// This saves us from writing 8,000 individual rules
if (path.includes("/news/")) {
return Response.redirect("[https://new-platform.com/news](https://new-platform.com/news)", 301);
}
// 3. Fallback (Safety Net)
return Response.redirect("[https://new-platform.com](https://new-platform.com)", 301);
}
};
The Result: Zero Downtime
We updated the Nameservers, and the switch was instantaneous.
- URLs Redirected: 10,600+
- Cost: $0 (Cloudflare Free Tier)
- Server Load: 0% (Serverless)
- Time to Deploy: < 3 Hours
The client successfully decommissioned their old server without losing a single visitor.
Key Takeaway
Migration is not just about moving content; it is about engineering a bridge for your traffic. Sometimes standard tools break, but with a little resourcefulness—and some JavaScript—you can build a solution that is faster, cheaper, and more robust than the paid alternatives.
Need help managing a complex site migration? Contact Me to discuss your strategy.
