Skip to content

Instantly share code, notes, and snippets.

@sperand-io
Last active January 6, 2022 22:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sperand-io/edc31c93a6340f48fcf4 to your computer and use it in GitHub Desktop.
Save sperand-io/edc31c93a6340f48fcf4 to your computer and use it in GitHub Desktop.
Using Segment via iFrame Communication
<script>
/**
* Provides a fake analytics object that sends all calls to the parent window for processing
*/
var analytics = (function() {
var eventQueue = [];
// Send the events to the frame if it's ready.
function flush(method, args) {
while (eventQueue.length) {
var evt = eventQueue.shift();
parent.postMessage({
method: evt[0],
arguments: evt[1]
}, '*');
}
}
var analyticsProxy = {};
// List of methods from the snippet at https://segment.com/docs/libraries/analytics.js/quickstart/
var methodsToProxy = [
'trackSubmit',
'trackClick',
'trackLink',
'trackForm',
'pageview',
'identify',
'group',
'track',
'ready',
'alias',
'page',
'once',
'off',
'on'
];
methodsToProxy.forEach(function(method) {
analyticsProxy[method] = function( /* Variable arguments */ ) {
eventQueue.push([method, Array.prototype.slice(arguments)]);
flush();
};
});
return analyticsProxy;
})();
</script>
<!doctype html>
<html>
<head>
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.0"; }}();
analytics.load('YOUR WRITE KEY');
</script>
<script>
// Forward all postMessage calls from the iframes that have data in the form {method:, arguments:} directly to Segment.
window.onmessage = function(e){
var method = e.data.method;
var args = e.data.arguments ? [].slice.call(e.data.arguments) : null;
if (analytics[method]) {
analytics[method].apply(analytics, args);
}
};
</script>
</head>
<body>
</body>
</html>
@ianfp
Copy link

ianfp commented Jun 23, 2021

If I'm not mistaken, line 40 in iframeSnippet.html should be

eventQueue.push([method, Array.prototype.slice.call(arguments)]);
// or
eventQueue.push([method, [].slice.call(arguments)]);

instead of:

eventQueue.push([method, Array.prototype.slice(arguments)]);

You're missing the .call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment