SharePoint Online: Client libraries not loaded in publishing pages

Recently worked with a customer who had JSOM code in a content editor web part.  They had this web part deployed to a page on their SharePoint Online publishing site.  For simplicity, let’s say they had the below code in a JS file referenced in their content editor web part.

 <script type="text/javascript">
  
     ExecuteOrDelayUntilScriptLoaded(spCallOut, 'SP.js');    
  
     var web;
  
     function spCallOut() {
         var clientContext = new SP.ClientContext.get_current();
         this.web = clientContext.get_web();
         clientContext.load(this.web, 'Title');
         clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
     }
  
     function onQuerySucceeded(sender, args) {
         alert(this.web.get_title());
     }
  
     function onQueryFailed(sender, args) {
         alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
     }
  
 </script>

According to the logic in the above code, we expect to see a message box with the current web’s title.  However, the message box pop-up never appears when the option to “Hide Ribbon” is enabled on publishing sites.

image

We found this to be because the client-side libraries (SP.js etc.,) was not loaded yet.  To circumvent this problem we replaced the call to ExecuteOrDelayUntilScriptLoaded(spCallOut, ‘SP.js’) to EnsureScriptFunc("SP.js", "SP.ClientContext", function() { spCallOut() }) (EnsureScriptFunc is definite in init.js).  And that fixed this problem.

Apparently ExecuteOrDelayUntilScriptLoaded function is not the correct one to be used in this case, but EnsureScriptFunc is, which also loads the dependent libraries on-demand.

Hope this post was useful in your client-side development efforts!