Ryan Battles Data-Driven Marketing Specialist

Embedding Salesforce Forms And Ad-Blockers

E

At Wastebits, we’ve utilized a number of lead-generation tools over the years, and we are currently utilizing Salesforce Account Engagement (formerly Pardot) to capture & nurture leads. One thing that surprised me with Salesforce was that the form embeds are iframes instead of loaded via javascript. This poses a number of problems:

  1. Iframes have to be given dimensions of height and width, and with forms sometimes this value can change when there are error messages that come up or progressive fields that display based off of previous answers. This can be overcome by adding JavaScript to both the embedded template and the parent, but is definitely more cumbersome than a fluid embed loaded via JavaScript in the first place.
  2. Ad Blockers target iframes pretty aggressively. I personally use Adblock, and my forms did not load at all when I was trying to visit our Request a Demo form.

Whenever I load a form via embed, I add a “loading” animation to cover those one or two seconds that it might take the form to load, so the viewer knows that there is something more to come.

Loading animation
The loading animation just kept looping because my ad blocker didn’t like the iFrame and wouldn’t load it.

What is it supposed to look like? When the ad-blocker doesn’t stop the iframe from loading, you should see something like this:

The expected form should be loaded via iFrame in a perfect world.

Create a Backup Plan

Around 33% of internet users have an ad-blocker of some sort on their devices. This number is likely to continue to increase with time, so having a plan for those users is crucial. I wanted a solution that would be easy to implement, and could be automatically applied to any Salesforce embedded forms from the get-go. I wanted some code that could be implemented and maintained in one place, so the solution that I came up with was somewhat simple:

Proposed Solution: If the form is still loading after a few seconds, show a link to open the embed directly in a new tab. 

For this to work there were a few criteria for the implementation:

  1. The option to open it in a new tab would only show if it took more than a few seconds, otherwise it would clutter up the interface and people would feel that they need to click that button.
  2. The button (and loading animation) should disappear if the form loads correctly.

The first criteria can be met by creating a div with the id “loadingError”, and setting it to hidden on page load, then use some JavaScript to put a 2 second (2000 millisecond) delay before displaying it:

window.onload = function(){
  setTimeout(loadAfterTime, 2000)
};

function loadAfterTime() { 
  document.getElementById('loadError').style.display='block';
};

Which produces this output 2 seconds after the page loads:

An extra button appears after 2 seconds.

The “Click Here to View” button grabs the source from the iframe embed and turns it into a direct link. This work was done within the template of my content management system so it will look different depending on what system you are using to load your marketing site. It can also be done with Javascript.

Removing the loading animation and button

Loading animations are great, but they need to go once the loading is done. This is actually pretty simple to do with JavaScript, just use an onload event when embedding the iframe and remove the div by id (I used “spinner” as my id in the example below):

<iframe src="{{iframeUrl}}" width="100%" scrolling="no" onload="document.getElementById('spinner').style.display='none';"></iframe>

The “Click Here to View” button was included within that div, so it disappeared as well when the iframe loaded properly.

Going Further: Styling the Standalone Form

At this point you would have a working method for displaying the form, but the problem is that in order for the form to display well in an iframe, it needs to have no other styling than just the form fields themselves. When viewed within its own browser window, it is too naked:

I knew that I needed to show some elements (like a header, maybe a title, and putting the form inside a bounding box). The solution I came up with had the following criteria:

  1. I would use JavaScript to determine whether or not the page was loaded via an iframe.
  2. If it was loaded outside of an iframe, I would give the body a class of “standalone”.
  3. I can use CSS to style elements on the page as long as the body is of the class “standalone”, otherwise these items would remain hidden.

Ultimately, I’d like a standalone page to look a little more like this:

Determine the iframe

To determine whether the page is being loaded via iframe, I used the following snippet:

function inIframe () {
  try {
    return window.self !== window.top;
  } catch (e) {
    return true;
  }
}
    
if (!inIframe()) {
  $('body').addClass('standalone');
}

This snippet also includes the conditional that will add the class of “standalone” to the body tag.

Conditionally style elements via CSS

So, items like the blue navbar with a logo should only show up when the page is loaded via a standalone page, but not in the embed. The HTML would look something like this:

<div class="navbar" style="display: none;">
  <a href="https://wastebits.com">
    <img src="https://wastebits.com/img/design/wastebits-logo-nav-white.png" alt="Wastebits" />
  </a>
</div>

By default the navbar is set to “display:none”, but by adding the following CSS, it can be made to show:

body.standalone .navbar {
  display: block !important;
}

I can also add in the custom styling code for the form, when it is loaded outside of an iframe:

body.standalone form.form {
  background-color: #fff;
  border: 1px solid #ddd;
  padding: 1.4rem;
  max-width: 500px;
  margin: 0 auto 2rem;
  border-radius: 3px;
}

Recap & Conclusion

The problem that brought us here is that sometimes an ad blocker will prevent an embedded form from displaying for the end-user. This will cost valuable leads and can be overcome with some creative, progressive solutions. What we did was add a button to open the form directly in another window when it hasn’t loaded after a few seconds. We then styled this form in a way that only shows up when it is viewed in its own window, not as an embed.

The end result is a solution that works as expected for the majority of visitors, but has a backup plan that works well for those who don’t see the form load. By applying this logic to our templates both in Salesforce and on our marketing site, we can add new forms easily to the marketing site without having to repeat the programming on each page. In fact, using embeds, our templating code to include a form with all of the backups in place looks like this:

{% include '_forms/salesforce' with {iframeUrl : 'https://go.wastebits.com/l/1049642/2024-03-08/5bqn'} %}

A new form can be embedded anywhere by simply changing out the iframeUrl value, and all of the above enhancements are added automatically. This makes for easy maintenance, expandability, and progressive enhancement.

About the author

Ryan Battles

HI, I'M RYAN. I believe the best way to learn and remember is by writing things down and sharing them with others. This blog exists to help me synthesize and process my journey towards self-improvement.

Ryan Battles Data-Driven Marketing Specialist

Get in touch

About me

HI, I'M RYAN. I believe the best way to learn and remember is by writing things down and sharing them with others. This blog exists to help me synthesize and process my journey towards self-improvement.