Web SDK · v0.6.0
Custom Events
Design stable custom event contracts with clear names, focused properties, and practical examples.
Use rtn.track(name, properties) when an action does not map to a built-in helper. Treat every custom event as a small data contract that dashboards, audiences, and automations may depend on.
Naming rules
Event names must begin with a lowercase letter, use snake_case, and stay within 64 characters. Prefer a completed action in past tense.
| Prefer | Avoid | Reason |
|---|---|---|
size_guide_opened | openSizeGuide | Stable snake_case contract |
promotion_clicked | click | Describes what was clicked |
review_submitted | review | Distinguishes intent from completion |
back_in_stock_requested | notify_me | Expresses the business outcome |
Product interaction example
rtn.track('size_guide_opened', {
product_id: 'sku_123',
variant_id: 'sku_123_black',
source: 'product_page',
guide: 'unisex_tops_v2'
});The event answers four questions: what happened, which product was involved, where it happened, and which guide was shown.
Promotion example
rtn.track('promotion_clicked', {
promotion_id: 'spring_homepage',
promotion_name: 'Spring arrivals',
creative: 'hero_a',
placement: 'homepage_hero',
position: 1,
destination: '/collections/spring'
});Keep promotion identifiers stable across impressions, clicks, and orders so performance can be joined later.
Wishlist example
rtn.track('product_added_to_wishlist', {
product_id: 'sku_123',
variant_id: 'sku_123_black',
name: 'Everyday Backpack',
price: 89.90,
currency: 'USD',
wishlist_id: 'wishlist_primary'
});If wishlist removal matters, use a symmetric contract:
rtn.track('product_removed_from_wishlist', {
product_id: 'sku_123',
variant_id: 'sku_123_black',
wishlist_id: 'wishlist_primary'
});Experiment exposure example
Record exposure when the customer actually sees the variant, not when the experiment assignment is calculated.
rtn.track('experiment_viewed', {
experiment_id: 'pdp_buy_button_2026_10',
variant: 'sticky_green',
surface: 'product_page'
});Property design
- Use stable IDs alongside readable names.
- Keep property names in
snake_case. - Send numbers as numbers and booleans as booleans.
- Prefer flat properties; nested data should not exceed three levels.
- Avoid sending full application state, DOM content, or API responses.
- Never place secrets, access tokens, passwords, or payment-card data in event properties.
- Avoid direct contact data in
track; useidentifyfor supported customer traits.
Shared page properties
Use register for values that belong on every later track and page event on the current page. Event properties win when the same key exists.
rtn.register({
store_id: 'store_us',
storefront_locale: 'en-US',
experiment_variant: 'checkout_b'
});
rtn.track('shipping_option_selected', {
shipping_method: 'express',
estimated_days: 2
});
rtn.unregister('experiment_variant');Do not use register for user identity. Use identify so identity follows the correct lifecycle and reset behavior.
Evolving an event
Adding an optional property is usually backward compatible. Renaming an event or changing a property's meaning is not. When semantics change, introduce a new event or a clearly versioned property and migrate consumers deliberately.
Before publishing an event, confirm:
- The name describes one completed action.
- The trigger occurs exactly once for that action.
- IDs match the systems that will consume the data.
- Properties have stable types and units.
- No sensitive or unnecessary payload is included.