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-ekooReq
string
Your Ekoo website UUID. Found in the backoffice → Site settings.
data-ekoo-product-idReq
string
Product reference (must match exactly what is in your Ekoo catalog).
data-ekoo-locale
string·default: auto
Locale 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-variant
string
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-id
string
ID of a specific audio review. If omitted, the first published review is used.
data-ekoo-on-event
string (fn name)
Name of a global window function called on each widget event (printed, played-0, played-25…).
Appearance — backoffice overrides
data-ekoo-direction
normal | reverse·default: normal
Expansion direction. normal = left-to-right, reverse = right-to-left.
data-ekoo-scale
number·default: 1
Scale factor (e.g. "1.2" for 20% larger).
data-ekoo-animation
string·default: pulse
Animation type for the widget icon at rest.
data-ekoo-animation-duration
string·default: continuous
Animation duration.
data-ekoo-always-open
boolean·default: false
If "true", the widget stays permanently expanded.
data-ekoo-show-image
boolean·default: true
Show or hide the product image in the widget.
data-ekoo-not-fully-clickable
boolean·default: false
If "true", only the play button is clickable.
data-ekoo-autoplay
boolean·default: false
Automatically start audio playback on load.
data-ekoo-show-transcript
boolean·default: false
Show a button to read the audio transcript.
data-ekoo-show-speed-button
boolean·default: false
Show a playback speed control.
data-ekoo-closed-state-main-text
string
Main CTA text shown when the widget is collapsed.
data-ekoo-closed-state-secondary-text
string
Secondary text below the CTA when the widget is collapsed.
SPA & Shadow DOM
data-ekoo-mode
spa | static·default: auto
Forces rendering mode. Auto-detected (Next.js, Nuxt, React, Vue, Angular, Sapper). Only use if auto-detection fails.
data-shadow-mode
open | 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 = true
Forces 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-widget
3 data-ekoo="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4 data-ekoo-product-id="my-product-123"
5 data-ekoo-locale="fr"
6></ekoo-widget>
7
8<!-- 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>
6
7<script>
8 // Retrieve the product ID from the URL, e.g.: /products/my-product-123
9 function getProductId() {
10 const parts = window.location.pathname.split('/');
11 return parts[parts.length - 1];
12 }
13
14 const container = document.getElementById('ekoo-container');
15 if (container) {
16 container.setAttribute('data-ekoo-product-id', getProductId());
17 }
18</script>
19
20<!-- 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 script
3 // The callback receives a single argument: the full stats body object
4 function onEkooEvent(data) {
5 console.log('Ekoo event:', data.stats.type, data);
6 // E.g.: send to Google Analytics, dataLayer, etc.
7 }
8</script>
9
10<ekoo-widget
11 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>
16
17<script src="https://app.ekoo.co/widgets/widget-4.0.0-standalone.js"</script>

Common pitfalls

  • Script loaded before the container: if the data-ekoo container is not yet in the DOM, the widget will not mount. Use defer or 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.js script once per page, even if you have multiple containers.
  • Undeclared callback: the function referenced in data-ekoo-on-event must be globally accessible (on window).
  • Wrong script URL: always use widget-4.0.0-standalone.js, not an older version.

Going further

HTML / Vanilla JS — Documentation — Ekoo