Overview
Custom Events allow you to track specific user interactions or business processes that are unique to your application. For e-commerce businesses, custom events can provide invaluable insights beyond standard events like purchases or add-to-cart actions.
This guide covers setting up events in the Custom Event Builder, adding event code to your website, and querying the resulting data.
Before you begin
Install the Triple Pixel base code on your website before adding custom-event tracking.
Identify the interaction you want to measure and the properties you want to send with it.
Arrange access to your website code or Google Tag Manager.
Test your implementation in a staging environment before deploying it to production.
Updating an existing SQL query?
The custom-event data column now stores JSON-formatted text as a String. Expressions such as data.productId no longer work. Use JSON extraction functions, as shown in the querying examples below.
Use Cases for Custom Events in E-commerce
Product Customization: Track how users interact with product customization tools.
A/B Test Segment Tracking: Monitor user behavior across different test variants.
Wishlist Interactions: Monitor wishlist creation, sharing, and conversion to purchases.
Advanced Search Usage: Analyze how customers use advanced search features.
Customer Support Interactions: Track customer service chatbot usage or support ticket creation.
Virtual Try-On: For fashion or cosmetics, track usage of virtual try-on features.
Scroll Depth: Measure how far users scroll on important pages.
Get Started
Using the Custom Event Builder
Use the Custom Event Builder to define an event, specify its properties, and receive sample tracking code.
Defining properties tells Triple Whale how to make them available as separate columns for querying. This is called flattening.
You can send custom events without defining them in the builder. However, Triple Whale will not automatically flatten their properties unless you define and save the configuration.
Define your event
To track your first custom event:
Navigate to the Custom Event Builder in Triple Whale by going to Settings > Pixel Settings > Custom Events.
Click Create Your First Event.
Under Title your event, enter a name for your custom event (e.g.,
productCustomizationInteraction). Event titles are required and will be visible in the code snippet.Under Event Attribution, check Run Through Attribution if you want this event tracked through attribution and displayed on the pixel pages.
[Custom Sales Platform accounts only]
Under Categorize your event, select an Event Category:
Lead Capture Event
Engagement Event
Conversion Event
Subscription Change Event
Pipeline Events
Other Event
Note: Selecting Conversion Event as the Event Category — not a checkbox — is what marks the event as a conversion, making it available as a column on the Pixel Attribution page and in the SQL Editor, Table Builder, or Moby for a Custom Dashboard. This is independent of Run Through Attribution, which only controls whether the event is tracked through attribution at all.
[Custom Sales Platform accounts only]
Select a Subcategory — options change based on the selected Event Category
e.g., Lead Capture Event:
Account Created
Email Capture / Newsletter Signup
Demo Request
Free Trial Start
Other
Note: Shopify-native accounts currently do not have the Categorize your event section — only the Run Through Attribution toggle is available.
Click Add Property to add a property to your event.
Note: new events automatically start with two default properties —
value(Float) andcurrency(String) — which you can keep, edit, or remove.Enter the property name (e.g.,
productId).Select the property type (
string,number,boolean,date, orfloat).
Repeat steps for each additional property you need.
Click Save Configuration.
Note: if you don't save your configuration, Triple Whale won't know to flatten the properties of your events in the SQL interface.
[Shopify-native accounts]
[Custom Sales Platform accounts]
Use Cases
The examples below show event names, properties, and tracking code. Replace the sample values with values from your website, and trigger the code when the corresponding interaction occurs.
Example 1: Product Customization Event
Event name: productCustomizationInteraction
Property | Type |
| String |
| String |
| Boolean |
Sample code for tracking this event:
TriplePixel('custom', 'productCustomizationInteraction', {
productId: 'TSHIRT-101',
customizationType: 'color',
completedCustomization: true
});Example 2: A/B Test Segment Event
Event Name: abTestSegmentAssignment
Property | Type |
| String |
| String |
Sample code for tracking this event:
TriplePixel('custom', 'abTestSegmentAssignment', {
testId: 'HOMEPAGE-REDESIGN-001',
variantId: 'B'
});Example 3: Scroll Depth Event
Event Name: scrollDepthReached
Property | Type |
| String |
| Number |
Sample code for tracking this event:
Trigger this event when the visitor reaches a scroll threshold:
TriplePixel('custom', 'scrollDepthReached', {
pageUrl: window.location.href,
scrollPercentage: 50
});
To implement scroll depth tracking, you would typically use JavaScript to calculate the scroll percentage and trigger the event at specific thresholds (e.g., 25%, 50%, 75%, 100%).
This example detects when a visitor reaches 25% of the page’s scrollable distance and sends the event once. Install the snippet once per page load.
var tracked25 = false;
window.addEventListener('scroll', function() {
var scrollableHeight =
document.documentElement.scrollHeight - window.innerHeight;
if (scrollableHeight <= 0) {
return;
}
var scrollPercentage =
(window.scrollY / scrollableHeight) * 100;
if (scrollPercentage >= 25 && !tracked25) {
TriplePixel('custom', 'scrollDepthReached', {
pageUrl: window.location.href,
scrollPercentage: 25
});
tracked25 = true;
}
});
To track additional thresholds such as 50%, 75%, and 100%, add separate threshold checks and tracking flags.
Example 4: Sign-Up Conversion Event
Event Name: scheduleDemo
Properties:
action
version
shop
email
firstName
lastName
phone
Sample code for tracking this event:
TriplePixel('custom', 'scheduleDemo', {
action: 'booked_demo',
version: '1.0',
shop: 'example-shop.myshopify.com',
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phone: '+1-555-123-4567'
});Implementing Custom Event Tracking
Choose direct implementation or Google Tag Manager to add the event snippet to your website.
Method 1: Direct Implementation
Add the following JavaScript code where you want to track the custom event:
TriplePixel('custom', '<event-name>', {
property1: '<property-1-value>',
property2: '<property-2-value>'
});
Replace <event-name> with your actual custom event name, and add your specific properties.
The quoted values in this template represent Strings. Use values that match your configured property types. For example, the product customization event sends completedCustomization as the Boolean value true, without quotation marks.
Method 2: Using Google Tag Manager
Log in to your Google Tag Manager account.
Create a new tag:
Click "New Tag"
Choose "Custom HTML" as the tag type
Paste the following code into the HTML field (replacing the name 'MyCustomEvent' with your desired event name):
<script>
TriplePixel('custom', 'MyCustomEvent', {
{{Property1 Name}}: {{Property1 Value}},
{{Property2 Name}}: {{Property2 Value}},
// ... additional properties
});
</script>
Create variables in GTM for the properties.
Set up a trigger that fires when you want to track the custom event (e.g., a specific button click or page view).
Save and publish your changes in GTM.
Example GTM setup for the product customization event:
<script>
TriplePixel('custom', 'productCustomizationInteraction', {
productId: '{{Custom Event - Product ID}}',
customizationType: '{{Custom Event - Customization Type}}',
completedCustomization: {{Custom Event - Completed}}
});
</script>
Remember to create corresponding variables in GTM for each of these placeholders.
Best Practices for Implementation
Install the Triple Pixel base code before adding custom-event tracking.
Test changes in a staging environment before deploying them to production.
Use consistent names for events and properties.
Use browser developer tools or Google Tag Manager preview mode to inspect the data being sent.
Verify your implementation
Perform the interaction that triggers your event.
Inspect the event using browser developer tools or Google Tag Manager preview mode.
Check that the event name matches the name in your configuration.
Check that the property names, values, and types match your intended payload.
Use the query examples below to inspect the event records available in Triple Whale. Checking the event payload and checking its reporting results are separate steps.
Querying Custom Events
Custom-event records are available in custom_pixel_events_table in ClickHouse.
The data column contains the event properties as JSON-formatted text stored in a String. Extract properties from that text with JSON extraction functions:
JSONExtractString(ce.data, 'productId')
In the examples below, ce is the table alias defined by:
FROM custom_pixel_events_table AS ce
Do not access properties with dot notation such as data.productId.
Table Schema
Field | Description |
| Date of the event. |
| String containing the event properties in JSON format. |
| Name of the custom event. |
| Timestamp of the event. |
| User ID assigned by Triple Pixel. |
Configured property columns | Additional flattened properties defined in the Custom Event Builder. |
For the complete field reference, see the Pixel Custom Events Table data dictionary.
Extracting property values
Match the extraction function to the type of value sent in the event.
Value in the event payload | Example |
String |
|
Boolean |
|
Number |
|
These examples correspond to the payload types used earlier in this article.
Missing String properties: JSONExtractString returns an empty string when a key is missing. If your query uses COALESCE to fall back to another value, convert the empty string to NULL first:
Missing String properties: JSONExtractString returns an empty string when a key is missing. If your query uses COALESCE to fall back to another value, convert the empty string to NULL first:
COALESCE(
nullIf(JSONExtractString(ce.data, 'productId'), ''),
'<fallback-product-id>'
)
This pattern treats both a missing key and an empty String value as NULL.
Pass data directly to the extraction function. Do not wrap it in toJSONString: it is already a String. Wrapping it can cause subsequent extraction to return an empty result without an error.
Viewing Custom Conversion Events
Use the Pixel Attribution page or a Custom Dashboard to analyze configured custom conversion events.
Pixel Attribution Page
To view your custom conversion event in the Pixel Attribution page, add it as a column on your attribution dashboard.
Two columns will be available:
Column | Description |
| Total count of the custom conversion event. |
| Total conversion value for events with defined |
Custom Dashboards
You will find your custom conversion event columns in the Pixel Joined table, ready to be added as a metric to your data visualization in a Custom Dashboard using either the Table Builder or the SQL Editor as:
Display name | SQL column | Description |
|
| Total count of the custom conversion event. |
|
| Total conversion value for events with defined |
For example, for a custom conversion event called scheduleDemo, you will see it as:
Table Builder
SQL Editor
Basic Query Structure
Replace <event-name> with the event you want to inspect.
The date filter below includes records dated seven days before today or later. Adjust the filter to the period you want to review.
SELECT
ce.event_date,
ce.event_timestamp,
ce.event_name,
ce.triple_id,
ce.data
FROM custom_pixel_events_table AS ce
WHERE ce.event_name = '<event-name>'
AND ce.event_date >= today() - 7
Example 1: Querying Product Customization Events
This example selects product customization events where completedCustomization was sent as the Boolean value true.
SELECT
ce.event_date,
ce.event_timestamp,
ce.triple_id,
JSONExtractString(ce.data, 'productId') AS productId,
JSONExtractString(ce.data, 'customizationType') AS customizationType,
JSONExtractBool(ce.data, 'completedCustomization') AS completedCustomization
FROM custom_pixel_events_table AS ce
WHERE ce.event_name = 'productCustomizationInteraction'
AND ce.event_date >= today() - 7
AND JSONExtractBool(ce.data, 'completedCustomization') = true
ORDER BY ce.event_date DESC
LIMIT 100
Example 2: Querying A/B Test Segment Assignments
This query returns the test and variant recorded for each assignment event.
SELECT
ce.event_date,
ce.event_timestamp,
ce.triple_id,
JSONExtractString(ce.data, 'testId') AS testId,
JSONExtractString(ce.data, 'variantId') AS variantId
FROM custom_pixel_events_table AS ce
WHERE ce.event_name = 'abTestSegmentAssignment'
AND ce.event_date >= today() - 30
ORDER BY ce.event_date DESC
LIMIT 100
Example 3: Analyzing Scroll Depth
This query groups scroll-depth events by page URL and the numeric scrollPercentage property sent in the event.
SELECT
JSONExtractString(ce.data, 'pageUrl') AS pageUrl,
JSONExtract(ce.data, 'scrollPercentage', 'Float64') AS scrollPercentage,
count(*) AS occurrences
FROM custom_pixel_events_table AS ce
WHERE ce.event_name = 'scrollDepthReached'
AND ce.event_date >= today() - 7
GROUP BY pageUrl, scrollPercentage
ORDER BY pageUrl, scrollPercentage
Advanced Querying
You can combine custom-event properties with other data to investigate behavior such as purchases associated with A/B test assignments.
Example: Conversion rates by A/B test variant
The following example matches visitors assigned to HOMEPAGE-REDESIGN-001 with visitors who have a purchase in the selected purchase period.
It returns:
Column | Description |
| The recorded test variant. |
| Distinct visitors assigned to that variant. |
| Distinct assigned visitors with at least one matching purchase. |
| Purchasing visitors divided by assigned visitors, multiplied by 100. |
Repeated assignments to the same variant do not increase its visitor count. Multiple purchases by the same visitor count as one converted visitor.
This example includes assignment records through today, with no assignment start date. It includes purchases dated 30 days before today through today, inclusive.
It does not require a purchase to occur after assignment. A visitor assigned to multiple variants can appear in each variant’s results. Use the query as an illustrative purchase-rate calculation, not as a validated measure of an A/B test’s effect.
WITH ab_test_users AS (
SELECT DISTINCT
ce.triple_id,
JSONExtractString(ce.data, 'testId') AS testId,
JSONExtractString(ce.data, 'variantId') AS variantId
FROM custom_pixel_events_table AS ce
WHERE ce.event_name = 'abTestSegmentAssignment'
AND ce.event_date <= today()
AND JSONExtractString(ce.data, 'testId') =
'HOMEPAGE-REDESIGN-001'
),
conversions AS (
SELECT
po.triple_id,
count(DISTINCT po.order_id) AS conversion_count
FROM pixel_orders_table AS po
WHERE po.event_date >= today() - 30
AND po.event_date <= today()
GROUP BY po.triple_id
),
variant_totals AS (
SELECT
ab.variantId,
uniqExact(ab.triple_id) AS total_users,
uniqExactIf(
ab.triple_id,
coalesce(c.conversion_count, 0) > 0
) AS converted_users
FROM ab_test_users AS ab
LEFT JOIN conversions AS c
ON ab.triple_id = c.triple_id
GROUP BY ab.variantId
)
SELECT
vt.variantId,
vt.total_users,
vt.converted_users,
round(
100.0 * vt.converted_users /
nullIf(vt.total_users, 0),
2
) AS conversion_rate_pct
FROM variant_totals AS vt
ORDER BY conversion_rate_pct DESC
The output is a percentage value. For example, one purchasing visitor out of two assigned visitors returns 50.00, meaning 50%.
Using Flattened Properties
If you've defined flattened properties using the custom event mapping tool, you can query them directly:
This example assumes your event configuration exposes productId, customizationType, and completedCustomization as separate columns with the corresponding types. Use the column names available for your configured event.
SELECT
event_date,
event_timestamp,
triple_id,
productId,
customizationType,
completedCustomization
FROM custom_pixel_events_table
WHERE event_name = 'productCustomizationInteraction'
AND event_date >= today() - 7
AND completedCustomization = true
ORDER BY event_timestamp DESC
LIMIT 100
Best Practices for Querying
Include an
event_datefilter, as required by the data dictionary’s query notes.Filter by
event_nameto select the event you want to analyze.Match extraction functions to the types sent in your event payload.
Handle missing and empty String values explicitly when using fallback logic.
Pass the String
datacolumn directly to JSON extraction functions.Use configured flattened columns when they are available.
Define the population and date ranges before interpreting a conversion rate.
Use ClickHouse aggregate and window functions for more detailed analysis.
Conclusion
Custom events provide a powerful way to track and analyze specific interactions in your e-commerce application. Whether you're tracking product customization interactions, A/B test segments, scroll depth, or other unique events, you can gain valuable insights into user behavior and preferences.
By carefully defining your events, consistently implementing them in your code, and effectively querying the data, you can uncover insights that go beyond standard e-commerce events. This data-driven approach allows you to make informed decisions about product features, user interface designs, and overall business strategies.
Remember to regularly review your custom events and queries to ensure they're providing valuable insights and performing efficiently. As your business evolves and you run new tests or introduce new features, you may need to add new custom events or modify existing ones to capture the most relevant data for your decision-making processes.
The flexibility of custom events allows you to adapt your analytics strategy to your changing business needs, ensuring that you always have the data you need to drive growth and improve user experience.



