Loading Munchkin in an IFRAME (when forced by a feature-limited app)

It’s a sinking feeling when the docs for a hosted app include the word “IFRAME”, but there’s no match for “custom JS”. Puts a damper on sending app activities over to Marketo — not just Munchkin hits but form fills, too.[1]

Nevertheless, you can still get useful stuff in the Activity Log, as long as you load Munchkin a special way in the IFRAME.

Step 1: See if you can add the referrer <meta> tag

OK, the app won't let you add custom JS or CSS, but there’s a chance it lets you add a <meta> tag to the <head> of all pages. If so, you definitely want this in there:

<meta name="referrer" content="no-referrer-when-downgrade">

As I've explored before, the default referrer policy in modern browsers is strict-origin-when-cross-origin, which means a cross-origin IFRAME (as your IFRAME will certainly be) would only receive the truncated value https://yourco.saasapp.example instead of the full URL https://yourco.saasapp.example/some/page?and=query_string.

Without access to the path and query, the Munchkin hit will be extremely generic. It can still let you know, broadly, who visited the app, but only if the browser has an independently associated Munchkin cookie.

That is, if the IFRAMEd page (see below) is on https://pages.example.com and the person clicks a tracked link to and/or fills out a form on https://pages.example.com or https://www.example.com at some point (or did in the past) that association will carry over to the hit logged by the IFRAME. But otherwise, the IFRAME will be stuck logging anonymous pageviews, which is pretty unhelpful.

In contrast, if you can set that <meta> tag, the IFRAME itself can associate people who click a tracked link (since the mkt_tok value will be forwarded to the IFRAME).

Step 2: Create a Marketo LP (or CMS page) with a custom Munchkin config

The page you include in the IFRAME doesn't need to be a Marketo LP. It can be hosted on your main site or even be a static .html file in Design Studio, as long as it loads Munchkin the right way.

If you do use a Marketo LP, you want to disable Munchkin in the page setup (important!) and then add the below script instead.

The special sauce:

<script>
	(function() {
	  var didInit = false;
	  function initMunchkin() {
		if(didInit === false) {
		  didInit = true;
		  Munchkin.init("123-XOR-456", { 
			  apiOnly: true
		  });

       	  const parentURL = new URL(document.referrer);
		  Munchkin.munchkinFunction("visitWebPage", { 
			url: parentURL.origin + parentURL.pathname,  
			params: parentURL.searchParams.toString() 
		  });
		}
	  } 
	  var s = document.createElement("script");
	  s.type = "text/javascript";
	  s.async = true;
	  s.src="//munchkin.marketo.net/munchkin-beta.js";
	  s.onreadystatechange = function() {
		if (this.readyState == "complete" || this.readyState == "loaded") {
		  initMunchkin();
		}
	  };
	  s.onload = initMunchkin;
	  document.getElementsByTagName("head")[0].appendChild(s);
	})();
</script>

Key differences between this and the default Munchkin embed:

  • the apiOnly option is enabled, so you can customize the Visit Web Page parameters
  • instead of logging a view for the IFRAME's URL, we log the IFRAME's referrer's URL, which will be the full or partial URL of the parent app window

For fun (?) here's a visual diff:

Notes

[1] You won't get UTM parameters forwarded unless the app lets you see the entire referrer, so the form data will be incomplete vs. what you'd get with the form embed code.