Explore the Visualforce App Container
- Describe three differences between Visualforce pages running in Salesforce Classic compared to the same pages running in Lightning Experience.
- Describe two common code patterns that need updating to work in Lightning Experience.
- List two changes to Visualforce page default values when running in Lightning Experience.
Exploring the Visualforce App Container
This change to the execution context has a number of effects on the way Visualforce pages can affect the overall Salesforce application. We’ll talk about these changes in this unit, but save the full details of a few of them for their own units.
The Outer Lightning Experience Container
Here’s what’s important to know: Lightning Experience, or /lightning, is in charge of the request. Your Visualforce page is not. Your page needs to work within constraints that Lightning Experience imposes upon it. Lightning Experience is the parent context, and your Visualforce page is the child context. Children need to obey their parents.
Some of these constraints, such as the size of the frame in which your Visualforce page is displayed, are imposed directly by Lightning Experience. They’re easier to understand and work with, and we’ll talk about them in a minute.
The Visualforce iframe
The advantage of running Visualforce pages inside an iframe is that, for pages that don’t need to access or change the top-level browsing context, running inside the iframe looks almost exactly like running as a page in Salesforce Classic. This is why you don’t need to modify all of your Visualforce pages to adapt to the wildly different behind-the-scenes request environment of Lightning Experience. It’s an important part of the “just works” strategy for supporting Visualforce.
Of course, the flip side is that pages that do need to access the top-level browsing context, well, there’s some things that need to change. We’ll cover some specifics in the next section.
If your page is communicating with services besides Salesforce, the iframe boundary might also result in you needing to update your organization’s CORS settings, remote site settings, clickjack settings, or content security policy. Since these depend on security policies and settings outside of Salesforce, we can’t provide a recipe for specific changes. We simply call it to your attention here.
Impact of the New Container
Again, we want to emphasize: many, or even most Visualforce pages won’t be affected by these issues. But for those that are, we’re thinking “forewarned is forearmed.” You’ll find the source of the problem faster if we’ve already talked about it together.
- Session maintenance and renewal
- Cross-domain requests
- Embedding restrictions
We discussed a few of these briefly already, the items dealing with cross-domain requests. That is, when the content in the full browser window comes from requests to different servers and services, there’s the potential for any of those requests to balk at being displayed in a context that it’s not prepared for. Your mission, should the need arise, is to prepare those services to handle requests intended to be put together within the Lightning Experience context. As we said before, the details vary, so we can’t provide specific answers here.
One thing we do want to mention specifically is session maintenance. A “session” for our purposes here is basically some kind of token that your browser re-uses from request to request so that you don’t need to enter your username and password for every request. You often need to access the current session using the global variable $Api.Session_ID .
Here’s the thing to keep in mind. $Api.Session_ID returns different values depending on the domain of the request. This is because the session ID varies during a session whenever you cross a hostname boundary, such as .salesforce.com to .force.com. Normally Salesforce transparently handles session hand-off between domains, but if you’re passing the session ID around yourself, be aware that you might need to re-access $Api.Session_ID from the right domain to ensure a valid session ID.
Lightning Experience and Visualforce pages are not only held in different browser contexts, they’re also served from different domains. So, even though it’s all showing in one browser window, the session ID inside the Visualforce iframe will be different than the session ID outside the iframe, in another part of Lightning Experience. Salesforce and Lightning Experience handle this transparently in normal use. But if you’re passing around the session ID like hors d'oeuvre at a party (not usually a good idea), you might need to review how you’re handling it.
- DOM access and modification
Practically speaking, the most common code pattern where you’d want to do this kind of thing is to manipulate window.location to navigate to another page. This is such a common thing to do, we’ve written up details on this specific issue...well, by the time you’re done with this module, you’ll be sick of hearing about it, we promise.
Doing things right means calling APIs we’ve made available in your Visualforce pages, primarily for navigation. If you really need to affect things across frame boundaries, use window.postMessage to send a message to receiving code in the other frame.
Visualforce Defaults and Environment Changes in Lightning Experience
Some of these changes are simple, and obvious once you think about them. For example, Visualforce pages that run in Lightning Experience always have the standard Salesforce Classic header and sidebar suppressed. Other changes aren’t as visible, but have just as large an impact.
<apex:page> showHeader and sidebar Attributes Are Always false
If your page is shared between Salesforce Classic and Lightning Experience, you can still set these attributes to the values you’d like to use when the page runs in Salesforce Classic.
sforce.one is primarily used to fire navigation events. The full details are in an upcoming unit, Managing Navigation .
* There is no Salesforce cantina. Alas.