mixpanel-browser 2.48.0 → 2.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
 
7
7
  var Config = {
8
8
  DEBUG: false,
9
- LIB_VERSION: '2.48.0'
9
+ LIB_VERSION: '2.49.0'
10
10
  };
11
11
 
12
12
  // since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
@@ -905,6 +905,7 @@
905
905
  // sending false tracking data
906
906
  var BLOCKED_UA_STRS = [
907
907
  'ahrefsbot',
908
+ 'ahrefssiteaudit',
908
909
  'baiduspider',
909
910
  'bingbot',
910
911
  'bingpreview',
@@ -1625,7 +1626,14 @@
1625
1626
  return '';
1626
1627
  },
1627
1628
 
1628
- properties: function() {
1629
+ currentUrl: function() {
1630
+ return window$1.location.href;
1631
+ },
1632
+
1633
+ properties: function(extra_props) {
1634
+ if (typeof extra_props !== 'object') {
1635
+ extra_props = {};
1636
+ }
1629
1637
  return _.extend(_.strip_empty_properties({
1630
1638
  '$os': _.info.os(),
1631
1639
  '$browser': _.info.browser(userAgent, navigator.vendor, windowOpera),
@@ -1633,7 +1641,7 @@
1633
1641
  '$referring_domain': _.info.referringDomain(document$1.referrer),
1634
1642
  '$device': _.info.device(userAgent)
1635
1643
  }), {
1636
- '$current_url': window$1.location.href,
1644
+ '$current_url': _.info.currentUrl(),
1637
1645
  '$browser_version': _.info.browserVersion(userAgent, navigator.vendor, windowOpera),
1638
1646
  '$screen_height': screen.height,
1639
1647
  '$screen_width': screen.width,
@@ -1641,7 +1649,7 @@
1641
1649
  '$lib_version': Config.LIB_VERSION,
1642
1650
  '$insert_id': cheap_guid(),
1643
1651
  'time': _.timestamp() / 1000 // epoch time in seconds
1644
- });
1652
+ }, _.strip_empty_properties(extra_props));
1645
1653
  },
1646
1654
 
1647
1655
  people_properties: function() {
@@ -3207,7 +3215,6 @@
3207
3215
  data[SET_ACTION] = _.extend(
3208
3216
  {},
3209
3217
  _.info.people_properties(),
3210
- this._mixpanel['persistence'].get_referrer_info(),
3211
3218
  data[SET_ACTION]
3212
3219
  );
3213
3220
  return this._send_request(data, callback);
@@ -4167,10 +4174,12 @@
4167
4174
  'cookie_domain': '',
4168
4175
  'cookie_name': '',
4169
4176
  'loaded': NOOP_FUNC,
4177
+ 'mp_loader': null,
4170
4178
  'track_marketing': true,
4171
4179
  'track_pageview': false,
4172
4180
  'skip_first_touch_marketing': false,
4173
4181
  'store_google': true,
4182
+ 'stop_utm_persistence': false,
4174
4183
  'save_referrer': true,
4175
4184
  'test': false,
4176
4185
  'verbose': false,
@@ -4404,8 +4413,9 @@
4404
4413
  }, '');
4405
4414
  }
4406
4415
 
4407
- if (this.get_config('track_pageview')) {
4408
- this.track_pageview();
4416
+ var track_pageview_option = this.get_config('track_pageview');
4417
+ if (track_pageview_option) {
4418
+ this._init_url_change_tracking(track_pageview_option);
4409
4419
  }
4410
4420
  };
4411
4421
 
@@ -4414,13 +4424,26 @@
4414
4424
  MixpanelLib.prototype._loaded = function() {
4415
4425
  this.get_config('loaded')(this);
4416
4426
  this._set_default_superprops();
4427
+ this['people'].set_once(this['persistence'].get_referrer_info());
4428
+
4429
+ // The original 'store_google' functionality will be deprecated and the config will be
4430
+ // used to clear previously managed UTM parameters from persistence.
4431
+ // stop_utm_persistence is `false` by default now but will be default `true` in the future.
4432
+ if (this.get_config('store_google') && this.get_config('stop_utm_persistence')) {
4433
+ var utm_params = _.info.campaignParams(null);
4434
+ _.each(utm_params, function(_utm_value, utm_key) {
4435
+ // We need to unregister persisted UTM parameters so old values
4436
+ // are not mixed with the new UTM parameters
4437
+ this.unregister(utm_key);
4438
+ }.bind(this));
4439
+ }
4417
4440
  };
4418
4441
 
4419
4442
  // update persistence with info on referrer, UTM params, etc
4420
4443
  MixpanelLib.prototype._set_default_superprops = function() {
4421
4444
  this['persistence'].update_search_keyword(document$1.referrer);
4422
- if (this.get_config('store_google')) {
4423
- this.register(_.info.campaignParams(), {persistent: false});
4445
+ if (this.get_config('store_google') && !this.get_config('stop_utm_persistence')) {
4446
+ this.register(_.info.campaignParams());
4424
4447
  }
4425
4448
  if (this.get_config('save_referrer')) {
4426
4449
  this['persistence'].update_referrer_info(document$1.referrer);
@@ -4457,6 +4480,55 @@
4457
4480
  return dt.track.apply(dt, args);
4458
4481
  };
4459
4482
 
4483
+ MixpanelLib.prototype._init_url_change_tracking = function(track_pageview_option) {
4484
+ var previous_tracked_url = '';
4485
+ var tracked = this.track_pageview();
4486
+ if (tracked) {
4487
+ previous_tracked_url = _.info.currentUrl();
4488
+ }
4489
+
4490
+ if (_.include(['full-url', 'url-with-path-and-query-string', 'url-with-path'], track_pageview_option)) {
4491
+ window$1.addEventListener('popstate', function() {
4492
+ window$1.dispatchEvent(new Event('mp_locationchange'));
4493
+ });
4494
+ window$1.addEventListener('hashchange', function() {
4495
+ window$1.dispatchEvent(new Event('mp_locationchange'));
4496
+ });
4497
+ var nativePushState = window$1.history.pushState;
4498
+ if (typeof nativePushState === 'function') {
4499
+ window$1.history.pushState = function(state, unused, url) {
4500
+ nativePushState.call(window$1.history, state, unused, url);
4501
+ window$1.dispatchEvent(new Event('mp_locationchange'));
4502
+ };
4503
+ }
4504
+ var nativeReplaceState = window$1.history.replaceState;
4505
+ if (typeof nativeReplaceState === 'function') {
4506
+ window$1.history.replaceState = function(state, unused, url) {
4507
+ nativeReplaceState.call(window$1.history, state, unused, url);
4508
+ window$1.dispatchEvent(new Event('mp_locationchange'));
4509
+ };
4510
+ }
4511
+ window$1.addEventListener('mp_locationchange', function() {
4512
+ var current_url = _.info.currentUrl();
4513
+ var should_track = false;
4514
+ if (track_pageview_option === 'full-url') {
4515
+ should_track = current_url !== previous_tracked_url;
4516
+ } else if (track_pageview_option === 'url-with-path-and-query-string') {
4517
+ should_track = current_url.split('#')[0] !== previous_tracked_url.split('#')[0];
4518
+ } else if (track_pageview_option === 'url-with-path') {
4519
+ should_track = current_url.split('#')[0].split('?')[0] !== previous_tracked_url.split('#')[0].split('?')[0];
4520
+ }
4521
+
4522
+ if (should_track) {
4523
+ var tracked = this.track_pageview();
4524
+ if (tracked) {
4525
+ previous_tracked_url = current_url;
4526
+ }
4527
+ }
4528
+ }.bind(this));
4529
+ }
4530
+ };
4531
+
4460
4532
  /**
4461
4533
  * _prepare_callback() should be called by callers of _send_request for use
4462
4534
  * as the callback argument.
@@ -4925,7 +4997,7 @@
4925
4997
  // update properties with pageview info and super-properties
4926
4998
  properties = _.extend(
4927
4999
  {},
4928
- _.info.properties(),
5000
+ _.info.properties({'mp_loader': this.get_config('mp_loader')}),
4929
5001
  marketing_properties,
4930
5002
  this['persistence'].properties(),
4931
5003
  this.unpersisted_superprops,
@@ -5089,10 +5161,9 @@
5089
5161
 
5090
5162
  /**
5091
5163
  * Track a default Mixpanel page view event, which includes extra default event properties to
5092
- * improve page view data. The `config.track_pageview` option for <a href="#mixpanelinit">mixpanel.init()</a>
5093
- * may be turned on for tracking page loads automatically.
5164
+ * improve page view data.
5094
5165
  *
5095
- * ### Usage
5166
+ * ### Usage:
5096
5167
  *
5097
5168
  * // track a default $mp_web_page_view event
5098
5169
  * mixpanel.track_pageview();
@@ -5109,6 +5180,23 @@
5109
5180
  * // views on different products or internal applications that are considered completely separate
5110
5181
  * mixpanel.track_pageview({'page': 'customer-search'}, {'event_name': '[internal] Admin Page View'});
5111
5182
  *
5183
+ * ### Notes:
5184
+ *
5185
+ * The `config.track_pageview` option for <a href="#mixpanelinit">mixpanel.init()</a>
5186
+ * may be turned on for tracking page loads automatically.
5187
+ *
5188
+ * // track only page loads
5189
+ * mixpanel.init(PROJECT_TOKEN, {track_pageview: true});
5190
+ *
5191
+ * // track when the URL changes in any manner
5192
+ * mixpanel.init(PROJECT_TOKEN, {track_pageview: 'full-url'});
5193
+ *
5194
+ * // track when the URL changes, ignoring any changes in the hash part
5195
+ * mixpanel.init(PROJECT_TOKEN, {track_pageview: 'url-with-path-and-query-string'});
5196
+ *
5197
+ * // track when the path changes, ignoring any query parameter or hash changes
5198
+ * mixpanel.init(PROJECT_TOKEN, {track_pageview: 'url-with-path'});
5199
+ *
5112
5200
  * @param {Object} [properties] An optional set of additional properties to send with the page view event
5113
5201
  * @param {Object} [options] Page view tracking options
5114
5202
  * @param {String} [options.event_name] - Alternate name for the tracking event
@@ -5859,7 +5947,7 @@
5859
5947
  /**
5860
5948
  * Opt the user in to data tracking and cookies/localstorage for this Mixpanel instance
5861
5949
  *
5862
- * ### Usage
5950
+ * ### Usage:
5863
5951
  *
5864
5952
  * // opt user in
5865
5953
  * mixpanel.opt_in_tracking();
@@ -5899,7 +5987,7 @@
5899
5987
  /**
5900
5988
  * Opt the user out of data tracking and cookies/localstorage for this Mixpanel instance
5901
5989
  *
5902
- * ### Usage
5990
+ * ### Usage:
5903
5991
  *
5904
5992
  * // opt user out
5905
5993
  * mixpanel.opt_out_tracking();
@@ -5940,7 +6028,7 @@
5940
6028
  /**
5941
6029
  * Check whether the user has opted in to data tracking and cookies/localstorage for this Mixpanel instance
5942
6030
  *
5943
- * ### Usage
6031
+ * ### Usage:
5944
6032
  *
5945
6033
  * var has_opted_in = mixpanel.has_opted_in_tracking();
5946
6034
  * // use has_opted_in value
@@ -5957,7 +6045,7 @@
5957
6045
  /**
5958
6046
  * Check whether the user has opted out of data tracking and cookies/localstorage for this Mixpanel instance
5959
6047
  *
5960
- * ### Usage
6048
+ * ### Usage:
5961
6049
  *
5962
6050
  * var has_opted_out = mixpanel.has_opted_out_tracking();
5963
6051
  * // use has_opted_out value
@@ -5974,7 +6062,7 @@
5974
6062
  /**
5975
6063
  * Clear the user's opt in/out status of data tracking and cookies/localstorage for this Mixpanel instance
5976
6064
  *
5977
- * ### Usage
6065
+ * ### Usage:
5978
6066
  *
5979
6067
  * // clear user's opt-in/out status
5980
6068
  * mixpanel.clear_opt_in_out_tracking();
@@ -78,6 +78,20 @@ ___
78
78
  Clear the user's opt in/out status of data tracking and cookies/localstorage for this Mixpanel instance
79
79
 
80
80
 
81
+ ### Usage:
82
+
83
+ ```javascript
84
+ // clear user's opt-in/out status
85
+ mixpanel.clear_opt_in_out_tracking();
86
+
87
+ // clear user's opt-in/out status with specific cookie configuration - should match
88
+ // configuration used when opt_in_tracking/opt_out_tracking methods were called.
89
+ mixpanel.clear_opt_in_out_tracking({
90
+ cookie_expiration: 30,
91
+ secure_cookie: true
92
+ });
93
+ ```
94
+
81
95
 
82
96
 
83
97
  | Argument | Type | Description |
@@ -189,6 +203,13 @@ ___
189
203
  Check whether the user has opted in to data tracking and cookies/localstorage for this Mixpanel instance
190
204
 
191
205
 
206
+ ### Usage:
207
+
208
+ ```javascript
209
+ var has_opted_in = mixpanel.has_opted_in_tracking();
210
+ // use has_opted_in value
211
+ ```
212
+
192
213
 
193
214
 
194
215
  | Argument | Type | Description |
@@ -207,6 +228,13 @@ ___
207
228
  Check whether the user has opted out of data tracking and cookies/localstorage for this Mixpanel instance
208
229
 
209
230
 
231
+ ### Usage:
232
+
233
+ ```javascript
234
+ var has_opted_out = mixpanel.has_opted_out_tracking();
235
+ // use has_opted_out value
236
+ ```
237
+
210
238
 
211
239
 
212
240
  | Argument | Type | Description |
@@ -271,6 +299,23 @@ ___
271
299
  Opt the user in to data tracking and cookies/localstorage for this Mixpanel instance
272
300
 
273
301
 
302
+ ### Usage:
303
+
304
+ ```javascript
305
+ // opt user in
306
+ mixpanel.opt_in_tracking();
307
+
308
+ // opt user in with specific event name, properties, cookie configuration
309
+ mixpanel.opt_in_tracking({
310
+ track_event_name: 'User opted in',
311
+ track_event_properties: {
312
+ 'Email': 'jdoe@example.com'
313
+ },
314
+ cookie_expiration: 30,
315
+ secure_cookie: true
316
+ });
317
+ ```
318
+
274
319
 
275
320
 
276
321
  | Argument | Type | Description |
@@ -294,6 +339,19 @@ ___
294
339
  Opt the user out of data tracking and cookies/localstorage for this Mixpanel instance
295
340
 
296
341
 
342
+ ### Usage:
343
+
344
+ ```javascript
345
+ // opt user out
346
+ mixpanel.opt_out_tracking();
347
+
348
+ // opt user out with different cookie configuration from Mixpanel instance
349
+ mixpanel.opt_out_tracking({
350
+ cookie_expiration: 30,
351
+ secure_cookie: true
352
+ });
353
+ ```
354
+
297
355
 
298
356
 
299
357
  | Argument | Type | Description |
@@ -438,6 +496,16 @@ The default config is:
438
496
 
439
497
  ```javascript
440
498
  {
499
+ // host for requests (customizable for e.g. a local proxy)
500
+ api_host: 'https://api-js.mixpanel.com',
501
+
502
+ // endpoints for different types of requests
503
+ api_routes: {
504
+ track: 'track/',
505
+ engage: 'engage/',
506
+ groups: 'groups/',
507
+ }
508
+
441
509
  // HTTP method for tracking requests
442
510
  api_method: 'POST'
443
511
 
@@ -696,9 +764,47 @@ If you pass a function in as the properties argument, the function will receive
696
764
 
697
765
  ___
698
766
  ## mixpanel.track_pageview
699
- Track a default Mixpanel page view event, which includes extra default event properties to improve page view data. The <code>config.track_pageview</code> option for <a href="#mixpanelinit">mixpanel.init()</a> may be turned on for tracking page loads automatically.
767
+ Track a default Mixpanel page view event, which includes extra default event properties to improve page view data.
768
+
769
+
770
+ ### Usage:
771
+
772
+ ```javascript
773
+ // track a default $mp_web_page_view event
774
+ mixpanel.track_pageview();
775
+
776
+ // track a page view event with additional event properties
777
+ mixpanel.track_pageview({'ab_test_variant': 'card-layout-b'});
700
778
 
779
+ // example approach to track page views on different page types as event properties
780
+ mixpanel.track_pageview({'page': 'pricing'});
781
+ mixpanel.track_pageview({'page': 'homepage'});
701
782
 
783
+ // UNCOMMON: Tracking a page view event with a custom event_name option. NOT expected to be used for
784
+ // individual pages on the same site or product. Use cases for custom event_name may be page
785
+ // views on different products or internal applications that are considered completely separate
786
+ mixpanel.track_pageview({'page': 'customer-search'}, {'event_name': '[internal] Admin Page View'});
787
+
788
+ ```
789
+
790
+
791
+ ### Notes:
792
+ The <code>config.track_pageview</code> option for <a href="#mixpanelinit">mixpanel.init()</a> may be turned on for tracking page loads automatically.
793
+
794
+
795
+ ```javascript
796
+ // track only page loads
797
+ mixpanel.init(PROJECT_TOKEN, {track_pageview: true});
798
+
799
+ // track when the URL changes in any manner
800
+ mixpanel.init(PROJECT_TOKEN, {track_pageview: 'full-url'});
801
+
802
+ // track when the URL changes, ignoring any changes in the hash part
803
+ mixpanel.init(PROJECT_TOKEN, {track_pageview: 'url-with-path-and-query-string'});
804
+
805
+ // track when the path changes, ignoring any query parameter or hash changes
806
+ mixpanel.init(PROJECT_TOKEN, {track_pageview: 'url-with-path'});
807
+ ```
702
808
 
703
809
 
704
810
  | Argument | Type | Description |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixpanel-browser",
3
- "version": "2.48.0",
3
+ "version": "2.49.0",
4
4
  "description": "The official Mixpanel JavaScript browser client library",
5
5
  "main": "dist/mixpanel.cjs.js",
6
6
  "directories": {
package/src/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var Config = {
2
2
  DEBUG: false,
3
- LIB_VERSION: '2.48.0'
3
+ LIB_VERSION: '2.49.0'
4
4
  };
5
5
 
6
6
  export default Config;
@@ -0,0 +1,4 @@
1
+ /* eslint camelcase: "off" */
2
+ import { init_from_snippet } from '../mixpanel-core';
3
+
4
+ init_from_snippet();
@@ -1,5 +1,5 @@
1
1
  /* eslint camelcase: "off" */
2
- import { init_as_module } from './mixpanel-core';
2
+ import { init_as_module } from '../mixpanel-core';
3
3
 
4
4
  var mixpanel = init_as_module();
5
5
 
@@ -0,0 +1,143 @@
1
+ import './mixpanel-jslib-snippet';
2
+
3
+ /*
4
+ * @see src/loaders/mixpanel-js-wrapper.md
5
+ */
6
+ (function (win, wrapper) {
7
+
8
+ // If window.mixpanel doesn't exist, return
9
+ if (!win['mixpanel'] || typeof win['mixpanel']['init'] !== 'function') return;
10
+
11
+ // Enumerate available commands
12
+ var commandEnum = [
13
+ 'add_group',
14
+ 'alias',
15
+ 'clear_opt_in_out_tracking',
16
+ 'disable',
17
+ /* Ignore getters
18
+ 'get_config',
19
+ 'get_distinct_id',
20
+ 'get_group',
21
+ 'get_property',
22
+ 'has_opted_in_tracking',
23
+ 'has_opted_out_tracking',
24
+ */
25
+ /* Ignore init
26
+ 'init'
27
+ */
28
+ 'identify',
29
+ 'opt_in_tracking',
30
+ 'opt_out_tracking',
31
+ /* Ignore push
32
+ 'push',
33
+ */
34
+ 'register',
35
+ 'register_once',
36
+ 'remove_group',
37
+ 'reset',
38
+ 'set_config',
39
+ 'set_group',
40
+ 'time_event',
41
+ 'track',
42
+ 'track_forms',
43
+ 'track_links',
44
+ 'track_pageview',
45
+ 'track_with_groups',
46
+ 'unregister',
47
+ 'people.append',
48
+ 'people.clear_charges',
49
+ 'people.delete_user',
50
+ 'people.increment',
51
+ 'people.remove',
52
+ 'people.set',
53
+ 'people.set_once',
54
+ 'people.track_charge',
55
+ 'people.union',
56
+ 'people.unset',
57
+ 'group.remove',
58
+ 'group.set',
59
+ 'group.set_once',
60
+ 'group.union',
61
+ 'group.unset'
62
+ ];
63
+
64
+ /* The people API can't be used with the .push() interface, so it requires its
65
+ * own helper method. To interact with it, simply use the _mixpanel interface
66
+ * as before.
67
+ *
68
+ * window._mixpanel('<libraryName.>people.set', 'gender', 'm');
69
+ *
70
+ */
71
+ var people = function (mp, cmd, args) {
72
+ // Extract the command
73
+ var peopleCmd = cmd.split('.').pop();
74
+
75
+ // Call the respective mixpanel method
76
+ mp['people'][peopleCmd].apply(mp['people'], args);
77
+ };
78
+
79
+ /* To utilize the group API, the command must include the group key and ID as
80
+ * an array in the second argument.
81
+ *
82
+ * window._mixpanel('<libraryName.>.group.set', ['group_key', 'group_id'], {
83
+ * someGroupProperty: 'someGroupValue'
84
+ * });
85
+ *
86
+ */
87
+ var group = function (mp, cmd, args) {
88
+ // Extract the command
89
+ var groupCmd = cmd.split('.').pop();
90
+
91
+ // Extract the group info
92
+ var groupInfo = args.shift();
93
+
94
+ // Validate the group array
95
+ if (!Array.isArray(groupInfo) || groupInfo.length !== 2) return;
96
+
97
+ // Get group reference
98
+ var group = mp['get_group'].apply(mp, groupInfo);
99
+
100
+ // Call the respective group method
101
+ group[groupCmd].apply(group, args);
102
+
103
+ };
104
+
105
+ // Build the command wrapper logic
106
+ win[wrapper] = win[wrapper] || function () {
107
+
108
+ // Build array out of arguments
109
+ var args = [].slice.call(arguments, 0);
110
+
111
+ // Pick the first argument as the command
112
+ var cmd = args.shift();
113
+
114
+ /* Commands can be passed to different namespaces with syntax:
115
+ * window._mixpanel('libraryName.command', arguments)
116
+ */
117
+ var libraryName = null;
118
+ var cmdParts = cmd.match(/^([^.]+)\.(.+)$/);
119
+ if (cmdParts && cmdParts.length === 3 && !/people|group/.test(cmdParts[1])) {
120
+ libraryName = cmdParts[1];
121
+ cmd = cmdParts[2];
122
+ }
123
+
124
+ // If libraryName is set, use that as the mixpanel interface
125
+ var mp = libraryName ? window['mixpanel'][libraryName] : window['mixpanel'];
126
+
127
+ // Return if namespace not found
128
+ if (!mp) return;
129
+
130
+ // If cmd is not one of the available ones, return
131
+ if (commandEnum.indexOf(cmd) === -1) return;
132
+
133
+ // Handle people command
134
+ if (/^people\./.test(cmd)) return people(mp, cmd, args);
135
+
136
+ // Handle group command
137
+ if (/^group\./.test(cmd)) return group(mp, cmd, args);
138
+
139
+ // Push the command to mixpanel
140
+ return mp.push.apply(mp, [[cmd].concat(args)]);
141
+
142
+ };
143
+ })(window, '_mixpanel');