Canonical URL for Sitecore Items

Adding Canonical URL for Sitecore Item

SEO (Search Engine Optimization) best practice suggest you to use a single URL for a particular resource. Content with duplicate URLs are given lower rankings by crawlers and instead of using multiple canonical URLs and redirecting to it’s item URL to show in address bar for a particular resource, we should use search engine’s recommended canonical tag. This tag will be added in html head tag. It’s a link tag with rel=”canonical”. This rel property is used as a hint for crawlers to consider the actual URL of the resource and should be used in their indices for ranking purpose. Take a look at sample canonical tag.

<link rel=”canonical” href=”https://example.com/resource” />

How to add a canonical tag for sitecore Item?

To add a canonical tag for your sitecore item, use following code in your page load function in your layout file. This function will call GetCanonicalUrl() function to retrieve canonical URL for the current requested Item. The following code lines will create a tag with rel=”canonical” and add it into html head tag. Remember the head tag should be runat=”server” to access it in code behind.

var canonicalUrl = GetCanonicalUrl();
if (!canonicalUrl.IsNullOrEmpty())
{
var canonicalTag = new HtmlLink { Href = canonicalUrl };
canonicalTag.Attributes["rel"] = “canonical”;
Header.Controls.Add(canonicalTag);
}

Add the following GetCanonicalUrl() function in your same layout file to identify the canonical URL for current Item. Here in addition I have created a setting to ignore any number of trailing slash.

<setting name=”IgnoreTrailingSlash” value=”true”/>

The following function will retrieve the current sitecore item URL, if you are using the aliases in your site then it will resolve them also and will get existing item’s URL as your canonical URL.

/// <summary>
/// Retrieving canonical URL
/// </summary>
/// <returns>Link render in meta data</returns>
private string GetCanonicalUrl()
{
var request = HttpContext.Current.Request;
var uri = new Uri(request.Url, request.RawUrl);
string url = HttpUtility.UrlDecode(uri.AbsolutePath);
string baseUrl = uri.GetComponents(UriComponents.Scheme | UriComponents.Host, UriFormat.Unescaped);
string canonicalUrl = “”;
if (Sitecore.Configuration.Settings.AliasesActive && Sitecore.Context.Database.Aliases.Exists(url))
{
Sitecore.Data.Items.Item targetItem = Sitecore.Context.Database.GetItem(Sitecore.Context.Database.Aliases.GetTargetID(url));
canonicalUrl = string.Format(“{0}{1}”, baseUrl, Sitecore.Links.LinkManager.GetItemUrl(targetItem));
}

 string itemUrl = Sitecore.Links.LinkManager.GetItemUrl(Sitecore.Context.Item);

if (url != itemUrl)
{
canonicalUrl = string.Format(“{0}{1}”, baseUrl, itemUrl);
}

 var ignoreTrailingSlash = Sitecore.Configuration.Settings.GetSetting(“IgnoreTrailingSlash”);

if (!canonicalUrl.IsNullOrEmpty())
{
if (!ignoreTrailingSlash.IsNullOrEmpty() && ignoreTrailingSlash.Equals(“true”))
{
return canonicalUrl.TrimEnd(‘/’);
}
else
{
return canonicalUrl;
}
}
return null;
}