The Trick to Resizing Inline Visualforce Pages in the Service Cloud Console

August 21, 2015 Appirio

By Rahul Jain


On several occasions, many of us developers have made an inline Visualforce page that lives on the object detail page. But whenever we do this, we invariably forget about resizing the inline Visualforce page height with respect to its content height. Because of this, we often get those annoying extra inline scrollbars for dynamic content in the Service Cloud console. This obviously causes a bad user experience.

The trick is to allow inline Visualforce pages to resize themselves. In order to do this, I came up with an approach that uses html injection with url hashing for cross-domain communication in After doing some research on the platform, I concluded that I could use use static resources (hosted on domain: to store an html page. And then I could use this static resource to communicate with the standard detail page to resize an inline Visualforce page.


The good news is that this approach is relatively simple and easy to implement.Before this approach, I was desperately looking for a way to achieve a better user experience with an inline Visualforce that adjusts to the content of the page. Many of us have used the sidebar components trick to achieve this, but we could not figure out how to do this in the Service Cloud console. This is because the sidebar doesn’t persist in the service console. But as the saying goes, “Necessity is the mother of invention.”

In the particular use case I was working on, we had to display a hierarchical tree structure in the account’s page layout. This was done using the inline Visualforce page of tree structure on the object detail page with fixed height and width. But every time a user expanded the tree structure, the inline Visualforce displayed a scrollbar. And then to get to a tree node, the user had to scroll; not a great user experience.

What is “html injection with url hashing for cross-domain communication in” Salesforce uses an iframe html element on the object detail page layout for inline Visualforce pages. The domains for the inline Visualforce page and the parent page (object detail page) are different. Because most browsers use a “same origin” policy, the communication between these two different domain pages is impossible. Not even with the following tricks:

  • postMessage-interface in HTML5 — In this approach, a developer needs to have control on both the domain pages in order to post a request from one page and receive the same in another. Because we don’t have control on the standard detail page, this approach is not feasible.
  • htmlarea in sidebar components — This won’t work because we can’t have sidebar components in the Service Cloud console.

Having tried those, I finally came to a solution that worked. I used html injection and url hashing to adjust the height of the inline Visualforce page. Here are the steps:

  1. When the inline Visualforce page is loaded, create an iframe element on fly using javascript that contains the static resource (html page). Append the javascript command for setting the height attribute of inline Visualforce page (which is also an iframe) using hashing with the url.
  2. When the static resource-based iframe is loaded, execute the command passed via url hash using javascript: eval.

Because the static resource iframe and the top parent detail page are hosted on the same domain, communication between these two is now possible. This allows us to modify the height of inline Visualforce page iframe.



Fortunately, this technique may not be needed in the future. Check out this idea page, and you’ll see that many people have been requesting this feature from a long time. But until then, you can follow the steps below to implement the solution in your org and give your users a much better experience:

  1. Save the Snippet 1 code as CrossBrowserPage.html and upload as a static resource and name as CrossBrowserPage.
  2. Save the Snippet 2 code as CrossDomainUtility.js and upload as a static resource and name as CrossDomainUtility.
  3. Include Snippet 3 code in the inline Visualforce page, change the value of origin javascript variable as per your org details, and you’re set!

[snippet caption=”1. CrossBrowserPage.html“]




var bodyReady = function(){    

  var command = getAnchor();   

  eval(‘var fn = ‘ + command + ‘; fn();’);  



function getAnchor() {       

   return (window.location.hash.split(‘#’).length > 1) ? window.location.hash.split(‘#’)[1] : null;




<body onload=”bodyReady();”>





[snippet caption=”2.CrossDomainUtility.js“]

var CrossDomainUtility = {

iframeURL : ”,

origin : ”,

callback : function (e) {       

      // Do whatever you want to do with the data got from IFrame in Parent form.


setHeight: function(){

var myHeight = 0;

if( typeof( window.innerHeight ) == ‘number’ ) {


   myHeight = window.innerHeight;

} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {

   //IE 6+ in ‘standards compliant mode’   

   myHeight = document.documentElement.clientHeight;

} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {

   //IE 4 compatible   

   myHeight = document.body.clientHeight;


if(document.body.offsetHeight && document.body.offsetHeight > 0){

  myHeight =  document.body.offsetHeight;


  var iframeName =;

  var fnc = ‘function(){‘;

fnc += ‘ var elements = parent.parent.document.getElementsByName(” + iframeName + ”);’;

fnc += ‘  for(var indx = 0; indx < elements.length; indx++){‘;

fnc += ‘      elements[indx].setAttribute(‘height’, ” + myHeight + ‘px’);’;

fnc += ‘      break;’;

fnc += ‘  }’;

fnc += ‘ }’;



invokeScript : function(func){

  if(this.iframeURL != ”){

   var functionString = “” + func;

   functionString = this.removeComments(functionString);   


   var src = this.origin + this.iframeURL + “#” + functionString;


   CrossDomainUtility.addEvent(window, ‘message’, CrossDomainUtility.callback, false);



addEvent : function(obj, evType, fn, useCapture){

 if (obj.addEventListener){

   obj.addEventListener(evType, fn, useCapture);

   return true;

 } else if (obj.attachEvent){

   var r = obj.attachEvent(“on” + evType, fn);

   return r;




createIframe : function(src){

   var iframe = document.createElement(“iframe”);

   iframe.src = src;

   iframe.height = ‘0px’;

   iframe.width = ‘0px’;

   iframe.onload = function() {

       //alert(“Content loaded, removing iframe…”);





removeComments : function(str) {    

       var uid = ‘_’ + +new Date(),

           primatives = [],

           primIndex = 0;


       return (


           /* Remove strings */

           .replace(/([‘”])(\1|.)+?1/g, function(match){

               primatives[primIndex] = match;

               return (uid + ”) + primIndex++;



           /* Remove Regexes */

           .replace(/([^/])(/(?!*|/)(\/|.)+?/[gim]{0,3})/g, function(match, $1, $2){

               primatives[primIndex] = $2;

               return $1 + (uid + ”) + primIndex++;




           – Remove single-line comments that contain would-be multi-line delimiters

               E.g. // Comment /* <–

           – Remove multi-line comments that contain would be single-line delimiters

               E.g. /* // <–


           .replace(///.*?/?*.+?(?=n|r|$)|/*[sS]*?//[sS]*?*//g, ”)



           Remove single and multi-line comments,

           no consideration of inner-contents


           .replace(///.+?(?=n|r|$)|/*[sS]+?*//g, ”)



           Remove multi-line comments that have a replaced ending (string/regex)

           Greedy, so no inner strings/regexes will stop it.


           .replace(RegExp(‘\/\*[\s\S]+’ + uid + ‘\d+’, ‘g’), ”)


           /* Bring back strings & regexes */

           .replace(RegExp(uid + ‘(\d+)’, ‘g’), function(match, n){

               return primatives[n];







[snippet caption=”3.Code to be included in your inline Visualforce page:“]

<script type=”text/javascript”>

// Use custom label or custom setting to store this

// The origin domain should be the top level domain of current salesforce org

// where all the standard sfdc pages are hosted.

CrossDomainUtility.origin = ‘<TOP_DOMAIN_URL>’; //example: ‘’;

CrossDomainUtility.iframeURL = ‘{!$Resource.CrossBrowserPage}’;  // this will give the relative address of the static resource


var pageOnLoad = function() {



CrossDomainUtility.addEvent(window, ‘load’, pageOnLoad, false);




Note that CrossDomainUtility.origin should be defined with the url of the top level of domain where the standard pages are hosted and CrossDomainUtility.iframeURL is the relativeURL of the supporting CrossBrowserPage.

Previous Article
The 7 Best (Non-Lightning) Features in the Salesforce Winter ‘16 Release
The 7 Best (Non-Lightning) Features in the Salesforce Winter ‘16 Release

Anyone who livestreamed or even read about the Meet the New Salesforce event won’t be surprised that Salesf...

Next Article
Chrome Extensions Every Salesforce Admin Should Have
Chrome Extensions Every Salesforce Admin Should Have

By Durgesh Dhoot In my last blog I discussed the extensions that every developer should have. But aside fro...