Introducing UI Theme Detection for Lightning Experience

With Winter ‘16, Salesforce introduced Lightning Experience. To provide a more streamlined user experience, you can now use Lightning Components and the Lightning Design System, as well as Visualforce. Using these tools you can create components that are reusable across applications and devices. These new options created an opportunity for customers and partners alike to revisit their applications to use this exciting new technology.

Back in December, our ISV Technical Enablement team launched a series of webinars around transitioning applications to Lightning. If you’re interested in developing Lightning Ready applications, watch the webinar recordings here.

However, with the initial launch of Lightning Experience developers had no way to build pages and components that dynamically react to the UI theme that the user is currently using.

Great news! With the Spring ‘16 release, Salesforce provides an easy and robust way for developers to detect the user’s UI theme.

UI Theme Detection in Spring ‘16

UI Theme Detection can be done in one of two ways:

  • Accessing global variables:
    • $User.UITheme – Returns the theme that is supposed to be used.
    • $User.UIThemeDisplayed – Returns the theme that is actually being used.
  • Calling Apex utility methods:
    • UserInfo.UITheme() – Returns the theme that is supposed to be used
    • UserInfo.UIThemeDisplayed() – Returns the theme that is actually being used

Why does Salesforce provide both the UITheme and UIThemeDisplayed methods? If users with Lightning Experience permissions are using an unsupported browser, they may experience Salesforce rendered in Salesforce Classic. If this happens, UITheme and UIThemeDisplayed return different values.

Note: Detecting the UI context via a server call is expensive, and should therefore be cached or carefully isolated into init or startup methods(see Apex utility sample below). This will prevent utility being called every time the component is rendered. If you only need to distinguish between Lightning Experience and Salesforce1, check out $Browser.

The string value stored in these variables or returned by these methods is one of the following:

  • 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

Detecting UI Theme Using Global Variables

Visualforce pages can use global variables to determine the UI theme in use without resorting to Apex. Look at the following Visualforce page.

<apex:page>
<apex:stylesheet value="{!URLFOR($Resource.slds, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
    <apex:outputPanel rendered="{!$User.UIThemeDisplayed == 'Theme3'}">
        <apex:pageBlock title="Visualforce (Using standard Visualforce Components)" mode="detail">
            <apex:outputLabel value="UI Theme Detection using Global Variables: {!$User.UIThemeDisplayed}"/>
        </apex:pageBlock>
    </apex:outputPanel>
    <apex:outputPanel rendered="{!$User.UIThemeDisplayed == 'Theme4d'}">
       <div class="slds">
    <div class="slds-card slds-card--empty">
  <div class="slds-card__header slds-grid grid--flex-spread">
    <h2 class="slds-text-heading--small slds-truncate">Visualforce (Using HTML + SLDS)</h2>
  </div>
  <div class="slds-card__body slds-p-horizontal--small">
    <h3 class="slds-text-heading--small slds-p-top--large slds-p-bottom--large">UI Theme Detection using Global Variables: {!$User.UIThemeDisplayed}</h3>
  </div>
</div>
    </div>
    </apex:outputPanel>
</apex:page>

Using the global variable $User.UIThemeDisplayed, it detects which UI theme is being used. Based on the theme detected it dynamically renders a page that is adapted to either Salesforce Classic 2010 (using Visualforce Components) or Lightning Experience (using HTML + Lightning Design System). We could add other conditions (or a default condition) to capture additional scenarios.

Visualforce page rendered in Salesforce Classic:

Visualforce Page rendered in Lightning Experience:

Detecting UI Theme Using Apex Utility Methods

You can’t determine the user’s UI theme directly within a Lightning Component because it only has access to a limited set of global values. You must implement an Apex server-side controller to provide this information.

We provide three pieces of sample code that demonstrate how you get the UI theme information you need into a component responsible for rendering UI. The basic flow is:

  1. Component invokes client-side controller.
  2. Client-side controller invokes Apex server-side controller.
  3. Apex server-side controller determines theme information.
  4. Apex server-side controller returns theme information to client-side controller.
  5. Client-side controller sets values for component.
  6. Client-side controller returns control to component.
  7. Component uses theme information to render correct output.

Client-side controller

({
    doInit : function(component, event) {
        var action = component.get("c.getUIThemeDescription");
        action.setCallback(this, function(a) {
            component.set("v.Name", a.getReturnValue());
            if(a.getReturnValue()=='Theme3' ||'Theme2'){
                component.set("v.Desc", "Lightning Components can be rendered in Salesforce Classic using Lightning Components for Visualforce");
component.set("v.isLEX",false);
            }else if(a.getReturnValue()=='Theme4d'){
                component.set("v.Desc", "Lightning Components can be rendered natively within Lightning Experience or, alternatively, within a Visualforce Page or within a Lightning Application.");
component.set("v.isLEX",true);
            }else if(a.getReturnValue()=='Theme4t'){
                component.set("v.Desc", "Salesforce1 Mobile natively supports Lightning Components");
component.set("v.isLEX",false);
            }
        });
        $A.enqueueAction(action);
    }
})

Server-side Apex controller

public with sharing class UIThemeController {
   @AuraEnabled
    public static String getUIThemeDescription() {
        String theme = UserInfo.getUiThemeDisplayed();
        return theme;
    }
}

Lightning Component

<aura:component implements="flexipage:availableForAllPageTypes" controller="UIThemeController" access="global">
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:attribute name="Name" type="String" />
<aura:attribute name="isLEX" type="Boolean" />
<aura:attribute name="Desc" type="String" />
    <div class="slds">
    <div class="slds-card slds-card--empty">
  <div class="slds-card__header slds-grid grid--flex-spread">
    <h2 class="slds-text-heading--small slds-truncate">Lightning Component</h2>
  </div>
  <div class="slds-card__body slds-p-horizontal--small">
    <h3 class="slds-text-heading--small slds-p-top--large slds-p-bottom--large">Detected Theme: {!v.Name}</h3>
    <h2 class="slds-text-heading--small slds-p-top--large slds-p-bottom--large">{!v.Desc}</h2>
<aura:if isTrue="{!v.isLEX}">
<p>This text is only displayed in Lightning Experience</p>
<aura:set attribute="else">
     <p>This text is only displayed outside of Lightning Experience</p>
    </aura:set>
</aura:if>
  </div>
</div>
    </div>
</aura:component>

If you want to try out the code yourself in Salesforce Classic, see Lightning Components for Visualforce.

Lightning Component rendered in Salesforce Classic

Lightning Component rendered in Lightning Experience:

Recommendations and Best Practices

Use the following recommendations and best practices for using UI Theme Detection in both Lightning Components and Visualforce.

Lightning Components

We recommend that you use Lightning Components as much as possible as you build out new UI. You can use Lightning Components within Salesforce Classic by using the steps outlined here. You can also use Lightning Components natively in Salesforce1 Mobile and Lightning Experience.

Here are some use cases for UI Theme detection in Lightning Components:

  • Display a simplified user interface in Salesforce1 Mobile, while using additional available screen real estate in the Desktop
  • Use SLDS within Lightning Experience and use a custom CSS within Salesforce Classic
  • Load different sets of child components for Salesforce Classic and Lightning Experience

Imagine you have a progress bar designed for Lightning Experience and another progress bar designed for Salesforce Classic. Putting your UI Theme detection at the facet level allows the facet to determine which of these lower-level components to invoke.

Visualforce

With the updated UI Theme Detection in Spring ‘16, you can now build Visualforce pages that dynamically adapt to Salesforce Classic, Lightning Experience, or Salesforce1 Mobile.

So why use UI Theme Detection for Visualforce pages now? The main advantage is that UI Theme Detection provides additional options:

  • You can build pages that fully use the Lightning Design System and the various design tokens we are continuously pushing to SLDS
  • You can use an extended version of the Lightning Design System that better reflects your brand
  • You can use your own custom design system

Visualforce pages containing standard Visualforce components retain the Salesforce Classic look-and-feel, even when displayed in Lightning Experience. We expect this to remain true for the foreseeable future.

Customers who want pages that adapt to their user experience context can use UITheme detection to do so. You can use UITheme detection to render standard components when in Salesforce Classic, and to render new content based on HTML, JavaScript, and the Lightning Design System when in Lightning Experience. You can make use of the flexible Visualforce component, which takes styling well, or you can make use of Lightning Components for Visualforce. The latter option offers easy entry into the world of Lightning Components, if you’re looking a way to get started there.

If you plan to use the SLDS, we recommend keeping all the same html element IDs. Once the Lightning Design System is available on platform, your UI can access those tags automatically with the latest SLDS.

Summary

We continue to invest in making Lightning Experience and Salesforce1 Mobile the best they can be. With these changes to UITheme and UITThemeDisplayed, you can make your applications more dynamic and responsive to the various UI themes we are providing to customers. We look forward to seeing many more applications that use these exciting technologies!

About the Authors

John Belo & William Yeh are ISV Technical Evangelists here at Salesforce, they work with ISV Partners developing business solutions on the Salesforce AppCloud.
in/johnbelo | twitter: @johnbelo
in/yehwilliam | twitter: @wwilliam89

 

Published
April 13, 2016

Leave your comments...

Introducing UI Theme Detection for Lightning Experience