0

I'm working on Canonical implementation on SXA, Sitecore 10.2. Self referencing canonical is working fine, So I have a doubt on Multi language Canonical url. I have a page like this one www.myhome.com/en/page1 . I have similar content in FR,DE,CA languages, so I would like to add these three URL in my Page 1 .I am expecting to deliver

 <link rel="canonical" href="https://www.myhome.com/en/page1"/>
 <link rel="canonical" href="https://www.myhome.com/FR/page1"/>
 <link rel="canonical" href="https://www.myhome.com/DE/page1"/>
 <link rel="canonical" href="https://www.myhome.com/CA/page1"/>

Is there any best practice to achieve this, I have to give the option to my content Author to choose the canonical page in backend. There is no OOTB available for this. Please give some suggestions on it.

1
  • First of all - you need to use alternates as mentioned in the answer below. And one more question: why do editors need to choose those pages? Are these translations of the same item? Or other items? ...
    – Gatogordo
    Mar 3, 2022 at 11:09

2 Answers 2

2

If I understand well, you have the same content but just translated on many languages. For my point of view, it would be better to use alternate to manage hreflang.

For example:- For Switzerland website with fr-ch and de-ch languages. When you call https://yourwebsite.com/fr-ch/solutions.

HTML generated should look like this :

<link rel="canonical" href="https://yourwebsite.com.com/fr-ch/solutions" />
<link rel="alternate" href="https://yourwebsite.com.com/fr-ch/solutions" hreflang="fr-CH" />
<link rel="alternate" href="https://yourwebsite.com.com/de-ch/loesungen" hreflang="de-CH" />

Please don't hesitate to tell me if it answers to your question ?

Thanks!

0

Cannot agree more with Accepted answer, in addition to this sharing details here on one of my recent working implementations which might be helpful as well:

You could still make use of OOTB Canonical Rendering to achieve the first line of HTML without manipulating the OOTB implementation and ensuring it works for other sites (single lang etc).

<link rel="canonical" href="https://yourwebsite.com.com/fr-ch/solutions" />

However for the alternatives -> create a new custom rendering which could be cloned from Canonicals named CanonicalAlternatives:

  1. Add a new Site Configuration property allowedLanguages which can be added to SXA site under Site groupings Other Properties, which is a list of comma separated allowed Site languages for your site which exists for a given site. ex: fr-ch and de-ch in your case.(It is good to have this config as although you may check if version or language item exists , this config allows you to restrict alternatives to your site especially when adding new languages which are yet to be tested).
  2. Then in repository I would grab all languages and process the allowed languages only to generate the Href(full link language URL) and HrefLang for my alternates through Link Manager (code below).
  3. Add this cloned Rendering(CanonicalAlternatives.cshtml) to the metadata partial design after Canonical (Head placeholder) so that it emits the alternatives.

Ex View cshtml

@model CanonicalAlternates

@foreach (var item in Model.Items)
{
<link rel="alternate" href="@item.Href" hreflang="@item.HrefLang" />
}

Repository (example for demo)

public CanonicalAlternates GetModel(){
            var model = new CanonicalAlternates();
            using (new EnforceVersionPresenceDisabler())
            {
                var item = _context.Item;
                if (item == null)
                {
                    return;
                }

                var urlOptions = GetUrlOptions();

                var langs = item.Languages
                           .OrderBy(x => x.CultureInfo.Name)
                           .ToList();
                var allowedLanguages = //Get List of AllowedLanguages List from Site Properties ex: site.Properties["allowedLanguages"] split by comma and get range -> fr-CH, de-ch;

                foreach (var language in langs)
                {
                    if(!allowedLanguages.Contains(language.Name, StringComparer.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    var item2 = item.Database.GetItem(item.ID, language);
                    if (item2 != null && item2.Versions.Count > 0)
                    {
                        urlOptions.Language = language;
                        var fullLink = LinkManager.GetItemUrl(item2, urlOptions);//get full url along with scheme and targethostname 
                        var hrefLang = //Get hrefLang from Language Item, you could store this in Display Tag item on Language for ease of use to get actual language tag
                        model.Items.Add(new CanonicalAlternate
                        {
                            Href = href,
                            HrefLang = hrefLang
                        });
                    }
                }
            }
            return model;
        }
//Model ***CanonicalAlternates*** is List of ***CanonicalAlternate*** which has Href and HrefLang Properties
ex: 

This would generate the alternates as below

<link rel="alternate" href="https://yourwebsite.com.com/fr-ch/solutions" hreflang="fr-CH" />
<link rel="alternate" href="https://yourwebsite.com.com/de-ch/loesungen" hreflang="de-CH" />

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.