+ Start a Discussion
Ken KoellnerKen Koellner 

Include Lightning Component in Sites VisualForce Page

I've started dabling in Lightning Components and worked through a tutorial last year and have done one of the trailheads a few days.  So I know how to code basic Lightning components and apps.  And I see in the metadata that these become AuraDefinitionBundles.  I also so an example of some code where a bit of JS is added to an empty VF page and that always a Lightning Component to be spun up inside a VF page.

What I want to do is take an exist VF page that is exposed to the internet as a SF "Sites" application and port it to Lightning.  What I included in the prior paragaph leads me to believe the page is codable.  Here's what I don't know.  When a Sites application is configured, you have to tell it what it has access to-- VF pages, Apex controllers, objects and fields, etc.  I don't know how you would give it access to the Aura bundle.  (Unless it's totally implicit and you don't have to and it automatically gets acces.)

Can anyone address the question of how to configure and deploy Sites application that includes a VF page that spins up an Lightning Component?
 
Ken KoellnerKen Koellner
I can amend the question to be both more specific and more general.

To be more specific, when you create a Sites application, it gets a special Public profile.  You can then edit that profile.  The question would then be on that Public Access Settings profile, can you grant permissions to Lightning Apps and if so how?

To be more general, on any profile you can grant access to VF pages and Apex classes.  Or you can come at it from the Page or Class definition in setup and use the Security feature to select which profiles have access.  I don't see any Security feature on the Lightning components listed under Setup->Development.  So how is security on Lighning components maintained?

 
Dayanand KumbharDayanand Kumbhar
Hi Ken,

Did you got any solution for this ? With Spring 16 release, there is Lightning Out coming. That may be used to resolve the issue.

However, want to know if you have any workaround before that ?

Thanks,
​Dayanand
Ken KoellnerKen Koellner
I don’t have time to attend to Lightning adoption now because of another project. But the question always be how to provide an SF sites access to a Lightning bundle? Access needs to be granted for pages and classes. Will access need to be granted for bundles? Will it be implicit in that no access need to be granted? Or will it not be possible for VF pages to access Lightning bundles in Sites? -K
TopalovichTopalovich
Ken - Dayanand is correct about Lightning Out solving this issue...since Sites exposes Visualforce pages, what you would need to do is wrap your Lightning App in a Visualforce page (as you've already figured out above), extend the "ltng:outApp" interface, use the "global" access modifier in your Lightning App, and ensure that all dependencies have been met. Easier said than done, I'm actually working on this right now and am finding some weirdness with the rendering of the Lightning Components within the iFrame exposed by Visualforce.

This is the documentation that I've been following:

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_visualforce.htm


Mike
TopalovichTopalovich
Another caveat with exposing Visualforce pages that embed Lightning Apps / Components through Sites is that you won't have the benefit of using metadata-aware components like "apex:inputField" - you're going to have to apply more object and field-level security in the underlying Apex controller than you used to have to with Visualforce.
 
Christian Szandor KnappChristian Szandor Knapp

+1

Currently, I cannot get lightning components to work with a publically exposed visualforce page aka site in our Sandbox Org. I get a 401 unauthorized error. 

Testing the VF Page on its own (logged in as admin), shows that lightning out does request the App via a faulty url (visual.force.com instead of lightning.force.com) 

These errors might not be related to each other or rather one might solve the other. Nonetheless, I would appreciate a clear statement on: What do I need to do to get lighting components on my public sites. 

Cheers,
Sz

 

 

Ken KoellnerKen Koellner

Sz, thanks for doing the experiment.  I've had other pressing priorities and haven't been able to.  What you experienced is what I was worried about.  For Sites, you have explicitly grant access to VF pages and Apex Classes.  But there's no place (yet) to explicitly grant access to Lightning Apps.  So I don't know if it even has a chance of working at all.  The only thing I could think of is if there's a hack to override that URL that you mentioned is bad.

 

I wish we could get SF to speak up on these issues.
 

Doug ChasmanDoug Chasman
LC in a guerst user/non authenticated container is not currently supported. This is on the roadmap and I hope to see it be part of Summer'16 but safe harbor and all that. I can say that when it does surface publicly there will simply be a lightning interface that you will add to your ltng:outApp - something like implements="ltng:allowGuestAccess". 
Matty BMatty B
ugh we need this too... unfortunately realized this all to late after the lightning app was done. back to VF we go.
Ken KoellnerKen Koellner
I skimmed the documention on Summer '16.  I see some documentation on Lightning Out and mention of Lightning Apps being available in Communitities.  I didn't see "Sites" mentioned anywhere.

Does anyone know if Summer '16 will allow Lightning pages in Sites?
John TJohn T
What's interesting is that SF communities uses sites with lightning components to log users in. I'm trying to make use of the loginForm component, but it's returning a 401.
Christian Szandor KnappChristian Szandor Knapp
Safe harbour and all, I have heard rumors: the next lightning for Visualforce update will be happening with Winter 16. 
MohandaasMohandaas
Finally, the 'ltng:allowGuestAccess' interface is coming in Spring '17 to make Lightning Out dependency app available to users without requiring them to authenticate with Salesforce.
Ken KoellnerKen Koellner
Access Lightning Apps in Public Communities
Add the ltng:allowGuestAccess interface to your Lightning app to make it available to users without requiring that they register with or log in to your community. This interface makes your Lightning app available to more people, with fewer barriers to using it.
That's what the spring '17 release notes say.  It mentioned only within communities.  I don't know if it will work for Sites.  My guess is SF is trying to steer customers away from Sites and towards communities but we haven't done Communities yet and have a few simple Sites VF pages.  I would be nice to port those pages to Lightning and still keep them on Sites. 

From what I understand, LightingOut will let a Lightning App run anywhere, even when not served by SF.  But there may still not be a way to get Sites to serve the Lighning buddle.  Perhaps the workaround would be to declare that guess access is allowed and then just server the bundle from an external web server.
 
Ch. Szandor KnappCh. Szandor Knapp
That was my understandig as well, Ken. Still I believe this to be a milestone towards public sites as well.
Ken KoellnerKen Koellner

I wonder if this would work--

  1. Give your lightning app guest access via the guest access tag.
  2. Put the aura bundle for the lightning app in a .zip file in a static resource.
  3. Have a trivial VF page that brings in that static resource.
  4. Serve that VF page and Static Resources via SF Sites.

 

Christian Szandor KnappChristian Szandor Knapp
I very much doubt that. You'd basically have text files that VIsualforce wouldn't understand how to initialize or bring to life.
Ken KoellnerKen Koellner
But they would be javascript files and then a VF page could contain a few lines of javascript in it to invoke the JS in the static resources.
Christian Szandor KnappChristian Szandor Knapp
Lightning Components need their own Framework (Aura) to run. No dice there
Vikram Kamboj 6Vikram Kamboj 6
Hi Ken,

I managed to embed a small lightning component inside a visual force page and displayed it on my sample force.com site, but it still needs authentication, I didn't manage to implement "ltng:allowGuestAccess"(any input is highly appreciated here).

I used Lightning Out( "ltng:outApp") below to embed my lightning component to my VF page and then used site login to navigate to my visualforce page. 
 
<!----------------Lightning app which includes a lightning component--------->
<aura:application extends="ltng:outApp">
    <aura:dependency resource="c:YourComponent" type="COMPONENT"/>
</aura:application>

<!--------------VF page with above Lightning app--------->

<apex:page showHeader="false" sidebar="false">
      <apex:outputLink value="{!$Site.Prefix}/secur/logout.jsp" rendered="  {!NOT(ISPICKVAL($User.UserType,'Guest'))}">{!$Label.site.logout}</apex:outputLink>

 <!-- This loads the JavaScript file needed to use Lightning Components for Visualforce-->
    <apex:includeLightning />

    <!-- div tag act as locator while calling Lightning.createComponent -->
    <div id="lightning" />
 
    <script>
 
        $Lightning.use("c:YouAppName", function() {
          $Lightning.createComponent("c:YourComponentName",
          "",
          "lightning",
          function(cmp) {
            // do some stuff
          });
        });
 
    </script>
</apex:page>

 
Miroslav SmukovMiroslav Smukov
Vikram was very close to a solution. Here's what worked for me to make the Lightning Component available in Sites without requiring users to log in - basically I only added the interface to the to the Lightning Out app. Note that Salesforce Communities need to be enabled in your org.
 
<!----- Lightning Out App ----->
<aura:application  access="GLOBAL" extends="ltng:outApp" implements="ltng:allowGuestAccess">
    <aura:dependency resource="c:YourComponent"/>
</aura:application>

<!----- VF Page exposed in Sites ----->

<apex:page showHeader="false" sidebar="false">
	<apex:includeLightning />

	<div id="lightning" />

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

</apex:page>

 
B2000B2000
Using Miroslav's code above, I am having a problem with my component on a sites page.  The VF page loads the component but the force:recordData code doesn't load the record.  I verified the recordId is being passed by putting an {!v.recordId} in the component and also in the recordUpdate controller function.  This component code in another lightning works perfectly in the sandbox.  Any ideas?
Application: myApplication
<aura:application access="GLOBAL" extends="ltng:outApp" implements="ltng:allowGuestAccess">
    <aura:attribute name="recordId" type="String" />
    <aura:dependency resource="c:myComponent"/>
</aura:application>

Component: myComponent
<aura:component >
    <aura:attribute name="record"             type="Object"/>
    <aura:attribute name="simpleRecord"       type="Object"/>
    <aura:attribute name="recordError"        type="String"/>
    <aura:attribute name="recordId"           type="String"/>
	
    <aura:handler name="accountChange" event="c:evtAccountChange"
 	      action="{!c.handleAccountChange}" />

	{!v.recordId}
	<force:recordData aura:id="accoutRecord"
		recordId="{!v.recordId}"
      	layoutType="FULL"
      	targetRecord="{!v.record}"
	  	targetFields="{!v.simpleRecord}"               
      	targetError="{!v.recordError}"
      	mode="VIEW"
      	recordUpdated="{!c.recordUpdate}"                
      	/>   

        <div class="slds-media__figure">
          <span class="slds-icon_container slds-icon-standard-opportunity" title="">
            <lightning:icon iconName="standard:contact" size="small" alternativeText="Name"/>                       </span>
        </div>
        <div class="slds-media__body">
          <h1 class="slds-page-header__title slds-truncate slds-align-middle" title="Header">
            {!v.simpleRecord.FirstName}&nbsp;{!v.simpleRecord.LastName}</h1>
                    
Controller:
    recordUpdate : function(cmp, event, helper) {
      console.log('recordUpdate:'+cmp.get("v.recordId"));      
	},

 
TopalovichTopalovich
force:recordData won't work in the context of Lightning Out / Visualforce for Lightning Components. It only works in the context of components surfaced through the one.app container application - i.e. Lightning Experience or Salesforce Mobile.
B2000B2000
I replaced the force:recordData code with an Apex controller.  The Id is passed to the controller fine but I get zero records found. I also query any 10 Account records and zero are found.
public class cAuraCrewMember 
{
    @AuraEnabled
    public static Account getAccount(String aId)
    {        
        system.debug('\n\n@@@ getAccount: aid='+ aId); //       
        system.debug('\n\n@@@Accounts='+[Select Name FROM Account limit 10]+'\n\n');
        
        Account a = new Account();         
                
        for (Account acc : [SELECT 
                Name, 
                LastName, 
                Id, 
                FirstName
            FROM Account
            WHERE id = :aID
            LIMIT 1]) 
        {
            a = acc;
        }            
        return a;
            
    }  

DEBUG LOG:

@@@ getAccount: aid=001m000000bTHDH

04:26:40.0 (2239074)|SOQL_EXECUTE_BEGIN|[19]|Aggregations:0|SELECT Name FROM Account LIMIT 10
04:26:40.0 (6505053)|SOQL_EXECUTE_END|[19]|Rows:0
04:26:40.0 (6650510)|USER_DEBUG|[19]|DEBUG|

@@@Accounts=()

04:26:40.0 (7710751)|SOQL_EXECUTE_BEGIN|[23]|Aggregations:0|SELECT Name, Id .... FROM Account 
04:26:40.0 (22043357)|SOQL_EXECUTE_END|[23]|Rows:0
B2000B2000
Resolved it with permissions
XinPing YangXinPing Yang
As the following codes, It doesn't worked for me to make the Lightning Component available in Sites without requiring users to log in . I hope anyone can help me.
<!-- Lightning Out App -->
<aura:application extends="ltng:outApp" access="GLOBAL" implements="ltng:allowGuestAccess">
    <aura:dependency resource="c:ProjectDetail"/>  
</aura:application>

<!-- VF Page -->
<apex:page standardController="Exhibition__c" standardStylesheets="false" applyBodyTag="false">
	<apex:includeLightning />	
	<style>
        html, body {
        margin: 0;
        padding: 0;
        }
        #lightningComponent {width: 100%;}
    </style>
    <script>    	
    	$Lightning.use("c:SiteProjectDetailApp",function(){
    		$Lightning.createComponent("c:ProjectDetail",
				{},
				"lightningComponent",
				function(cmp){
					
				}
			);
    	});
    </script>
    <div id="content">
        <div id="lightningComponent" />
    </div>
</apex:page>