In our Sitecore 10.2 XM SXA website, the canonical URLs are not being generated properly - the domain name gets appended twice -

Screenshot of canonical tag

<link rel="canonical" href="https://prod.*******.orghttps://prod.*******.org/locations">

We have used OOTB Canonical URL rendering to add canonical URLs, added this rendering in our metadata partial.

Strangely, this issue occurs only in our PROD instance, it generates the correct URL in local and QA environments. Even shows the correct URL in PROD CM Experience Editor.

We have two Site Definition items in our Site Grouping - one for CM and the other for CD. I have compared the Site Definitions of all the instances, everything looks fine.

Unable to pin the cause or find a fix for this issue. Any help would be appreciated.

2 Answers 2


I have seen this happening when you have multiple site definitions. If you have multiple site definition items under Site Grouping, then I would suggest to keep only required one and mark rest others as non-publishable. In your case,

  • You can mark CM definition item as unpublishable and then publish Site Grouping Node. (You can make sure that other definitions are removed from Web database.)
  • Clear cache and rebuild index as well.

If that works, please revert all your changes and see if that works again.

Though this sounds strange, I never got time to dig deep into its real cause. I suspect this is due to the sequence these definition items are indexed in. I would recommend to keep one site definition per site.

  • 1
    Surprisingly, unpublishing the CM Site Definition worked. I republished it again as you mentioned and the URLs are still correct. Thank you for the help. However I do have a concern about this issue re-appearing, how can I make sure that this won't happen again?
    – Neha Pasi
    Jul 26, 2023 at 11:16
  • I don't have a solid answer to this, may be redo all the steps again. As mentioned in answer, I could not check more details on this. I could neither find any such case on google, this was all trial-n-error. Jul 26, 2023 at 11:36

PS: I'd like to share some relevant information related to site resolving in sxa as an answer.

The site resolution sequence in SXA is important. Many SXA components use SiteInfoResolver to determine the site, and the results may differ from Sitecore.Context.Site. The resolver verifies the path, language, and internal status first. If a this match is found it skip check for Context.Site.Name (in the next statement). It returns the first matching site, regardless of whether it is in a Content Management (CM) or Content Delivery (CD) context - which could be causing your problem.

To implement a quick fix, try modifying the site sequence and unpublish cm-site as answer given above.

If changing the sequence is not possible for any reason, as in my case. You can construct a custom site resolver by overriding public override SiteInfo GetSiteInfo(Item item, Func<SiteInfo, bool> sitesFilter).

Replace the default SiteResolver with your own implementation.

<register serviceType="Sitecore.XA.Foundation.Multisite.ISiteInfoResolver, Sitecore.XA.Foundation.Multisite" implementationType="Sitecore.XA.Foundation.Multisite.SiteInfoResolver, Sitecore.XA.Foundation.Multisite" lifetime="Singleton" patch:source="Sitecore.XA.Foundation.Multisite.config"/>

In my case, when I moved CD to the top, all internal links of the CM website were pointing to the CD. However, when I kept CM at the top, Coveo indexes were indexing wrong URLs for CD items (it was taking CM-site urls for CD-site pages).

//Added custom site info logic before existing logic
            SiteInfo siteInfoCustom1 = siteInfoArray.FirstOrDefault(s => Context.Site != null && s.Name.Is(Context.Site.Name) && PathMatch(s, item) && LanguagesMatch(s, item) && !s.IsInternal);
            if (siteInfoCustom1 != null)
                return siteInfoCustom1;

            SiteInfo siteInfoCustom2 = siteInfoArray.FirstOrDefault(s => PathMatch(s, item) && LanguagesMatch(s, item) && !s.IsInternal && DatabaseMatch(s, item));
            if (siteInfoCustom2 != null)
                return siteInfoCustom2;

The first logic siteInfoCustom1 helps to resolve site by matching both item's path and Context.Site. The second siteInfoCustom2 by matching path and database which is for indexing jobs that may run under Sitecore's system SiteContext.

protected bool DatabaseMatch(SiteInfo site, Item item)
            string siteDatabase = site.Database;
            return item.Database.Name.Equals(siteDatabase, StringComparison.InvariantCultureIgnoreCase);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.