Skip to main content
Back to Projects
Technical SEO / WordPressWordPressWPML.htaccess / ApacheRedirectionYoast SEOSearch Console

Shutting Down Three Markets and Restructuring a Live Multi-Region WordPress Site

Technical SEO Engineer & WordPress Consultant
8 min read

The client runs a VR therapeutics platform on a multilingual WordPress site, with several regional sections served through WPML. The engagement started as a contained brief: implement about 100 URL redirects, and permanently shut down three regional sections for markets the business had exited. It grew into a standing relationship across four separate workstreams, all on a live, revenue-driving production site where a wrong status code or a stale cache is a costly, visible mistake.

~639 indexed pages → 0717 items retired to clean 410s100+ redirects, single-hop, 0 chains4 workstreams, 0 downtime

Context

Two facts about the site shaped everything.

First, it ran two redirect systems at once: a redirect plugin (182 rules) and roughly 200 hand-written rules in the server's .htaccess. This is exactly the "server rules and a plugin fighting each other" situation that quietly breaks sites, and it meant every change had to be validated against both layers, not just the one that was easy to see.

Second, it ran two cache layers, a WordPress page cache plus a server-level cache, either of which will happily serve a stale 200 after you have changed a page to a redirect or a 410. Getting the status codes right is only half the job; proving the public actually receives them is the half people skip.

Add WPML multi-region, a page builder, and a live paid-campaign layer pointing ads at real URLs, and "just add some redirects" stops being simple.


Part 1: Retiring three markets

The client sheet listed 283 URLs to remove across the three regional sections. Before touching anything I enumerated the actual content under those prefixes through the WordPress REST API, and found 717 items, not 283. The extra 434 were VR environment pages, testimonials, and press-release translations that were never in the sheet but would have stayed publicly live if I had worked from the sheet alone. I flagged the delta and shut all of it down.

The shutdown itself:

  • Full database backup first, then every item set to draft rather than deleted, so the entire change was reversible with a logged per-item rollback.
  • A proper 410 Gone at the server level for all three sections, with the regex ordered so a shorter prefix could never swallow a longer overlapping one.
  • WPML languages deactivated so the dead regions dropped out of the language switcher and the hreflang tags, with translations preserved in the database.
  • Sitemap and crawl rules handled deliberately: I left the dead sections crawlable at launch, because Google has to be able to crawl a URL to see the 410 and deindex it. Blocking them in robots.txt too early is a common mistake that slows deindexation down.
  • Both caches purged, then every one of the 717 URLs verified twice, once normally and once with a cache-busting request, to catch any stale 200 the server cache might still be serving.

I then submitted removal requests in Search Console and monitored the outcome. Google indexed roughly 639 pages under the three sections at the start. It fell to ~465 within two days, and to zero within about a week, where it held. I re-checked at the two-week and four-week marks and reported the curve honestly, including the part where some of that traffic was already declining before the shutdown, so a future dip in sitewide numbers would not be mistaken for a technical problem.


Part 2: The main-region restructure

The redirect map looked like a straightforward "point old at new" exercise. It was not, for a reason specific to WordPress: a page's URL is built from its parent's slug, so a page cannot stay at its address once its parent section moves. Several landing pages the client explicitly wanted left untouched lived inside two sections that were being relocated. Moving the sections would have dragged those pages along and changed their URLs, which for live paid-campaign destinations is exactly what you do not want.

The fix was a ghost-parent technique: move the real section under its new parent, recreate a lightweight placeholder at the old path, and reparent the protected landing pages onto the placeholder so their URLs are preserved to the character. The pinned pages stayed exactly where the ads pointed; everything else moved and got a clean 301.

Two things from this phase are worth calling out, because they are the difference between "the redirects are in" and "the site actually still works":

I validated the map against both redirect layers, not one. My first pass checked only the plugin export and looked clean. Once I had server access and could see the .htaccess, re-running the same validation against both layers surfaced nine redirect chains the plugin-only view had completely missed, several of them two-hop chains that would have quietly degraded crawl efficiency and link equity.

A regression crawl caught a collateral break, and I chased it to root cause. After the changes, a full re-crawl flagged a URL in another region that had gone from working to a 404. It was not in any map. The cause was WordPress's own 404 slug-guessing: an address that was never a real page had been silently resolving to a live page by name, and my change moved the page it had been guessing at. I proved the mechanism by experiment, hardened the affected URLs with explicit redirects so they no longer depended on guessing, and swept the rest of the section for the same pattern. Every redirect across the whole of this phase ended up verified as a single clean hop, with query strings passed through so ads, UTM tracking, and bookmarks all kept working, and a full before-and-after crawl confirmed zero collateral damage.


Part 3: The audit and the domain migration

Once the core work was done, two more workstreams came out of it.

The client asked whether other live pages existed that were never in the inventory. I enumerated every published page on the site and diffed it against the workbook: 126 published pages were live but listed nowhere, a mix of orphan landing pages, old duplicates, and leftover builder templates. I handed over a classified list, the client marked each one keep, redirect, or prune, and I executed the decisions with the same verification discipline as the rest.

Then leadership decided to move the entire services line to a separate domain. I migrated all 51 service pages with single-hop 301s (pointing at the canonical www host directly, since the apex forwarded to www, so nothing took an extra hop), pruned the retired landing pages to 410, and left the legal and compliance pages in place. A follow-up health pass then found that dozens of older legacy redirects now funneled through the moved section, so I prepared the corrected server file to flatten those too.


How I worked

The through-line across all four workstreams was the same, and it is the reason a small redirect brief turned into a multi-month relationship:

  • Everything reversible. Draft, never delete. Back up before changes. Keep a per-change log that a rollback script can read.
  • Verify against reality, not the plan. Crawl before and after. Bust the cache on every check. When the plan and the live site disagree, the live site wins.
  • Flag the dangerous thing instead of running it. One row in the client's own sheet would have set the main section page to draft, taking down the page that half the new redirects pointed at. I did not run it. I explained why, recommended the safe alternative, and waited for a decision. The same instinct surfaced a redirect quietly sending live traffic to a leftover development domain.
  • Be honest in the numbers. Report the decline that was already happening. Note the lag in Search Console data. Say when a "fix" is cosmetic rather than load-bearing.

What I took from it

The satisfying part was not any single redirect. It was operating on a live production site with SEO stakes and paid traffic on it, making a hundred-plus changes across two redirect layers and two cache layers, and having the after-crawl come back clean, because the one thing that did break got caught by a regression check and fixed the same day rather than by the client a week later.

That is the whole job on work like this: get the status codes and the caching right so the change is invisible, and build enough verification around it that when something unexpected moves, you find it before anyone else does.