Navigating Between Sites in a Sitecore Multisite Solution: Creating a "Back To Referrer" button and translating text

Pretty much all of the Sitecore websites I work on are multisite solutions which consist of a primary website and a number of microsites. While the primary website and the microsites are mostly independent of each other, there are occasionally links that take the user from a microsite to the main website, or vice versa. Because the microsites have different navigation menus from the primary site, the only way to get back to the previous site is for the user to click the "back" button. In order to improve the user experience, several of my clients have recently requested that a link or button display on the page when the user goes from one site to another that will take them back to the previous site. The conditions are as follows

  • Show the button when:
    • User goes from one site to a different site within the Sitecore instance
  • Do not show the button when:
    • User goes to another page within the same site
    • User enters site from an external source (e.g. Google)

The way I chose to implement this was to use HttpContext.Current.Request.UrlReferrer. I compare this to HttpContext.Current.Request.Url.Host; if they are different, check if the UrlReferrer.Host is one of our internal sites; and if so, display the button (with the text "Back To {UrlReferrer.Host}."

There are several different ways to get the domains of your internal sites. The easiest one is to use Sitecore.Configuration.Factory.GetSiteInfoList(). This returns all of the SiteInfo items for your Sitecore instance. I've used that method in the following code snippet:

    public bool ShowBackToReferrer
    {
        get
        {
            var referrer = HttpContext.Current.Request.UrlReferrer;
            if (referrer == null) return false;
            var domain = HttpContext.Current.Request.Url.Host.ToLower();

            var referrerDomain = referrer.Host.ToLower();
            if (referrerDomain == domain) return false;

            return GetReferrerSite(referrerDomain) != null;
        }
    }   	
    private SiteInfo GetReferrerSite(string domain)
    {
        var sites = Sitecore.Configuration.Factory.GetSiteInfoList();
        return sites.FirstOrDefault(x => x.HostName.ToLower() == domain.Replace("www", "*"));
    }

There are a few things to note here:

  1. In my configuration, my hostNames begin with * to allow for the domain to work both with and without www (and redirect to www) in Azure. To handle that, if the referrer domain in the request begins with "www," it gets replaced with "*" so that it will match the hostName in the configuration.
  2. All of the microsites should have hostName defined. However, I discovered while debugging that my primary website in one of my projects did not have the hostName set. The linq statement to find the site whose hostName matches the referrer host will not work if the hostName property is not set. You can add the hostName property for the "website" site, or you can manually get the primary website domain from your appSettings as shown in the next snippet.

You can always get the hostNames manually, using properties in the appSettings or hardcoding the names

return (domain == WebConfigurationManager.AppSettings["Hostname"] ||
       domain == WebConfigurationManager.AppSettings["MicrositeHostname"]) ||
       domain == "OtherMicrosite.com";

Note however that you will have to change the code if a new site is added. (This example also assumes that you have "Hostname" and "MicrositeHostname" properties in your <appSettings>).

A few more methods to generate the button link and text:

public Uri GetReferrer
    {
        get
        {
            if (HttpContext.Current.Request.UrlReferrer == null)
                return "";

            return HttpContext.Current.Request.UrlReferrer;
        }
    }

Then the button is simple:

@if (Model.ShowBackToReferrer)
{
    <a href="@Model.GetReferrer.ToString()">Back To @Model.GetReferrer.Host</a>
}

But let's make things more complicated!

In one of my projects, each site is in a different language. Sure, we could just display "Back To {Referrer}" for each one, but it would be nicer to display the text in the language the user speaks. So, if the user was on the Spanish microsite and clicked a link to the English site, it would make sense to display "Back to SpanishSite.com" in Spanish instead.

I already do all of our translating using Sitecore's dictionary items and the handy Translate.Text()method. I created a new dictionary item with the key "Back To", and added each language version. The trick here is that we need to translate into a different language than the current site language, and Translate.Text() translates the text into the language of the current site context. Therefore, I instead used Translate.TextByLanguage()to translate the text into the language of the previous site.

The following method is used to get the link text in the appropriate language (using the previously defined GetReferrerSite method).

    public string BackToReferrerText
    {
        get
        {
            var refererrer = HttpContext.Current.Request.UrlReferrer.Host.ToLower();

            var domain = refererrer.Replace("www", "*");

            var referrerSite = GetReferrerSite(domain);

            if (referrerSite == null) return "Back To " + ReferrerUrl.Host;

            var referrerLang = referrerSite.Language;

            var backTo = "Back To";

            backTo = Sitecore.Globalization.Translate.TextByLanguage(backTo, Language.Parse(referrerLang));             

            var text = backTo + " " + ReferrerUrl.Host;
            return text;
        }
    } 

(Translate.TextByLanguage() is actually in a different namespace than Translate.Text(), so it was a bit tricky to find; Translate.Text is under Sitecore.Form.Core.Configuration, whereas Translate.TextByLanguage() is under Sitecore.Globalization).

So there you have it- an easy way to provide a button to take a user back to the previous site they were on, with the ability to translate the button text into a different language if necessary.