Field report
Adding a Citable Content Layer to a Live WordPress Domain
The short answer
How do you add a citable content layer to a site you can't rebuild?
On our auto-finance rebuild, 1 Cloudflare Worker on the apex works as an explicit allowlist. Only GET and HEAD requests on 12 content path prefixes and a short list of named files reach the new static library. Everything else — every other method, and every path the Worker has never heard of — passes to WordPress untouched, so live lead flow was never in the new layer's path [our data].
The site that most needs a citable content library is usually the site you are least allowed to touch: live lead flow, a converting funnel someone tuned over years, a CMS the client's team knows how to use, and a URL structure carrying whatever equity it has.
On our auto-finance rebuild we did not migrate it. One Cloudflare Worker on the apex holds an explicit allowlist of content paths and sends everything else to WordPress untouched, so the knowledge surface moved and nothing else did [our data]. This page is the routing and cutover record. The trust-liability repair that had to happen on the same domain before any of this — fabricated review markup, hidden text, four contradictory approval-rate claims — is a separate story, told in clearing inherited trust liabilities.
What was the situation?
An existing business with real lead flow that could not be interrupted, a WordPress stack that could not be frozen for a rebuild, and a knowledge surface that did not exist yet [our data]. The commercial constraint was the hard one: every week spent on a migration was a week not publishing, and the migration itself would risk a working funnel to gain nothing a reader would notice.
The conventional answer is a phased migration — export, rebuild, redirect, verify, repeat. Its honest problem is that the risky work happens first and the valuable work happens last. We wanted that order reversed.
How does one Worker put a new library on a domain you can't freeze?
By making origin selection a per-request decision, and by writing that decision as an allowlist rather than a fallback chain. The Worker names the paths the content project owns. Anything not on that list — including a path the Worker has never heard of — goes to WordPress with no probing, no extra round trip, and no new failure mode [our data].
| Request | Where it goes | Why |
|---|---|---|
| Any non-GET, non-HEAD method | WordPress | Live lead flow must never traverse a new layer |
| An allowlisted content prefix or named file | New static library | 12 path prefixes plus a short list of files the content project owns |
| A published pillar slug at the root | New static library | The slug list is generated from the content repo at deploy time |
| A slug that still exists as a live WordPress page | WordPress | Every WP page stays WP until its override is retired deliberately |
| Anything else | WordPress, untouched | The default has to be the origin that already works |
The direction of the default is the whole safety argument. A router that tries the new layer first and falls back on a 404 makes every unknown URL on the domain depend on the new deployment behaving correctly. A router that defaults to WordPress makes the new layer's blast radius exactly the list of paths someone wrote down [our data].
Google's Search Essentials sets the baseline a site has to meet to appear in Search at all, and a routing layer is only safe while it stays invisible against that baseline: same URLs, same crawlable HTML, no method-dependent surprises. That is also why the content layer ships as static HTML — the reasoning is in do AI crawlers render JavaScript.
Two details keep the crawl surface stable. The Worker deliberately does not claim /robots.txt or /sitemap.xml; WordPress keeps both, and the content sitemap is exposed on its own path and submitted directly instead [our data]. And the one redirect it issues is narrow — an un-slashed new content URL is 301'd to its canonical trailing-slash form. No existing WordPress URL is redirected.
Why do all non-GET requests bypass the new layer?
Because a form POST is revenue and a page request is not. Only GET and HEAD are eligible for the allowlist; every other method is pinned to WordPress, so the lead pipeline runs exactly as it did before the Worker existed, whatever the new layer is doing [our data].
This is the rule we would keep if we kept only one. Path patterns are easy to get subtly wrong — one that matches a form endpoint, an AJAX handler, or a webhook path is a routing bug that presents as lost leads, days later, with no error anywhere. Routing by method draws the boundary around the thing that must not break, rather than around a list of paths someone has to maintain.
Which way does a failure fall?
Toward the old site. If the static origin returns a 5xx, or the fetch throws or times out, the Worker re-fetches from WordPress and the visitor gets whatever WordPress would have said [our data]. That is the asymmetry worth copying: the new layer is allowed to be down, and the domain is not.
The exception is deliberate. A 404 from the static origin is passed through rather than retried against WordPress, because the request was already on an allowlisted content path — re-asking WordPress for a URL it never had would only produce its own 404 a round trip later.
What did the first two weeks actually produce?
Publishing started immediately and the cutover machinery waited, which was the whole design goal [our data]. On day 1 the Worker was deployed inert — live on the apex but not yet routing anything to the new library.
| Day | Date | What landed |
|---|---|---|
| 0 | 2026-08-05 | Research corpus synthesized; content engine's first commit; ~67 pages by end of day |
| 1 | 2026-08-06 | Adversarial review of the 67-page build; apex Worker deployed inert |
| 14 | 2026-08-19 | 298 content files against a ~365-URL architecture |
Deploying the router inert is the part worth copying. It separates "does the routing work" from "is the content ready," so cutover becomes a configuration change rather than a launch, and none of that 298-file growth was gated on migration risk [our data].
Deliberately absent from this record: any traffic, ranking, or revenue outcome. We have none to report for this build, and the arrangement — a live domain, a concurrent content build, a phase-0 cleanup in the same window — could not isolate one anyway. The reportable results are velocity, preserved function, and a cutover designed to be reversible.
Why does the noindex defense get two layers?
Because a single stray noindex at the apex is a site-wide outage that renders perfectly. Google documents noindex — as a meta tag or an X-Robots-Tag HTTP header — as the directive that keeps a page out of search results (Google, robots meta tag), and a header applied at the edge applies to everything behind it.
The AI-surface consequence makes it a monitoring priority rather than an SEO nicety. Google's AI features documentation ties AI Overview and AI Mode eligibility to pages being indexed and snippet-eligible, so a domain that drops out of the index drops out of Google's AI surfaces at the same moment — from one header, with no error page and no alert.
So the Worker handles it in-band and a monitor watches out-of-band. Every response the Worker proxies from the static origin has its x-robots-tag header deleted before it reaches the visitor — the staging platform sets that header, and the Worker's own code calls it the single most dangerous header on this architecture. The hourly external check covers what the strip cannot: a plugin, a theme, a CDN rule, or a meta tag inside the HTML [our data]. Both are precautions, not incident reports. This build's record documents the defenses, not a leak.
What is the generalizable rule?
Put the router in front of the domain, ship it inert, default it to the origin that already works, and route by method as well as by path. The rule underneath all four: a content layer should be able to fail without the business failing, which means keeping the money paths — and every path nobody has thought about — out of the new layer entirely.
The rollback story is the design constraint that makes the rest defensible. The cutover was designed as a roughly 15-minute procedure that reverses by greying the DNS records, putting the domain back exactly where it was [our data]. Be exact about what that number is: it comes from the build's cutover plan. We did not time the executed cutover and no stopwatch record exists — so it is a design target, not a measurement we can show you.
Against our own interest: this is plumbing, and plumbing earns nothing. The Worker is a permanent extra moving part in front of a live business, it adds an origin-selection bug class that did not exist before, and no reader will notice it. If you can freeze the site and rebuild it properly, do that. If the existing CMS can host an answer-first library without fighting you, use the CMS — the cluster design in how to structure a content library is platform-agnostic and matters far more than where the pages are served from. We reach for a Worker in one situation only: when the alternative is publishing nothing for six months.
The wider system this routing layer serves — research, contract, gates, measurement — is described in the authority engine, and the reason any of it is pointed at answer engines in the first place is laid out in the guide to generative engine optimization.
Frequently asked questions
How do you add a citable content layer to a site you can't rebuild?
Put a router in front of the domain instead of migrating it. On our auto-finance rebuild one Cloudflare Worker on the apex holds an explicit allowlist of content paths that go to a new static library, and passes everything else to WordPress untouched, so no existing URL changed and the CMS was never edited [our data].
Does this change any existing URLs?
No existing WordPress URL changes — the address bar for pages that already existed is untouched, and any path the Worker does not recognize goes to WordPress with no probing. The Worker does issue one class of 301: an un-slashed form of a new content URL is redirected to its canonical trailing-slash form, so the new library has one address per page [our data].
What happens to forms and lead capture?
Nothing. Only GET and HEAD requests are eligible for the new layer; every other method is pinned to WordPress, so form POSTs never enter it. On our auto-finance rebuild that rule is what let a converting funnel keep running untouched while the knowledge surface moved [our data].
What happens if the new static layer breaks?
The failure falls toward WordPress. A 5xx from the static origin, or a thrown error or timeout reaching it, is answered by re-fetching from WordPress instead. A 404 from the static origin is passed through as a 404, because on an allowlisted content path a missing page is a better answer than an error page [our data].
Why monitor for a noindex header?
Because one wrong header at the apex is a site-wide outage you cannot see. Google documents noindex as keeping a page out of search results, and its AI features documentation ties AI Overview and AI Mode eligibility to being indexed and snippet-eligible — so the same header removes both at once. The Worker strips that header from every response it proxies, and an external monitor checks hourly in case something else sets it.
Is a routing layer better than migrating properly?
Usually not. A Worker is a permanent moving part in front of a live business and it earns nothing on its own. It buys one thing: the right to start publishing now instead of after a six-month rebuild [our data].