HTML / Vanilla JS Integration
Standard integration without a framework, directly in HTML
The widget auto-loads its config from the backoffice. Appearance attributes are optional overrides — no need to set them if the backoffice is configured.
Core attributes
data-ekooReqstring
Your Ekoo website UUID. Found in the backoffice → Site settings.
data-ekoo-product-idReqstring
Product reference (must match exactly what is in your Ekoo catalog).
data-ekoo-localestring·default:
autoLocale code: fr, en, es, it, de, ar, cn, tw, hk, jp, kr, nl, tr, pl, pt, lu, be, ru. "auto" = navigator.language detection.
data-ekoo-variantstring
Stable reference of a widget configuration. The product, its audios, and its reviewers still come from data-ekoo-product-id; only the widget styling changes.
data-ekoo-review-idstring
ID of a specific audio review. If omitted, the first published review is used.
data-ekoo-on-eventstring (fn name)
Name of a global window function called on each widget event (printed, played-0, played-25…).
Appearance — backoffice overrides
data-ekoo-directionnormal | reverse·default:
normalExpansion direction. normal = left-to-right, reverse = right-to-left.
data-ekoo-scalenumber·default:
1Scale factor (e.g. "1.2" for 20% larger).
data-ekoo-animationstring·default:
pulseAnimation type for the widget icon at rest.
data-ekoo-animation-durationstring·default:
continuousAnimation duration.
data-ekoo-always-openboolean·default:
falseIf "true", the widget stays permanently expanded.
data-ekoo-show-imageboolean·default:
trueShow or hide the product image in the widget.
data-ekoo-not-fully-clickableboolean·default:
falseIf "true", only the play button is clickable.
data-ekoo-autoplayboolean·default:
falseAutomatically start audio playback on load.
data-ekoo-show-transcriptboolean·default:
falseShow a button to read the audio transcript.
data-ekoo-show-speed-buttonboolean·default:
falseShow a playback speed control.
data-ekoo-closed-state-main-textstring
Main CTA text shown when the widget is collapsed.
data-ekoo-closed-state-secondary-textstring
Secondary text below the CTA when the widget is collapsed.
SPA & Shadow DOM
data-ekoo-modespa | static·default:
autoForces rendering mode. Auto-detected (Next.js, Nuxt, React, Vue, Angular, Sapper). Only use if auto-detection fails.
data-shadow-modeopen | closed·default:
open"open" (default) enables inspection, external CSS access and analytics tracking. Set to "closed" to fully isolate the widget.
Global JS config
window.EKOO_FORCE_SPA = trueForces SPA mode globally (alternative to data-ekoo-mode="spa" on each widget).
window.ekooShadowMode = "open"Global Shadow DOM mode (alternative to data-shadow-mode on each widget).
Recommended method: data attributes
Add a container with data-ekoo-* attributes and load the official script. The widget initializes automatically.
Simple integration
html
1<!-- Widget container -->2<ekoo-widget3 data-ekoo="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"4 data-ekoo-product-id="my-product-123"5 data-ekoo-locale="fr"6></ekoo-widget>78<!-- Ekoo script — load once per page -->9<script src="https://app.ekoo.co/widgets/widget-4.0.0-standalone.js"</script>Dynamic Product ID
If the product identifier is dynamic (e.g. extracted from the URL or a page attribute), you can use a JavaScript function to retrieve it and inject it into the data-ekoo-product-id attribute.
Dynamic Product ID from the URL
html
1<!-- Container — the ID will be injected by the script below -->2<div id="ekoo-container"3 data-ekoo="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"4 data-ekoo-locale="fr"5></div>67<script>8 // Retrieve the product ID from the URL, e.g.: /products/my-product-1239 function getProductId() {10 const parts = window.location.pathname.split('/');11 return parts[parts.length - 1];12 }1314 const container = document.getElementById('ekoo-container');15 if (container) {16 container.setAttribute('data-ekoo-product-id', getProductId());17 }18</script>1920<!-- Ekoo script — AFTER the product ID injection -->21<script src="https://app.ekoo.co/widgets/widget-4.0.0-standalone.js"</script>✅
Declare callbacks BEFORE the script
If you use data-ekoo-on-event to receive widget events, declare the callback function before loading the Ekoo script. Otherwise, the script will not find the function at initialization time.
Event callback
html
1<script>2 // Declare the function BEFORE the Ekoo script3 // The callback receives a single argument: the full stats body object4 function onEkooEvent(data) {5 console.log('Ekoo event:', data.stats.type, data);6 // E.g.: send to Google Analytics, dataLayer, etc.7 }8</script>910<ekoo-widget11 data-ekoo="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"12 data-ekoo-on-event="onEkooEvent"13 data-ekoo-product-id="my-product-123"14 data-ekoo-locale="fr"15></ekoo-widget>1617<script src="https://app.ekoo.co/widgets/widget-4.0.0-standalone.js"</script>Common pitfalls
- Script loaded before the container: if the
data-ekoocontainer is not yet in the DOM, the widget will not mount. Usedeferor place the script at the end of<body>. - Missing or incorrect Product ID: the widget will not display if the ID does not match any published audio.
- Multiple scripts loaded: only load the
widget-4.0.0-standalone.jsscript once per page, even if you have multiple containers. - Undeclared callback: the function referenced in
data-ekoo-on-eventmust be globally accessible (onwindow). - Wrong script URL: always use
widget-4.0.0-standalone.js, not an older version.