Intégration Svelte / SvelteKit

Composant Svelte pour le widget Ekoo avec gestion du cycle de vie

Le widget charge automatiquement sa configuration depuis le backoffice. Les attributs d'apparence sont des surcharges optionnelles — inutile de les définir si le backoffice est configuré.
Attributs principaux
data-ekooReq
string
UUID du site Ekoo. Visible dans le backoffice → Paramètres du site.
data-ekoo-product-idReq
string
Référence produit (doit correspondre exactement au catalogue Ekoo).
data-ekoo-locale
string·default: auto
Code langue : fr, en, es, it, de, ar, cn, tw, hk, jp, kr, nl, tr, pl, pt, lu, be, ru. "auto" = détection navigator.language.
data-ekoo-variant
string
Référence stable d’une configuration widget. Le produit, ses audios et ses reviewers restent pilotés par data-ekoo-product-id ; seul l’habillage change.
data-ekoo-review-id
string
ID d'un avis audio spécifique. Si omis, le premier avis publié est utilisé.
data-ekoo-on-event
string (fn name)
Nom d'une fonction globale window appelée à chaque événement widget (printed, played-0, played-25…).
Apparence — surcharges backoffice
data-ekoo-direction
normal | reverse·default: normal
Sens d'expansion. normal = gauche→droite, reverse = droite→gauche.
data-ekoo-scale
number·default: 1
Facteur de zoom (ex: "1.2" pour 20% plus grand).
data-ekoo-animation
string·default: pulse
Type d'animation de l'icône au repos.
data-ekoo-animation-duration
string·default: continuous
Durée de l'animation.
data-ekoo-always-open
boolean·default: false
Si "true", le widget reste toujours déplié.
data-ekoo-show-image
boolean·default: true
Afficher ou masquer l'image produit dans le widget.
data-ekoo-not-fully-clickable
boolean·default: false
Si "true", seul le bouton lecture est cliquable.
data-ekoo-autoplay
boolean·default: false
Lecture audio automatique au chargement.
data-ekoo-show-transcript
boolean·default: false
Afficher un bouton pour lire la transcription.
data-ekoo-show-speed-button
boolean·default: false
Afficher un contrôle de vitesse de lecture.
data-ekoo-closed-state-main-text
string
Texte CTA principal affiché quand le widget est replié.
data-ekoo-closed-state-secondary-text
string
Texte secondaire sous le CTA quand le widget est replié.
SPA & Shadow DOM
data-ekoo-mode
spa | static·default: auto
Force le mode rendu. Auto-détecté (Next.js, Nuxt, React, Vue, Angular, Sapper). À utiliser seulement si la détection auto échoue.
data-shadow-mode
open | closed·default: open
"open" (par défaut) permet l'inspection, l'accès CSS externe et le tracking analytics. Définir à "closed" pour isoler complètement le widget.
Config JS globale
window.EKOO_FORCE_SPA = true
Force le mode SPA globalement (alternative à data-ekoo-mode="spa" sur chaque widget).
window.ekooShadowMode = "open"
Shadow DOM mode global (alternative à data-shadow-mode sur chaque widget).

1. Composant EkooWidget

Créez un composant Svelte qui charge le script dynamiquement et utilise onMount / onDestroy pour gérer le cycle de vie.

src/lib/components/EkooWidget.svelte
svelte
1<script lang="ts">
2 import { onMount, onDestroy } from 'svelte'
3
4 export let websiteId: string
5 export let productId: string
6 export let locale: string = 'fr'
7
8 const SCRIPT_URL = 'https://app.ekoo.co/widgets/widget-4.0.0-standalone.js'
9
10 onMount(() => {
11 let script = document.querySelector<HTMLScriptElement>(
12 `script[src="${SCRIPT_URL}"]`
13 )
14
15 if (!script) {
16 script = document.createElement('script')
17 script.src = SCRIPT_URL
18 script.defer = true
19 document.head.appendChild(script)
20
21 script.addEventListener('load', () => {
22 window.ekooLoad?.()
23 })
24 } else {
25 window.ekooLoad?.()
26 }
27 })
28
29 onDestroy(() => {
30 window.ekooUnload?.()
31 })
32</script>
33
34<ekoo-widget
35 data-ekoo={websiteId}
36 data-ekoo-product-id={productId}
37 data-ekoo-locale={locale}
38></ekoo-widget>

2. Utilisation dans une page

src/routes/product/[id]/+page.svelte
svelte
1<script lang="ts">
2 import EkooWidget from '$lib/components/EkooWidget.svelte'
3 import type { PageData } from './$types'
4
5 export let data: PageData
6</script>
7
8<h1>{data.product.name}</h1>
9
10<EkooWidget
11 websiteId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
12 productId={data.product.id}
13 locale="fr"
14/>

3. Navigation SvelteKit

SvelteKit effectue des navigations côté client (soft navigation). Lorsque l'utilisateur passe d'un produit à un autre, le composant peut ne pas être détruit et recréé. Utilisez afterNavigate pour recharger le widget après chaque navigation :

Gestion de la navigation SvelteKit
svelte
1<script lang="ts">
2 import { onMount, onDestroy } from 'svelte'
3 import { afterNavigate } from '$app/navigation'
4
5 export let websiteId: string
6 export let productId: string
7 export let locale: string = 'fr'
8
9 const SCRIPT_URL = 'https://app.ekoo.co/widgets/widget-4.0.0-standalone.js'
10
11 function loadScript() {
12 let script = document.querySelector<HTMLScriptElement>(
13 `script[src="${SCRIPT_URL}"]`
14 )
15 if (!script) {
16 script = document.createElement('script')
17 script.src = SCRIPT_URL
18 script.defer = true
19 document.head.appendChild(script)
20 script.addEventListener('load', () => window.ekooLoad?.())
21 } else {
22 window.ekooLoad?.()
23 }
24 }
25
26 onMount(() => loadScript())
27 onDestroy(() => window.ekooUnload?.())
28
29 // Reload the widget after each SvelteKit navigation
30 afterNavigate(() => {
31 window.ekooReload?.()
32 })
33</script>
34
35<ekoo-widget
36 data-ekoo={websiteId}
37 data-ekoo-product-id={productId}
38 data-ekoo-locale={locale}
39></ekoo-widget>
💡

Stratégie de chargement du script

Le script widget-4.0.0-standalone.js ne doit être chargé qu'une seule fois. Le composant vérifie si le script est déjà présent dans le DOM avant de l'ajouter. Lors des navigations suivantes, seul ekooLoad() ou ekooReload() est appelé.

⚠️

Ré-initialisation

Si le widget présente des incohérences visuelles après plusieurs changements de produit, appelez window.ekooReload() pour forcer une réinitialisation complète.

Aller plus loin

Svelte — Documentation — Ekoo