> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ordergroove.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ordergroove.com/_mcp/server.

# Preserve Analytics Tracking while Customizing Subscription Manager Templates

If you are making customizations to your Subscription Manager (SM) template, be careful not to remove or change elements that our library code relies on for front-end analytics. Here is a description of how our front-end tracking works so you can avoid making changes that stop tracking certain events.

This guide assumes familiarity with HTML, CSS, and JavaScript.

## DOM Elements

The SM watches certain DOM elements to trigger tracking events. Most of these are **click** listeners that fire a tracking event when a button or link is clicked. Certain events are also triggered when a given element becomes **visible** on screen — for example, in a multi-step cancel flow. If you move or change the attributes on these elements, these events may no longer be fired.

Below is a list of the CSS selectors the SM watches, as well as what kind of interactions trigger a tracking event. If the element matches any of the selectors for an event, the tracking event is fired. The selectors are based on the position of the elements that trigger these events in the default v0 and v25 templates. Some events have multiple selectors; if any of these match, the event is fired. The SM will always check every selector listed below — for example, if you have a v25 template but a button matches a v0 selector, the tracking event will still be fired.

| Event name                                   | Type                          | CSS selectors (v25)                                                                                                                      | CSS selectors (v0)                                                           |
| :------------------------------------------- | :---------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| `skuswap_started`                            | click                         | `[data-click-target^=og-sku-swap-dialog]`                                                                                                | `.og-change-product-control > .og-link`                                      |
| `skuswap_exited`                             | click                         | `[id^=og-sku-swap-dialog] :is(.og-dialog-close, .og-dialog-footer button[type="button"])` `[id^=og-sku-swap-dialog] [data-dialog-close]` | `dialog[id^="og-change-product"] button[type="reset"]`                       |
| `skuswap_completed_swapped`                  | click                         | `[id^=og-sku-swap-dialog] button[type="submit"]`                                                                                         | `dialog[id^="og-change-product"] button[name="change_product"]`              |
| `subscriptioncancel_started`                 | click                         | `[data-click-target^=og-cancel-sub-dialog]`                                                                                              | `.og-cancel-subscription-button > .og-link`                                  |
| `subscriptioncancel_exited`                  | click                         | `[id^=og-cancel-sub-dialog] .og-dialog-close` `[id^=og-cancel-sub-dialog] [data-dialog-close]`                                           | `.og-cancel-subscription-button button[type="reset"]`                        |
| `subscriptioncancel_skuswap_shown`           | visibility                    | `[id^=og-cancel-sub-dialog] [data-step="swap"]`                                                                                          |                                                                              |
| `subscriptioncancel_completed_saved_swapped` | click                         | `[id^=og-cancel-sub-dialog] [data-step="swap"] button[type="submit"]`                                                                    |                                                                              |
| `subscriptioncancel_skuswap_backedout`       | click                         | `[id^=og-cancel-sub-dialog] [data-step="swap"] button[data-back-button]`                                                                 |                                                                              |
| `subscriptioncancel_skip_shown`              | visibility                    | `[id^=og-cancel-sub-dialog] [data-step="skip"]`                                                                                          |                                                                              |
| `subscriptioncancel_completed_saved_skipped` | click                         | `[id^=og-cancel-sub-dialog] [data-step="skip"] button[type="submit"]`                                                                    | `.og-cancel-subscription-button button[name="skip_subscription"]`            |
| `subscriptioncancel_skip_backedout`          | click                         | `[id^=og-cancel-sub-dialog] [data-step="skip"] button[data-back-button]`                                                                 |                                                                              |
| `subscriptioncancel_pause_shown`             | visibility                    | `[id^=og-cancel-sub-dialog] [data-step="pause"]`                                                                                         |                                                                              |
| `subscriptioncancel_completed_saved_paused`  | click                         | `[id^=og-cancel-sub-dialog] [data-step="pause"] button[type="submit"]`                                                                   |                                                                              |
| `subscriptioncancel_pause_backedout`         | click                         | `[id^=og-cancel-sub-dialog] [data-step="pause"] button[data-back-button]`                                                                |                                                                              |
| `subscriptioncancel_exitsurvey_shown`        | visibility (v25) / click (v0) | `[id^=og-cancel-sub-dialog] [data-step="reason"]`                                                                                        | `.og-cancel-subscription-button button[name="continue_cancel_subscription"]` |
| `subscriptioncancel_exitsurvey_backedout`    | click                         | `[id^=og-cancel-sub-dialog] [data-step="reason"] button[data-back-button]`                                                               |                                                                              |

### Preventing DOM Elements from Firing Tracking Events

If you do not want an element matching one of these selectors to fire a tracking event, you can add a `data-og-no-track` attribute to it or to a parent element. Placing this attribute on a parent element will prevent interactions with any of its descendant elements from firing a tracking event.

## Form Actions

Our code fires certain tracking events from our SM library when certain forms are submitted. For example, the `change_product` form looks like this — it will automatically trigger a handler inside our SM library that makes the appropriate API calls and fires a tracking event:

```liquid
<form
  action="{{ 'change_product' | action }}"
  @success="{{ 'SMDialog.close' | js }}"
  @reset="{{ 'SMDialog.close' | js }}"
>
```

If instead of using the existing SM form elements you directly make fetch calls from JavaScript, these tracking events will be missing. To preserve existing tracking events, continue to use our forms.

| Tracking event                          | Form action attribute |
| :-------------------------------------- | :-------------------- |
| `subscriptioncancel_completed_canceled` | `cancel_subscription` |

## Making API Calls

If you directly make fetch calls to Ordergroove APIs from your JavaScript code, add the `tracking-source: MSI` header. This allows us to attribute those actions to the SM (as opposed to a customer service agent or other processes).

## Verifying That Tracking Is Working

If you want to check that events are being fired, use your browser's dev tools and look for requests to `https://staging.collect.ordergroove.com`. You can see the event that was fired in the request body.

This API endpoint is not considered public and may have breaking changes at any time. Do not call this endpoint directly.

## Further Customization

If you want additional control over when and where tracking events are fired, reach out to your Ordergroove representative. We don't currently expose any JS APIs to directly fire tracking events, but are gathering feedback to guide our future roadmap.

If you find that a tracking event has gone missing after making SM changes, reach out to your Ordergroove representative for assistance.