Webmasters Stack Exchange is a question and answer site for pro webmasters. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have inherited a Sitecore architecture that is a mess from an SEO duplicate content POV.

There are multiple aliases that have been created (and indexed by the search engines) for many of the 2nd tier pages of the site.

Due to server issues, I am not able to 301 redirect these duped pages, so I would like to use the rel=canonical tag in an attempt to try and get Google/Bing to recognize the correct pages I would like to appear in the index.

I have blocked the most extraneous duped pages with a robots.txt file, however, since Google/Bing have already spidered many of the duped pages, I need to keep them accessible to the spiders, BUT removed from the index.

The catch is, since the duped pages are aliases (and don't really physically exist in Sitecore that I can find), I am not sure how to go about using rel=canonical - or if I even can in this situation..?

share|improve this question

migrated from stackoverflow.com Nov 17 '11 at 11:42

This question came from our site for professional and enthusiast programmers.

This probably belongs over on webmasters or superusers, unless you have a programming related question in here. – Mech Software Nov 16 '11 at 16:30
Not sure I agree with the move... it is a code related solution. – Sean Kearney Nov 17 '11 at 14:51

Mike, I think the easiest, and first place, I would start is to modify your Layout (.aspx) such that pages using an alias have the <link rel="canonical" href="..."/> in the head.

You can leverage code provided with this answer to help you.

Essentially, add a asp:Literal to the <head> of your .aspx page. Now, on Page_Load of your .aspx.cs you can do the following

if (global::Sitecore.Configuration.Settings.AliasesActive && global::Sitecore.Context.Database.Aliases.Exists(System.Web.HttpContext.Current.Request.RawUrl))
    const string format = "<link rel=\"canonical\" href=\"{0}://{1}{2}\"/>";
    global::Sitecore.Data.Items.Item targetItem = global::Sitecore.Context.Database.GetItem(global::Sitecore.Context.Database.Aliases.GetTargetID(System.Web.HttpContext.Current.Request.RawUrl));

    canonicalLiteral.Text = string.Format(format, "http", System.Web.HttpContext.Current.Request.Url.Host, global::Sitecore.Links.LinkManager.GetItemUrl(targetItem));

Note, you may need to adjust that based on the configuration of your LinkManager.

share|improve this answer
Great solution! – Mark Ursino Nov 16 '11 at 17:37

Regardless of whether or not an item has any aliases, you will most likely need the canonical URL of the context item anyway; Therefore, the solution is even simpler:

var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
canonicalLiteral.Text =
Sitecore.Links.LinkManager.GetItemUrl(Sitecore.Context.Item, options);
share|improve this answer

Use Sean's answer, but I would use LinkManager to build the entire url:

var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
canonicalLiteral.Text = LinkManager.GetItemUrl(global::Sitecore.Links.LinkManager.GetItemUrl(targetItem));
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.