Kameleoon Integration
Measure the first Ekoo audio play with a Kameleoon custom goal.
Recommended integration
Use the Ekoo played-0 event through data-ekoo-on-event. It confirms that playback started and does not depend on the widget's internal HTML structure.
1. Create the Goal in Kameleoon
- Open the relevant project in Kameleoon.
- Go to Settings > Goals, then create a custom goal such as Ekoo – Audio play.
- Copy the numeric goal ID.
- Attach the goal to the relevant experiments or personalizations.
2. Trigger the Conversion from Ekoo
Place this code before the widget script and replace only 123456 with your Kameleoon goal ID.
1(() => {2 const KAMELEOON_GOAL_ID = 123456; // Replace with your custom goal ID34 window.onEkooEvent = function (data) {5 if (data.stats.type !== 'played-0') return;67 if (!window.Kameleoon?.API?.Goals?.processConversion) {8 console.warn('[Ekoo] Kameleoon API is unavailable');9 return;10 }1112 window.Kameleoon.API.Goals.processConversion(KAMELEOON_GOAL_ID);13 };14})();Then add this attribute to the element that initializes the Ekoo widget:
1data-ekoo-on-event="onEkooEvent"3. Verify the Integration
In the browser console, confirm that the Kameleoon conversion API is available:
1typeof window.Kameleoon?.API?.Goals?.processConversion2// Expected result: "function"The expected result is "function". Then use Kameleoon Preview mode, start playback once, and check the conversion on the goal.
Temporary Workaround Without the Ekoo Callback
Kameleoon tracking based only on a CSS selector can miss clicks: the Play button is inside the widget's Shadow DOM and stops event propagation. If you cannot add data-ekoo-on-event yet, temporarily use a capture-phase listener:
1(() => {2 const KAMELEOON_GOAL_ID = 123456; // Replace with your custom goal ID34 if (window.__ekooKameleoonTrackingInstalled) return;5 window.__ekooKameleoonTrackingInstalled = true;67 const trackedWidgets = new WeakSet();89 function trackPlay(event) {10 const path = event.composedPath?.() || [];11 const isPlayButton = path.some((element) =>12 element?.matches?.('.ekoo-widget-container-picture-button')13 );1415 if (!isPlayButton) return;1617 const widget = path.find((element) => element?.tagName === 'EKOO-WIDGET');1819 if (!widget || widget.classList.contains('playing') || trackedWidgets.has(widget)) {20 return;21 }2223 if (!window.Kameleoon?.API?.Goals?.processConversion) {24 console.warn('[Ekoo] Kameleoon API is unavailable');25 return;26 }2728 trackedWidgets.add(widget);29 window.Kameleoon.API.Goals.processConversion(KAMELEOON_GOAL_ID);30 }3132 document.addEventListener('pointerdown', trackPlay, true);33 document.addEventListener('keydown', (event) => {34 if (event.key === 'Enter' || event.key === ' ') trackPlay(event);35 }, true);36})();Fallback limitation
This method measures the intent to click Play, not confirmation that audio playback started. Replace it with the native callback when possible.
Expected Behavior
- One conversion on the first audio play.
- No additional conversion on pause or resume.
- A new widget can trigger its own conversion.
To also send events to GTM or GA4, see the DataLayer guide.