Last active
May 16, 2024 13:31
-
-
Save ak--47/6c2b6bf317f56e09a260367860ca1a00 to your computer and use it in GitHub Desktop.
Segment + Mixpanel w/Session Replay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- segment snippet --> | |
<script> | |
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)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","reset","group","track","ready","alias","debug","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,e){var n=document.createElement("script");n.type="text/javascript";n.async=!0;n.src="https://cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(n,a);analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.1.0"; | |
analytics.load("SEGMENT-API-KEY"); | |
analytics.page(); | |
}}(); | |
</script> | |
<!-- mixpanel snippet --> | |
<script type="text/javascript">(function(e,a){if(!a.__SV){var b=window;try{var c,l,i,j=b.location,g=j.hash;c=function(a,b){return(l=a.match(RegExp(b+"=([^&]*)")))?l[1]:null};g&&c(g,"state")&&(i=JSON.parse(decodeURIComponent(c(g,"state"))),"mpeditor"===i.action&&(b.sessionStorage.setItem("_mpcehash",g),history.replaceState(i.desiredHash||"",e.title,j.pathname+j.search)))}catch(m){}var k,h;window.mixpanel=a;a._i=[];a.init=function(b,c,f){function e(b,a){var c=a.split(".");2==c.length&&(b=b[c[0]],a=c[1]);b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments, | |
0)))}}var d=a;"undefined"!==typeof f?d=a[f]=[]:f="mixpanel";d.people=d.people||[];d.toString=function(b){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);b||(a+=" (stub)");return a};d.people.toString=function(){return d.toString(1)+".people (stub)"};k="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" "); | |
for(h=0;h<k.length;h++)e(d,k[h]);a._i.push([b,c,f])};a.__SV=1.2;b=e.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js";c=e.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}})(document,window.mixpanel||[]); | |
</script> | |
<!-- mixpanel initalization to activate session replay + use same Ids as segment --> | |
<script> | |
// This code is a Mixpanel init function that binds Segment's device_id and user_id to Mixpanel | |
// to ensure that the session replay feature works correctly when events are tracked through Segment | |
// and replays are tracked in Mixpanel. | |
// Segment device_id docs: https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/identity/#retrieve-the-anonymous-id | |
// Mixpanel session replay options: https://docs.mixpanel.com/docs/tracking-methods/sdks/javascript#session-replay-beta | |
mixpanel.init('MIXPANEL-PROJECT-TOKEN', { | |
// session replay options | |
record_sessions_percent: .1, // .1 = 10% of sessions | |
record_idle_timeout_ms: 1800000, | |
record_max_ms: 86400000, | |
record_mask_text_selector: "*", | |
//binding segment's device_id and user_id to mixpanel | |
loaded: function (mixpanel) { | |
const pollInterval = 500; // How frequently to check | |
const maxAttempts = 10; // Max times to check | |
const recordPercent = mixpanel?.config?.record_sessions_percent || 0; | |
let anonymousCheckAttempts = 0; | |
let authCheckAttempts = 0; | |
// wrapper to start session recording based on record_percent | |
const startSessionRecording = (percent = recordPercent) => { | |
if (Math.random() < percent) { | |
mixpanel.start_session_recording(); | |
} | |
}; | |
// Checking for segment device_id | |
try { | |
const anonymousCheck = setInterval(() => { | |
const segment_device_id = analytics?.user()?.anonymousId(); | |
if (segment_device_id) { | |
mixpanel.register({ $device_id: segment_device_id }); //use segment's device_id | |
clearInterval(anonymousCheck); | |
startSessionRecording(); | |
} else { | |
anonymousCheckAttempts++; | |
if (anonymousCheckAttempts >= maxAttempts) { | |
clearInterval(anonymousCheck); | |
console.log('mixpanel: Max attempts reached for segment device_id'); | |
} | |
} | |
}, pollInterval); | |
} | |
catch (e) { | |
console.error(`mixpanel: error checking for segment device_id: ${e}`); | |
} | |
// Checking for segment user_id | |
try { | |
const authCheck = setInterval(() => { | |
const segment_user_id = analytics?.user()?.id(); | |
if (segment_user_id) { | |
mixpanel.identify(segment_user_id); //use segment's user id | |
clearInterval(authCheck); | |
startSessionRecording(); | |
} else { | |
authCheckAttempts++; | |
if (authCheckAttempts >= maxAttempts) { | |
clearInterval(authCheck); | |
console.log('mixpanel: Max attempts reached for segment user_id'); | |
} | |
} | |
}, pollInterval); | |
} | |
catch (e) { | |
console.error(`mixpanel: error checking for segment user_id: ${e}`); | |
} | |
} | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment