[SalesForce] What’s the expected behavior of UserInfo.getUIThemeDisplayed()

Looking for clarification around the getUIThemeDisplayed() method. I have simple VF page that displays the value returned by this method from a corresponding controller and a lightning component on the same VF page that also shows the value returned from the method from the same controller.

When in SF classic I'm seeing both the VF page and Lightning Comp returning Theme3 (SF Classic). So far so good. But when I switch (via the menu) to LEX and go to the VF page, the VF page shows Theme3 (Classic) and the component returns Theme4d (LEX).

Example VF Page

<apex:page controller="ThemeTestController" showHeader="true">

    <apex:includeLightning />
    Theme returned by VisualForce page: {!UIThemeValue}

    <div id="lightning" />

    <script> 
        window.onload = function(){
            $Lightning.use("c:TestApp", function() {

                $Lightning.createComponent("c:ThemeTestCmp",
                {},
                "lightning",
                function(cmp) {
                });
            });
        }
    </script>

</apex:page>

Documentation states these variables Identify the CSS used to render SF web pages to a user, so if the component utilizing Lightning CSS and the VF still uses classic CSS hence the different values displayed? And if so, why do we see both the VisualForce page and component display Theme3 when in classic?

Best Answer

There is a nice trailhead Sharing Visualforce Pages Between Classic and Lightning Experience on this to answer your question.

Use the $User.UITheme and $User.UIThemeDisplayed global variables to determine the current user experience context. You can use these variables in Visualforce expressions to adapt your pages to Lightning Experience, Salesforce Classic, and Salesforce1.

These global variables return a string that uniquely identifies the current user interface context. The possible values for $User.UITheme and $User.UIThemeDisplayed are the same:

  • Theme1—Obsolete Salesforce theme
  • Theme2—Salesforce Classic 2005 user interface theme
  • Theme3—Salesforce Classic 2010 user interface theme
  • Theme4d—Modern “Lightning Experience” Salesforce theme
  • Theme4t—Salesforce1 mobile Salesforce theme
  • PortalDefault—Salesforce Customer Portal theme
  • Webstore—Salesforce AppExchange theme

Question: When in SF classic I'm seeing both the VF page and Lightning Comp returning Theme3 (SF Classic). So far so good. But when I switch (via the menu) to LEX and go to the VF page, the VF page shows Theme3 (Classic) and the component returns Theme4d (LEX).

The difference between the two variables is that $User.UITheme returns the look and feel the user is supposed to see, while $User.UIThemeDisplayed returns the look and feel the user actually sees. For example, a user may have the preference and permissions to see the Lightning Experience look and feel, but if they are using a browser that doesn’t support that look and feel, for example, older versions of Internet Explorer, $User.UIThemeDisplayed returns a different value.

And, here this is happening for you.

In general, your code should use $User.UIThemeDisplayed. The simplest way to use these theme globals is to use one in a Boolean expression, like {! $User.UIThemeDisplayed == "Theme3" }, in the rendered attribute of a component. The component will only display if the page appears in the desired user interface context.

// This is an anonymous self-executing function closure thingie,
// like all the cool kids are using these days.
(function(myContext){

    // Deal with possible order-of-execution issues.
    // Don't overwrite ourself if we already exist.
    myContext.ForceUI = myContext.ForceUI || {};

    // Utility methods that make simple string comparisons
    // against a local UserUITheme value. This value is
    // injected from a Visualforce page to allow expression
    // evaluation of the $User.UIThemeDisplayed global.
    myContext.ForceUI.isSalesforceClassic = function() {
        return (this.UserUITheme == 'Theme3');
    }
    myContext.ForceUI.isLightningExperience = function() {
        return (this.UserUITheme == 'Theme4d');
    }
    myContext.ForceUI.isSalesforce1 = function() {
        return (this.UserUITheme == 'Theme4t');
    }
})(this);
Related Topic