Skip to content

Instantly share code, notes, and snippets.

@ak--47
Last active May 16, 2024 13:31
Show Gist options
  • Save ak--47/6c2b6bf317f56e09a260367860ca1a00 to your computer and use it in GitHub Desktop.
Save ak--47/6c2b6bf317f56e09a260367860ca1a00 to your computer and use it in GitHub Desktop.
Segment + Mixpanel w/Session Replay
<!-- 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