diff --git a/pages/docs/tracking-methods/sdks/javascript.md b/pages/docs/tracking-methods/sdks/javascript.md new file mode 100644 index 0000000000..0de02b253e --- /dev/null +++ b/pages/docs/tracking-methods/sdks/javascript.md @@ -0,0 +1,473 @@ +# Mixpanel SDKs: Javascript + +## Getting Started + +Please refer to our [Quickstart Guide](/docs/quickstart/connect-your-data?sdk=javascript). + +The [Full API Reference](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanel), [Library Source Code](https://github.com/mixpanel/mixpanel-js), and an [Example Application](https://github.com/mixpanel/mixpanel-js/tree/master/examples) is documented in our GitHub repo. + +## Track Events + +### Sending Events +Once you have the snippet in your page, you can track an event by calling `mixpanel.track()` with the event name and properties. +```javascript JavaScript +// Send a "Played song" event to Mixpanel +// with a property "genre" +mixpanel.track( + "Played song", + {"genre": "hip-hop"} +); +``` + +All events sent from the JavaScript library will be sent over HTTPS. + +### Tracking Page Views + +Page view tracking is turned off by default. Page view events can be added automatically on every page load by using the `track_pageview` option to the `mixpanel.init` call, like so: + +```javascript JavaScript +mixpanel.init('YOUR_TOKEN', {track_pageview: true}); +``` + +The default `track_pageview` setting does not auto-track page views in single-page applications. For tracking dynamic page views in single-page applications, the `track_pageview` option can also accept the following values for tracking. + +```javascript JavaScript +// Track when the path changes, ignoring any query string or hash changes +mixpanel.init('YOUR_TOKEN', {track_pageview: "url-with-path"}); + +// Track when the path or query string change, ignoring hash changes +mixpanel.init('YOUR_TOKEN', {track_pageview: "url-with-path-and-query-string"}); + +// Track any URL changes in the path, query string, or hash +mixpanel.init('YOUR_TOKEN', {track_pageview: "full-url"}); +``` + +The standard page view event (`$mp_web_page_view`) includes the page title (`current_page_title`), URL components (`current_domain`, `current_url_path`, `current_url_protocol`, `current_url_search`), and [marketing parameters](/docs/tracking-methods/sdks/javascript#tracking-utm-parameters) described below. Additional page view event properties can also be added as event properties. + +```javascript JavaScript +// Send a default page view event +mixpanel.track_pageview(); + +// Send a default page view event with additional properties +mixpanel.track_pageview({"page": "Pricing"}); +``` + +### Tracking UTM Parameters + +The JavaScript library will automatically add any UTM parameters (`utm_source`, `utm_campaign`, `utm_medium`, `utm_term`, `utm_content`, `utm_id`, `utm_source_platform`, `utm_campaign_id`, `utm_creative_format`, `utm_marketing_tactic`) present on the page to events fired from that page load. Please note when configuring UTMs that UTM tracking is case sensitive, and should be formatted lower-case as shown in the examples above. + +When UTM parameters for an identified user are seen for the first time, these will also be stored on the user profile as `initial_utm_source`, `initial_utm_campaign`, `initial_utm_medium`, `initial_utm_term`, `initial_utm_content`, `initial_utm_id`, `initial_utm_source_platform`, `initial_utm_campaign_id`, `initial_utm_creative_format`, and `initial_utm_marketing_tactic`. + +In addition to UTM parameters, Mixpanel will also add any advertising click IDs to events fired. These include `dclid`, `fbclid`, `gclid`, `ko_click_id`, `li_fat_id`, `msclkid`, `sccid`, `ttclid`, `twclid`, `wbraid`. + +> Note: UTM parameters are by default persisted as [Super Properties](/docs/tracking-methods/sdks/javascript#super-properties). To disable this behavior, use the SDK initialization option `{stop_utm_persistence: true}` (refer to our [Release Notes](https://github.com/mixpanel/mixpanel-js/releases/tag/v2.52.0) in GitHub). + +### Tracking Website Links + +When tracking link clicks with [`mixpanel.track()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpaneltrack), the page can change before the event is successfully sent, leading to inaccurate results. + +To make this easier, use [`mixpanel.track_links()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpaneltrack_links). This function will allow you to bind an event to a link click with much greater accuracy. + +Here's how it works: +```javascript JavaScript + + +``` + +This will send a "click nav link" event (with a "referrer" property) each time a user clicks on a navigation link. It's important to note that the links matched by the CSS selector must exist on the page at the time the `mixpanel.track_links()` call is made, or it will not bind correctly. + +### Other Tracking Methods +There are other less common ways to send data to Mixpanel. To learn more, please refer to the [full API documentation](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanel). + +[`mixpanel.track_forms()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpaneltrack_forms) - similar to `mixpanel.track_links()`, but tracks form submissions. + +### Mixpanel Cookie +By default, Mixpanel cookies send over HTTPS requests as part of the headers. However, Mixpanel’s JavaScript library provides a configuration to completely prevent the browser from transmitting your cookies with non-HTTPS requests. + +To enable this, use the [`set_config()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanelset_config) method and change the `secure_cookie` flag from `false` to `true`. If you configure your instance to send data over HTTP instead of HTTPS but do set `secure_cookie: true`, then your cookie data is not sent to the server. + +#### Mixpanel Cookies for Hosted Subdomains +The Mixpanel JavaScript library has a default setting of `cross_subdomain_cookie: true` in the `mixpanel.init` function. This enables Mixpanel cookies to work across subdomains, keeping Mixpanel's Distinct ID and [Super Properties](/docs/tracking-methods/sdks/javascript#super-properties) consistent across these sub-domains. + +However, if your site is hosted on a domain like Heroku (or similar - [see a complete list of affected domains](https://publicsuffix.org/list/effective_tld_names.dat)) with a URL like XYZ.herokuapp.com, cross-subdomain cookies are not allowed for security reasons. Having Mixpanel default settings for `cross_subdomain_cookie` on these sites, results to users' Distinct IDs being reset to a new `$distinct_id` on each page load. This will cause issues with Mixpanel reports, namely broken Retention reports and Funnels. + +For domains that don't allow cross-subdomain cookies, you should be setting `cross_subdomain_cookie: false`. Alternatively, you can also use a CNAME to change from yourdomain.herokuapp.com to yourdomain.com. + + +### Super Properties + +It's very common to have certain properties that you want to include with each event you send. Generally, these are things you know about the user rather than about a specific event - for example, the user's age, gender, source, or initial referrer. + +To make things easier, you can register these properties as super properties. If you tell us just once that these properties are important, we will automatically include them with all events sent. Super properties are stored in a browser cookie, and will persist between visits to your site. Mixpanel already stores some information as super properties by default; see a full list of Mixpanel default properties [here](/docs/data-structure/property-reference/properties). + +To set super properties, call [`mixpanel.register()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanelregister). + +```javascript JavaScript + +``` + +The next time you track an event, the super properties you just set will be included as properties. If you call: +```javascript JavaScript +mixpanel.track("Signup"); +``` + +after making the previous call to `mixpanel.register()`, it is just like adding the properties directly: +```javascript JavaScript +mixpanel.track("Signup", { + "age": 28, + "gender": "male", + "source": "facebook" +}); +``` + +#### Setting Super Properties Only Once + +If you want to store a super property only once (often for things like initial referrer, ad campaign, or source), you can use [`mixpanel.register_once()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanelregister_once). This function behaves like `mixpanel.register()` and has the same interface, but it doesn't override super properties you've already saved. + +```javascript JavaScript + +``` + +This means that it's safe to call `mixpanel.register_once()` with the same property on every page load, and it will only set it if the super property doesn't exist. + +#### Super Properties Live in a Cookie +Our JS library uses a cookie (created in the domain of the page loading the lib) to store super properties. These are stored as JSON in the cookie. They will persist for the life of that cookie, which by default is 365 days. If you wish to change the life of the cookie, you may do so using [`set_config()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanelset_config) to adjust the value for the `cookie_expiration` (an integer in days). + +## Managing User Identity + +You can handle the identity of a user using the `identify()` and `alias()` methods. Proper use of these methods can connect events to the correct user as they move across devices, browsers, and other platforms. + +### Identify +Identify a user with a unique ID to track user activity across devices, tie a user to their events, and create a user profile. If you never call this method, unique visitors are tracked using a UUID that generates the first time they visit the site. + +Call `identify()` when you know the identity of the current user, typically after log-in or sign-up. We recommend against using `identify()` for anonymous visitors to your site. + +```javascript JavaScript +// after log-in or sign-up: +mixpanel.identify("13793"); +``` + +### Call Reset at Logout +[`Reset()`](https://github.com/mixpanel/mixpanel-js/blob/master/doc/readme.io/javascript-full-api-reference.md#mixpanelreset) generates a new random distinct_id and clears super properties. Call `reset()` to clear data attributed to a user when that user logs out. This allows you to handle multiple users on a single device. For more information about maintaining user identity, see the [Identifying Users](/docs/tracking-methods/id-management/identifying-users) article. + +```javascript JavaScript +// after logout: +mixpanel.reset(); +``` + +## Storing User Profiles + +In addition to events, you can store user profiles in Mixpanel. Profiles are persistent sets of properties that describe a user - things like name, email address, and signup date. You can use profiles to explore and segment users by who they are, rather than what they did. + +*Please take note of the [reserved profile properties](/docs/data-structure/user-profiles#reserved-user-properties) (e.g. `$name`, `$email`) which receive special treatment in our UI or are used for special processing. + +### Setting Profile Properties + +You can set properties on a user profile with `mixpanel.people.set`. +```javascript JavaScript +// mixpanel.identify must be called in order to associate the profile properties you set +// with that user. You only need to call it once per page load for a given user. +mixpanel.identify("13793"); + +mixpanel.people.set({ "Plan": "Premium" }); +``` + +This will set a "Plan" property, with a value "Premium", on user 13793's profile. If there isn't a profile with distinct_id 13793 in Mixpanel already, a new profile will be created. If user 13793 already has a property named "Plan" in their profile, the old value will be overwritten with "Premium". + +#### Other Types Of Profile Updates + +There are a few other types of profile updates + + * `mixpanel.people.set_once` - set properties if they don't exist + * `mixpanel.people.append` - append to a list property + * `mixpanel.people.union` - append to a list property, excluding duplicates + +### Incrementing Numeric Properties + +You can use `mixpanel.people.increment` to change the current value of numeric properties. This is useful when you want to keep a running tally of things, such as games played, messages sent, or points earned. + +```javascript JavaScript +// If no number is passed, the default is to increment by 1 +mixpanel.people.increment("games played"); + +// You can also pass a number to increment +// Here we add 500 to the user's point count +mixpanel.people.increment("points earned", 500); + +// Pass an object to increment multiple properties +mixpanel.people.increment({ + "dollars spent": 17, + // Subtract by passing a negative value + "credits remaining": -34 +}); +``` + +## Debug Mode + +Debug Mode allows you to see the requests being sent by your implementation to Mixpanel, in real time, from your browser's developer console. This includes events (with their properties), as well as other types of requests such as `identify` and `alias`. It also exposes SDK errors and warnings that occur before data is sent to Mixpanel. Debug mode works with both NPM and HTML snippet implementations, but the setup process differs slightly. + +### Start Debugging + +**If you implemented using NPM**, you will need to add the `debug` parameter to your `mixpanel.init` call, like so: + +```jsx +mixpanel.init('YOUR_TOKEN', {debug: true}); +``` + +Be sure to remove this parameter before going into production; we suggest setting this parameter conditionally, based on the environment your implementation is running in (e.g. `true` for dev and staging; `false` for production). + +**If you implemented using the HTML snippet**, you can enable debug mode either in code (as above), or you can enable it directly from your developer tools console, without making any code changes. This is because the `mixpanel` object is globally accessible from the snippet, so you can open your devtools console and simply run `mixpanel.set_config({debug: true})` to enable debug mode. + +### Interpreting Debug Output + +![image](/230696892-8fb6e415-bd0a-4e0a-a9ef-a121ccda3600.png) + +Here, we are debugging an HTML snippet implementation, but the logs are the same regardless of how you enabled debug mode. These events are being sent normally — each batch of events can be expanded to see the properties being sent with the event. Logging for other types of Mixpanel requests, such as `identify` and `alias`, works the same way, with all request contents logged. + +SDK errors and warnings, such as calling `track` without an event name and `alias`ing an identifier to itself, are also logged to the console in debug mode. These client-side errors do not result in an request to Mixpanel, so they can't be debugged using the network tab — you must use debug mode to surface them. + +![image](/230696898-b839468c-e3a4-444a-ae2c-ae419c44be56.png) + + +## Group Analytics +Mixpanel Group Analytics is a paid add-on that allows behavioral data analysis by selected groups, as opposed to individual users. + +Grouping by identifiers other than the `distinct_id` will allow analysis at a company or group level when using Mixpanel analytics. Read [this article](/docs/data-structure/advanced/group-analytics) to learn more about Group Analytics. + +A group is identified by the `group_key` and `group_id`. +* `group_key` is the property that connects event data for Group Analytics. +* `group_id` is the identifier for a specific group. + +If the property “company” is chosen for Group Analytics, “company” is the `group_key`, and “Mixpanel”, “Company A”, and “13254” are all potential `group_id` values. + +A user can belong to multiple groups. All updates to a group operate on the `group_key` and `group_id`. + +### Creating a Group Key +Administer group keys through your Project Settings. Group keys are event properties. All events need to have a defined group key on them in order to be attributed to a group. Group keys are project specific, and the group key should be set up before group data is sent. Note that Mixpanel does not backfill historical data before the group key was implemented. + +To administer group keys, navigate to your Project Settings. Click **+Add Group Key** under the *GROUP KEYS* section. + +### Adding Users to a Group +Adding users to groups causes the `group_key` and `group_id` to send as a property key and value for all events triggered by that user on the device. You can add multiple values for a single user to the `group_key` list property. + +Similar to a `distinct_id`, the `group_key` allows Mixpanel to group events by an identifier for analysis. A `group_key`, however, is a group level identifier and not a user level identifier like the `distinct_id`. + +You can add users to groups by calling the [`mixpanel.set_group()`](/docs/tracking-methods/sdks/javascript#setting-group-profile-properties) method. + +```javascript JavaScript +//Assign Company A and Company B to a user +mixpanel.set_group(“company”, [“Company A”, “Company B”]) +``` + +You can call [`mixpanel.add_group()`](/docs/tracking-methods/sdks/javascript#creating-group-profiles) to add any additional groups to an existing list. + +```javascript JavaScript +//Add “Mixpanel” to the list of existing groups +mixpanel.add_group(“company”, “Mixpanel”) +``` + +### Creating Group Profiles +It is possible to create a Group profile that is similar to a user profile. You must call [`mixpanel.set_group()`](/docs/tracking-methods/sdks/javascript#setting-group-profile-properties) to build a group profile. It is important to set the `group_key`, `group_id`, and at least one property so that the profile is not empty. +```javascript JavaScript +mixpanel.get_group(group_key, group_id).set({“property_name”: property_value}) +``` + +### Setting Group Profile Properties +You can add details to Groups by adding properties to them. + +In order to update Group profile properties, you must specify the group that needs to be updated by calling [`get_group()`](/docs/tracking-methods/sdks/javascript#group-analytics) +```javascript JavaScript +mixpanel.get_group(“company”, “Mixpanel”) +``` +The [`get_group()`](/docs/tracking-methods/sdks/javascript#group-analytics) method can be chained with other commands that edit properties specific to the group. + +You can set the property `$name` to populate the name field at the top of the group profile. + +These operations are similar to the corresponding operations for user profile property updates. +#### set +`mixpanel.get_group().set` updates or adds a property to a group. + +```javascript JavaScript +mixpanel.get_group(group_key, group_id).set({“property_name”: property_value}) +``` +#### set once +`mixpanel.get_group().set_once` adds a property value to a group only if it has not been set before. + +```javascript JavaScript +mixpanel.get_group(group_key, group_id).set_once({“property_name”: property_value}) +``` + +#### unset +`mixpanel.get_group().unset` unsets a specific property in the group. + +```javascript JavaScript +mixpanel.get_group(group_key, group_id).unset(“property_name”) +``` + +#### remove +`mixpanel.get_group().remove` removes a specific value in a list property. +```javascript JavaScript +mixpanel.get_group(group_key, group_id).remove(“property_name”, “property_value”) +``` + +#### union +`mixpanel.get_group().union` adds the specified values to a list property and ensures that those values only appear once. +```javascript JavaScript +mixpanel.get_group(group_key, group_id).union(“property_name”, [property_value1, … [property_valueN]) +``` +## EU Data Residency + +Route data to Mixpanel's EU servers by setting the `api_host` config property. +```javascript +mixpanel.init( + "YOUR_TOKEN", + { + api_host: "https://api-eu.mixpanel.com", + }, +); +``` +## Tracking Via Proxy + +This guide demonstrates how to route events from Mixpanel's SDKs via a proxy in your own domain. This is useful when tracking from the web, to reduce the likelihood of ad-blockers impacting your tracking. + +![image](https://github.com/mixpanel/docs/assets/2077899/3ec6f3c2-aed0-4a18-9395-36838c3b53f1) + +There are two steps: setting up a proxy server and pointing our JavaScript SDK at your server. + +**Step 1: Set up a proxy server** +The simplest way is to use our [sample nginx config](https://github.com/mixpanel/tracking-proxy). This config redirects any calls made to your proxy server to Mixpanel. + +**Step 2: Point our JavaScript SDK at your server** +Add the following line before the Mixpanel JS snippet, replacing `YOUR_PROXY_DOMAIN` with your proxy server's domain. This is not required if you use npm or yarn instead of the snippet: +```js +const MIXPANEL_CUSTOM_LIB_URL = "https:///lib.min.js"; +``` + +Add your proxy server to the `mixpanel.init` call: + +```js +mixpanel.init("", {api_host: "https://"}) +``` + +🎉 Congratulations, you've set up tracking through a proxy server! Here's a [full code sample](https://gist.github.com/ranic/80459104def4e4bcd73d5c77b817ee43). + +## Session Replay + +> Session Replay is currently available as an add-on purchase for Enterprise plans. + +Capture and replay data on how a user interacts with your application. Replay collection is disabled by default, and the Replay portion of the SDK will not be loaded into your application until specified. To use this feature, you must be on at least version 2.50.0 of our JavaScript SDK. + +Before you enable Session Replay for a large audience, we recommend testing in a demo project, and starting in production with smaller sets of users or accounts, so that you can monitor performance and ensure your privacy rules align with company policies. + +### Sampling Method + +The easiest way to begin capturing session replays is by sampling a subset of users, specified during initialization: + +```javascript +mixpanel.init( + "", + { + record_sessions_percent: 1 //records 1% of all sessions + } +) +``` + +Start with a smaller percentage and tune to fit your analytics needs. + +If you already have the JS SDK installed, this is the only code change you need to start capturing session replays. + +### Init Options + +| Option | Description | Default | +| --- | --- | --- | +| `record_block_class` | CSS class name or regular expression for elements which will be replaced with an empty element of the same dimensions, blocking all contents. | `new RegExp('^(mp-block\|fs-exclude\|amp-block\|rr-block\|ph-no-capture)$')`
(common industry block classes) | +| `record_block_selector` | CSS selector for elements which will be replaced with an empty element of the same dimensions, blocking all contents. | `"img, video"` | +| `record_collect_fonts` | When true, Mixpanel will collect and store the fonts on your site to use in playback. | `false` | +| `record_idle_timeout_ms` | Duration of inactivity in milliseconds before ending a contiguous replay. A new replay collection will start when active again. | `1800000`
(30 minutes) | +| `record_mask_text_class` | CSS class name or regular expression for elements that will have their text contents masked. | `new RegExp('^(mp-mask\|fs-mask\|amp-mask\|rr-mask\|ph-mask)$')`
(common industry mask classes) | +| `record_mask_text_selector` | CSS selector for elements that will have their text contents masked. | `"*"` | +| `record_max_ms` | Maximum length of a single replay in milliseconds. Up to 24 hours is supported. Once a replay has reached the maximum length, a new one will begin. | `86400000`
(24 hours) | +| `record_min_ms` | Minimum length of a single replay in milliseconds. Up to 8 seconds is supported. If a replay does not meet the minimum length, it will be discarded. | `0`
(0 seconds) | +| `record_sessions_percent` | Percentage of SDK initializations that will qualify for replay data capture. A value of "1" = 1%. | `0` | + + +### Session Replay Methods + +We give our customers full control to customize when and where they capture session replays. + +#### Start capturing replay data + +```javascript +mixpanel.start_session_recording() +``` +This will have no effect if replay data collection is in progress. + +This is optional, and can be used primarily to programmatically start and stop recording, or exclude something specific from recording. We recommend using the [sampling method](/docs/tracking-methods/sdks/javascript#sampling-method) detailed above unless you need to customize when you capture replay data. + +#### Stop capturing replay data + +```javascript +mixpanel.stop_session_recording() +``` +This will have no effect if there is no replay data collection in progress. + + +#### Get replay properties + +Use this method to get properties used to identify a replay that is taking place. Add the properties from this method to any events sent to Mixpanel that are not coming from the SDK (e.g. from a [CDP library](/docs/session-replay/session-replay-web#can-i-use-session-replay-with-a-cdp)). + +If your Mixpanel Events are instrumented using the JavaScript SDK, these properties will automatically be added. + +```javascript +mixpanel.get_session_recording_properties() +// {$mp_replay_id: '19221397401184-063a51e0c3d58d-17525637-1d73c0-1919139740f185'} +``` +Returns an empty object if there is no Replay in progress. + +#### Example Scenarios + +| Scenario | Guidance | +| --- | --- | +| We have a sensitive screen we don't want to capture | When user is about to access the sensitive screen, call `mixpanel.stop_session_recording()`. To resume recording once they leave this screen, you can resume recording with `mixpanel.start_session_recording()` | +| We only want to record certain types of users (e.g. Free plan users only) | Using your application code, determine if current user meets the criteria of users you wish to capture. If they do, then call `mixpanel.start_session_recording()` to force recording on | +| We only want to users utilizing certain features | When user is about to access the feature you wish to capture replays for, call `mixpanel.start_session_recording()` to force recording on | + + +### Tips & Tricks While Implementing +- Search for Session Recording Checkpoint events in your project, tracked as `$mp_session_record`. When you capture Mixpanel session replays, the SDK will automatically emit this default event. If you've implemented correctly, you should see these events appear. +- Calling `mixpanel.start_session_recording()` in your website / application is a good test to see if it causes Session Recording Checkpoint event mentioned above to appear. If it does, and you're still struggling to find replays for Users and Reports, your sampling rate may not be working, or may be set too low. +- Check the home page for your project to see if there are any replays listed in the Latest Replays card. +- If you're still struggling to implement, [submit a request to our Support team](https://mixpanel.com/get-support) for more assistance. + +### Privacy +Mixpanel offers a privacy-first approach to Session Replay, including features such as data masking. Mixpanel’s Session Replay privacy controls were designed to assist customers in protecting end user privacy. Read more [here](/docs/session-replay/session-replay-web#appendix-session-replay-privacy-controls). + + +#### User Data +The Mixpanel SDK will always mask all inputs. By default, all text on a page will also be masked unless a different `record_mask_text_selector` is specified. + +Along with other data, the SDK respects all Do Not Track (DNT) settings as well as manual opt-out for any replay data. + +#### Retention +User replays are stored for 30 days after the time of ingestion. There is no way to view a replay older than 30 days old. + +## Release History +[See All Releases](https://github.com/mixpanel/mixpanel-js/releases). \ No newline at end of file