A fix for this went live last week - canonical URLs should now be properly working across the network. Canonicals are also the question, not per-answer which should clean up Google over time.
This won't be immediate as there are tens of millions of links to crawl, but I'm keeping an eye on their search console dashboards and trying to remedy what I can.
Some Details:
For the curious, the root of this was several issues that combined into craziness. Attempted fixes years ago for proper one-boxing of answers on various social platforms (which never actually worked when we dug in) was why canonicals were being set per-answer.
Additionally, a subtle and important behavior in ASP.NET MVC that we use is how ViewData
works. Due to the semantics of this collection being a copy-on-write dictionary, when we set a canonical on a top level .ViewContext.ViewData
, it should be set for the master layout view we're in. And that worked for many, many years. Until a call ahead of the canonical further down was added which caused that copy-on-write style dictionary fork in the view chain. This meant we wrote the canonical the master view should be using just fine, but it wasn't the same dictionary the master view was using anymore.
It's a crazy subtle behavior that's always been there, but it bit us here. One of the reasons my team is working hard on moving us to .NET Core (almost done for Q&A!) is the ability to have things like this in a test, and in a fully supported way. Testing views in MVC 5 is a nightmarish mess...but in Core it's beautiful. This will be one of the first tests we add to the new suite.
?rq=1
(e.g. google.com/search?q=asterism%20latex).?rq=1
and similar query parameters which cause the same problem.canonical
tags altogether, but I haven't yet found a post where that is explained. Anyways, at least the query parametersrq
,noredirect
,lq
etc. that apparently make no difference in content should be considered.rel="canonical"
is the only solution. But apparently nobody cares...