40

So I am planning to transfer our current VF pages to lightning ready. Most of our VF pages are based on a standard controller or standard set controller and use an extension. And they are pretty much using the classic salesforce look and feel. Many of them are binding to buttons and links in the record or list page.

I have done some learning and exercise in lightning component and slds. But I have to admit I am still quite new to them. From what I have investigated, there are three options:

  1. Keep the VF pages and only apply slds upon them. This is the safest option. However, I don't quite want to use it in the first place as I am keen to learn and use lightning component. It can be viewed as an approach to retreat.

  2. Use lightning component in the VF pages. In that case, I can probably only pass Ids of standard objects into lightning component (I might be wrong) and which means VF pages are pretty much just a container. It also seems I need to create a outer container app for each usage which seems strange to me. I am not quite sure how viable is this approach.

  3. In lightning experience, it seems lightning component can be used for actions. But seems only apply to lightning experience. Since we are developing an app in App exchange, our customers who are still using Salesforce classic won't share the love. So I am also hesitant about this one.

Any suggestions on this?

5
  • 6
    For me, too many restrictions / issue / bug to change everything to lightning components. besides, most VF page are not easy to break down to an individual component IMHO. I just tried this and ended up with doing it this way: 1 - use SLDS styling 2 - Ensure navigation uses the appropriate way depending on the users theme. Then is works in lightning and VF. After you do that, then you can look at changing to components. Baby steps
    – Eric
    Nov 3, 2016 at 0:51
  • 7
    Not sure if I am correct here, but when I tried to convert a VF page to a lightning component, I ended up with a Lightning app and almost 10 components. Was not worth the time. moving forward I will try to steer more towards Lightning components but backward compatibility will be done as stated above. Side note: I hope this does not get closed for too broad as I think as a community we MUST have this discussion. And I would prefer not to have to do it on the developer forums that I have not visited since SFSE went live.
    – Eric
    Nov 3, 2016 at 0:52
  • See the answer here for a related previous discussion and how to use the same page for both VF and Lightning: salesforce.stackexchange.com/questions/96220/…
    – Eric
    Nov 3, 2016 at 1:05
  • @Eric Thank you for all the information. Really helpful. The situation is a bit different now than the last year. Not sure whether this will affect the result in people choosing. And anyway, I do see lightning component to be the future.
    – Lance Shi
    Nov 3, 2016 at 1:10
  • you are right but the parts about using lightning in vf pages is still relevant and if you look at the comments it has been updated with the new information. Also, it seems with every new release comes new challenges. We will get there and like you I think now is the time to seriously start moving in that direction.
    – Eric
    Nov 3, 2016 at 1:53

2 Answers 2

58
+200

WINTER-18 Update

new property for VF <apex:page> tag lightningStyleSheets="[false|true]" will supposedly be the single thing you need to do to convert VF pages to SLDS type styles

https://releasenotes.docs.salesforce.com/en-us/winter18/release-notes/rn_vf_lightningstylesheets.htm

Previous Comments

Too much for a comment

This is the Template page I use for all VF pages now. It allows me to control the Navigation and add SLDS styling all starting from the same point:

<apex:page name="SLDS_template" showHeader="false" standardStylesheets="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0">

    <head>
        <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"/>

        <apex:insert name="title"/>

        <apex:stylesheet value="{!URLFOR($Resource.SLDS, 'assets/styles/salesforce-lightning-design-system-vf.min.css')}" />

        <style>
            #loader {
                position: fixed;
                left: 0;
                top: 0;
                bottom: 0;
                right: 0;
                background: #000;
                opacity: 0.6;
                filter: alpha(opacity=100);
                z-index: 99999;
            }

        </style>

        <script>
            function goHome(){
                ForceUI.isSalesforce1() ? sforce.one.navigateToURL('/home/home.jsp',true) : window.location.href='/';
            }

            function goretURL(){
                ForceUI.isSalesforce1() ? sforce.one.navigateToURL('{!$CurrentPage.parameters.retURL}') : window.location.href='{!$CurrentPage.parameters.retURL}';
            }

            function gotoURL(u, isParent){ //isParent to indicate if Inline VF
                ForceUI.isSalesforce1() ? sforce.one.navigateToURL(u) : (isParent ? window.top.location.href = u : window.location.href=u);
            }

            function showProcessing() {
                $('#loader').show();
            }

            function hideProcessing() {
                $('#loader').delay(300).fadeOut(400);
            }


            (function(myContext){
                myContext.ForceUI = myContext.ForceUI || {};

                myContext.ForceUI.isSalesforce1 = function() {
                    return((typeof sforce != 'undefined') && sforce && (!!sforce.one));
                }
            })(this);

        </script>
    </head>



    <div class="slds">

        <body>

        <apex:insert name="header"/>

        <div id="loader" class="slds-spinner_container">
            <div class="slds-spinner slds-spinner--large" role="alert">
                <span class="slds-assistive-text">Loading</span>
                <div class="slds-spinner__dot-a"></div>
                <div class="slds-spinner__dot-b"></div>
            </div>
        </div>

        <apex:insert name="body"/>

        </body>

    </div>

</apex:page>

Add in your own Error Message div to replace the standard page messages and use code to populate the message and go from there.

My VF pages now start like so:

<apex:page id="THEID" showHeader="false" sidebar="true"
           standardController="Account" extensions="EXTENSION" tabStyle="Account"
           standardStylesheets="false" applyHtmlTag="false"
           applyBodyTag="false" docType="html-5.0" cache="false">

    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <apex:composition template="SLDS_Template">
        <apex:define name="title">

        </apex:define>
        <apex:define name="body">

        </apex:define>

    </apex:composition>

    </html>
</apex:page>
6
  • 13
    That's a brilliant thought. Simply make a template for your other pages to switch to. I think I might steal/borrow this idea.
    – sfdcfox
    Nov 3, 2016 at 1:13
  • 2
    @sfdcfox - I am humbled. If you can improve upon the idea please do share if you can.
    – Eric
    Nov 3, 2016 at 1:37
  • @Eric It seems like the template exists mainly for the loading spinner and the javascript, but I'm not sure how to use it, why we would need it and what the last part does. may you write a view sentences about it?
    – itsmebasti
    Apr 6, 2017 at 7:25
  • @Basti - How to use is is the last part of the answer. The first part is basically a template that allows you to easily convert your existing VF pages to SLDS in a standardize way. In the last part is is an example of a VF page using the template. You can add your own content in. Additionally the template offers the navigation needed if used both in LEX and Classic
    – Eric
    Apr 6, 2017 at 12:28
  • @Eric sure, but it is missing how the javascript is used. The example does not show, why the template brings any advantage. It just implements it. What I'm asking for is more like a demonstration, why the Template makes things easier. Right now it's just defining unused JS methods and an unused spinner. So my question is more: Why would I need these things on every page that needs to be lightning enabled. Sorry if I'm missing something :)
    – itsmebasti
    Apr 7, 2017 at 7:11
15

As a first step, you can convert your pages to SLDS simply by uploading a static resource with the SLDS generated for you, and then adding a handful of lines of code:

<apex:stylesheet value="{!URLFOR($Resource.SLDS213, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
<div class="slds myns">
    <!-- the rest of your VF code goes here -->
</div>

Adding just these three lines of code will give you nearly all of the look and feel of Lightning for virtually zero effort. You can even "theme select" by using some special Visualforce, outlined in this article.

I recommend this as a first step, because it gives your LEX clients an immediate look and feel of Lightning with about 1 minute worth of effort per page you need to modify. You'll want to spend time testing your pages out in LEX anyways, because some JavaScript used in typical Visualforce pages will generate errors; these need to be fixed.

The second step is then to write the bulk of your pages as Lightning Out components or apps. This will allow your non-LEX clients continue to use the Classic theme and Visualforce, while simultaneously allowing your LEX clients to take advantage of your components by adding them to Lightning Apps and Lightning Pages. This takes significantly more effort than the first step, which is why I recommend SLDS as an intermediary to raise adoption of your app while you transition.

This is the approach that we're using internally to fast-track us to Lightning. Style first, then build out the new functionality one component at a time. Keep in mind that Salesforce recommends a ton of components, but the truth is, you can write many Visualforce pages as just a single monolithic Lightning component, at least initially. Over time, as I have in the weeks since Dreamforce, you'll come to appreciate components that you end up reusing again and again, but there's no specific requirement that you start out with tons and tons of components.

Finally, it's worth noting that Lightning Out will allow you to embed your components in Visualforce pages, so your Classic users can still build Visualforce actions, buttons, and links, while your LEX users can use the components from those pages directly. You can definitely have your cake, and eat it, too. In many cases, we're using this approach for many of our prior JavaScript buttons that do not appear in Lightning; just wrap the code into a tidy little component, and you then then add it to whatever context you need.

8
  • 1
    Its funny, if we had embraced visual force components heavily, the transition to Lightning components would be much easier :)
    – Eric
    Nov 3, 2016 at 1:37
  • 1
    very helpful -- how would you modify the above, if at all, for an enterprise org where some users use LEX and others use Classic?
    – cropredy
    Nov 3, 2016 at 1:48
  • 1
    @cropredy We're actually doing just that-- we have a user base of about 3k. This is essentially our internal plan, and we figure we'll have everyone migrated over to LEX by February at the latest. Existing users will be "encouraged" to move over to LEX, while new users will be defaulted that way. Using Lightning Out appears to be the most beneficial method, as users can get the same functionality in both experiences. We're not doing theme detection though, because we eventually want everything custom to look like LEX regardless of what mode they're in.
    – sfdcfox
    Nov 3, 2016 at 1:51
  • you can actually use <apex:slds> </apex:slds> and encompass your entire sheet. You don't need the static resource to do that.
    – tjcinnamon
    Mar 28, 2017 at 20:52
  • 1
    @MANUELAN00 I'd recommend SLDS (Salesforce Lightning Design System) instead of Bootstrap.
    – sfdcfox
    May 26, 2017 at 1:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .