Smart homepage switching on HTTP accept-language headers

by Damiaan Peeters 1. December 2013 10:18

Http Headers

Every time time a browser requests a webpage from a web server, there are headers added to the the request.  Information like: Give me page X, I accept HTTP, you can Gzip or deflate data, proxy information, …

On of these http headers are the “Accept-Language” http headers.  So what does these headers mean?

Each language-range MAY be given an associated quality value which represents an estimate of the user's preference for the languages specified by that range.

If you open your browser hit F12, you can find for every request the headers back.  The accept language headers can look like this:

image

This means: I prefer Dutch, but will accept US English or any English dialect if available.  Every user can change the browser settings to reflect their language preference.

Sometimes – from a user design perspective, using the http headers to show understandable content to the user might be a good idea.  A lot of UX experts argue pro and/or contra.  We won’t go into the discussion because this is mainly a technical blog.  Let’s just try to implement it, because we can!  Glimlach

The solution

I’ll be using the IContentFinder for the solution. Never heard of the ContentFinderResolver?  Then read my previous blogpost or some official umbraco documentation.

I think that this is one of the cases where you can use IContentFinder to control what Umbraco serves to the rendering process.  We need to start with adding a new entry to the ContentFinderResolver.  This time we want it to be launched before the default umbraco implementation.  We can do this by using the following code:

ContentFinderResolver.Current.InsertTypeBefore<ContentFinderByNiceUrl, MyCustomHttpAcceptLanguageContentFinder>();

The rest of the idea is simple, for all root content nodes, search back the “Domain” object, and check whether the language matches.

try {
  string acceptLanguage = HttpContext.Current.Request.UserLanguages[0].Split('-')[0];
  string domainName = System.Web.HttpContext.Current.Request.Url.Host.ToLower();
  var rootDocs = UmbracoContext.Current.Application.Services.ContentService.GetRootContent();
  foreach (var rootDoc in rootDocs)
  {
    var domains = Domain.GetDomainsById(rootDoc.Id);

    var domainmatch = domains.FirstOrDefault(domain => domain.Language.CultureAlias.StartsWith(acceptLanguage));
    if (domainmatch != null)
    {
        contentRequest.PublishedContent = rootDoc;
        continue;
     }
  }
} catch {
  // search engines don't send language-accept headers
}

Attention, this is a very basic implementation and not ready for production at all! 

The SEO Warning

Like mentioned in the code: take care when implementing a solution using accept-language.  Googlebot is NOT sending any accept language headers along.  So be sure that you don’t get trapped in sending empty pages or (500) errors to the Search Engines.

With that I would like to ask, do you consider this as a valid use of IContentFinder?  What other Content Finders do you have in mind?  Have you already used the ContentFinderResolver?

blog comments powered by Disqus

Who.I.am

Certified Umbraco Master, Part of Umbraco Certified partner comm-it, .Net and Azure developer, seo lover. Magician in my spare time.

Month List