Monday, January 11, 2021

Sitecore personalization with device detection

Sitecore device detection personalization rules

I had a request from a content editor to add a different (large) image to a page depending on the device - on smaller screens it had to be a completely different image that was better suited. So the normal approach of a responsive image didn't work here as the image source was different and not just the size.



A first test was made by using the grid options provided by SXA. This way the editor can add both images and select when they should appear by setting the visibility as none on the unwanted devices per image.

Although this works on first sight, there is something that made us not use this - browsers will load both images even if they are marked not to be displayed by css. As we are trying to find a solution to have better mobile experience, this is not what we want.


Sitecore personalization - "where device type is value"

Out of the box Sitecore has some personalization rules that work with the device detection. As mentioned in the documentation we can use this to set up personalization targeting users differently based on their device. Many rules are available and documented. The screen size rules might seem an option, but those are not very easy to configure to detect what we wanted. A better suited rule would be the check on device type: "where device type is value". 

But.. although it is still in the documentation and screenshots, we couldn't find that rule. With the Sitecore search we did find it - in a section with obsolete rules :(  There is another -very similar- rule now though: "where device type is one of". This does almost the same but you can give a list of device to match - which seems even better! 

When testing the rule we found something weird though.


Where device type is one of

I created a page with a simple component and two datasources, one with the desktop image and one with the mobile image. When we tested this it worked once, but most of the time it didn't. We were using the Chrome developer tools device simulator as we didn't have access to the test environment with a mobile phone. I started the investigation with a look in the code.   

I started by checking the DeviceTypeCondition in the CES assembly, but that is marked obsolete (just as the item in Sitecore) - we should check Sitecore.ContentTesting.Rules.Conditions.DeviceTypeCondition instead. 

This new version of the rule has some twists however that seemed weird. When I debugged this code I noted that the cast from ruleContext to DeviceRuleContext always failed and in the RuleDeviceInformationManager this leads to a fallback mechanism - the getFallbackUserAgent pipeline.
DeviceRuleContext deviceRuleContext1 = ruleContext as DeviceRuleContext;
if (deviceRuleContext1 != null)
{
    ...
    string deviceRuleContext2 = this.GetUserAgentFromDeviceRuleContext(deviceRuleContext1);
    ...
    return ...
}
GetFallbackUserAgentArgs args = new GetFallbackUserAgentArgs();
GetFallbackUserAgentPipeline.Run(args);
When I checked the pipeline I found one processor: GetUserAgentFromTracker. And then it made sense to me...
The rule is getting the user agent from the tracker and not from the request - so the first call in the session determines the device.


Problem?

Although it is very weird that a piece of code always seems to go into what is called a fallback, is this actually a problem? Sitecore support thinks not - I think it is. I added a proposal to the Sitecore product ideas portal where you can upvote it if you agree...

So why is this a problem for me? My editors want to test their setup before going live. The site has a preview target where this can be accomplished but that preview target is (obviously) not publicly available. To properly test some content an editor would have to connect their mobile devices with a VPN or such and that is not that simple within some companies. It is much easier to use simulator tools like the one in Google Chrome. To use those however, one would have to clear all the site cookies before switching devices. This is possible... but with all due respect to editors, I think it wouldn't take that long before we get a request for help because the device rule is not working...

And what happens when there is no tracker? With all privacy regulations in place these days one cannot assume we do have a tracker.

The fix

We could create our own custom version of the rule - this works but we did bump into obsolete Sitecore code. It's an option - not sure whether it is a good one.

 Another option is to use the pipeline. Adding another processor before the tracker fallback will do the trick as well. For now I couldn't find any other usage except for the device rules so we might "fix" more than one...  

 Pipeline code

public class GetUserAgentFromContext : Sitecore.CES.DeviceDetection.Pipelines.GetFallbackUserAgent.GetFallbackUserAgentProcessor
{
    protected override string GetUserAgent()
    {
        return HttpContext.Current?.Request.UserAgent;
    }
}
<sitecore>
   <pipelines>
     <getFallbackUserAgent>
       <processor patch:before="*[1]" type="Feature....GetUserAgentFromContext, Feature..." />
     </getFallbackUserAgent>
   </pipelines>
</sitecore>
I've placed my processor first to keep the tracker as the fallback. If the context code found a useragent the other processors won't do anything anymore - if not, they will still do their job.




No comments:

Post a Comment