We run two websites. One for South Africa, one for everyone else. Same business, same writing, two front doors, and it made sense at the time for reasons I still think were correct.
Then I went looking at what a crawler outside South Africa actually sees, and found that every blog post I have written exists twice. Two full copies of the same inventory, on two different domains, and each copy carries a canonical tag pointing at itself.
A canonical tag is a page telling a search engine "this address is the original, index this one". Both copies were saying it. About themselves. Confidently.
Nobody decided this
That is the part worth writing down.
There was no meeting where we chose to duplicate the blog. There was a decision to have a local site and a global site, which is reasonable. There was a separate decision to publish posts through a pipeline that writes to both, which is convenient. There was a third decision, made by a default in a template, to have every page self-canonicalise, which is correct behaviour for a normal site.
Three sensible choices, none of which is wrong on its own. The problem only exists at the join, and nobody owns the join.
I have started to think this is what most technical debt actually is. Not bad decisions. Good decisions that were never told about each other.
Why I did not see it sooner
Because I looked from here.
I have written before about the geo-redirect that ate my Google rankings, where a rule sending international visitors to the global site also sent the crawler there, and I never noticed because I was testing from the one country the rule exempted. This is the same blind spot wearing a different coat.
From my chair, the local site loads, the posts are there, the canonical tag on the page I am looking at points at the page I am looking at. Everything checks out. The failure only appears when you stop asking "does my site work" and start asking "what does the visitor I never am actually get served".
That question keeps finding things. It found the redirect bug. It found this. I suspect it will keep earning its keep, which is annoying, because it is a question that only ever produces bad news.
What it costs
Honestly: probably less than the panic instinct says, and more than nothing.
Search engines have dealt with duplicate content for a very long time and mostly handle it by picking one version and ranking that. The risk is not a penalty. The risk is that the pick is theirs and not mine, and that the two copies split whatever authority the writing earns, so neither version is as strong as one version would have been.
What I object to is not the ranking effect. It is that I was not making the choice. Something was being decided about my business, repeatedly, by a default I never read.
What I am not doing
I am not fixing this in an afternoon, and I want to say why, because the instinct to just push something was strong.
The obvious move is to point every canonical tag at the local domain and be done. But the global site exists for a reason, some of its traffic is genuinely international, and I do not yet know what that change does to people who should be landing there. A quick fix to an SEO problem that quietly breaks the international path is not a fix, it is a trade I have not priced.
The options are roughly: pick one domain as the canonical home for all content, or keep both but make each canonical to a single chosen original, or split the content so the two sites stop overlapping at all. They have different costs and I am not the only person who should pick.
So it is written down, the diagnosis is in the log with the evidence attached, and it gets decided properly this week. Some things deserve a decision rather than a commit.
The lesson, if there is one
Every system I have broken this month, I broke in the space between two things that each worked.
The bugs that hid our own site were configuration meeting configuration. The redirect was a business rule meeting a crawler. The automation that missed a day was a schedule meeting an assumption about the machine being on. This one is a publishing pipeline meeting a template default.
Nothing in that list is a bug in a component. All of it is a bug in a seam.
I do not have a neat process for this yet. The closest thing I have is a habit: every time I add a second of something, a second domain, a second channel, a second copy of a workflow, ask what now exists in two places and which one is supposed to be the real one. If I cannot answer that, I have not built a system. I have built two things that happen to agree for now.
Frequently Asked Questions
What is a canonical tag? A line in a page's HTML telling search engines which address is the original version of that content. It exists so that identical pages reachable at different addresses do not compete with each other.
Why is the same content on two domains a problem? It usually is not penalised, but the search engine chooses which copy to show. If both copies claim to be the original, the choice is made for you, and any authority the content earns is split across two addresses instead of building on one.
How did you find it? By requesting the site as a crawler outside South Africa would, rather than as myself inside it. The same check that exposed an earlier redirect bug. Testing as the visitor you never are is the only way location-dependent behaviour shows itself.
Why not just fix it immediately? Because the international site exists for a reason and I have not yet worked out what redirecting its authority does to the people it serves. The diagnosis is documented and the decision is scheduled. Pushing a fix I cannot predict is not caution, it is just a different mistake.
More of the build, and the mistakes, at heinoux.nexbdm.co.za.