Le widget d'intégration couvre la plupart des cas d'usage dès le départ. Cet article aborde les options de personnalisation plus poussées.
Variables CSS
Le widget expose des variables CSS que tu peux surcharger :
| Variable | Valeur par défaut | Rôle |
|---|---|---|
--mm-primary-color | #1a1813 | Couleur des boutons et des accents |
--mm-primary-fg | #fff | Texte sur la couleur primaire |
--mm-bg | #fff | Arrière-plan du widget |
--mm-fg | #1a1813 | Couleur de texte par défaut |
--mm-muted-fg | #5a5550 | Texte secondaire |
--mm-border | #e5e1d8 | Bordures des cartes |
--mm-radius | 1rem | Rayon des bordures |
--mm-font-family | system-ui | Police de caractères |
--mm-spacing | 1rem | Densité du padding |
--mm-shadow | minimal | Ombre des cartes |
Définis-les sur le div conteneur :
<div id="movementors-embed" style="
--mm-primary-color: #c4533c;
--mm-radius: 0;
--mm-font-family: 'Helvetica Neue', sans-serif;
"></div>
Ou dans la feuille de style de ton site :
#movementors-embed {
--mm-primary-color: #c4533c;
--mm-radius: 0;
}
Plusieurs widgets par page
Tu peux avoir plusieurs instances du widget sur la même page. Chacune a besoin d'un ID de conteneur unique et d'un data-target correspondant sur le script.
<script src="https://movementors.com/embed.js" data-studio="your-slug" data-mode="single" data-class="yoga-flow" data-target="mm-featured" async></script>
<div id="mm-featured"></div>
<!-- ailleurs sur la même page -->
<script src="https://movementors.com/embed.js" data-studio="your-slug" data-mode="list" data-target="mm-full-list" async></script>
<div id="mm-full-list"></div>
Les deux widgets partagent le même chargement de script (le navigateur déduplique), mais s'affichent dans leurs propres conteneurs.
Filtrer la vue intégrée
La page de configuration du widget te permet de filtrer ce qui s'affiche. Tu peux aussi surcharger via les attributs data-* :
| Attribut | Effet |
|---|---|
data-location | Filtrer sur un slug de lieu spécifique |
data-category | Filtrer sur un slug de catégorie (par ex. "yoga") |
data-teacher | Filtrer sur un professeur spécifique (slug pour un mentor de la plateforme, ID pour un personnalisé) |
data-limit | Limiter le nombre de cours affichés |
data-from | Afficher les cours commençant après cette date (format ISO) |
data-to | Afficher les cours commençant avant cette date |
Exemple : un widget de page d'accueil affichant uniquement les cours de yoga des "7 prochains jours" sur ton lieu principal :
<script src="https://movementors.com/embed.js"
data-studio="your-slug"
data-mode="grid"
data-category="yoga"
data-location="main-studio"
data-limit="6"
async></script>
<div id="movementors-embed"></div>
Suivi d'événements
Le widget déclenche des événements personnalisés que tu peux écouter :
movementors:loaded: le DOM du widget est prêt.movementors:class-viewed: l'utilisateur a cliqué sur une carte de cours.movementors:booking-started: l'utilisateur a ouvert le formulaire de réservation.movementors:booking-completed: la réservation a réussi.movementors:booking-failed: la réservation a échoué.
Écoute via :
window.addEventListener('movementors:booking-completed', (e) => {
console.log('booking completed', e.detail);
// e.detail contient : { bookingId, classId, classTitle, amountCents, currency }
});
Utile pour :
- Google Analytics : déclencher un événement de conversion quand une réservation se termine.
- Facebook Pixel : suivre les réservations terminées.
- Analytique interne : enregistrer sur ton propre backend.
Intégration CSP
Si ton site a une Content Security Policy, tu dois autoriser MoveMentors dans ces directives :
Content-Security-Policy:
script-src 'self' https://movementors.com;
frame-src https://movementors.com;
connect-src 'self' https://movementors.com https://api.stripe.com;
img-src 'self' https://*.movementors.com https://res.cloudinary.com data:;
Le widget lui-même utilise un sandboxing d'iframe en interne ; ta CSP a juste besoin d'autoriser le framing.
Transfert d'authentification
Le widget supporte un mode "preauth" : si un utilisateur est déjà connecté à ton site, tu peux le faire passer à MoveMentors sans redemander son nom et son e-mail.
<script src="https://movementors.com/embed.js"
data-studio="your-slug"
data-prefill-name="Jane Doe"
data-prefill-email="jane@example.com"
async></script>
<div id="movementors-embed"></div>
Les valeurs pré-remplissent le formulaire de réservation. L'utilisateur peut les modifier ; c'est un confort, pas une frontière de sécurité. (Ne suppose pas que l'utilisateur est "connecté" simplement parce que tu as pré-rempli les valeurs ; la réservation effective nécessite toujours la confirmation par e-mail.)
Rendu côté serveur
Le widget est uniquement côté client. Il n'existe pas de version rendue côté serveur (SSR) qui émet du HTML à des fins de SEO.
Si tu veux que ta page de réservation soit indexée par les moteurs de recherche avec le contenu complet des cours visible pour les crawlers, fais un lien vers les pages de détail de cours MoveMentors correspondantes (qui SONT rendues côté serveur) plutôt que de t'appuyer sur le widget pour le SEO.
Pour des "5 prochains cours" visibles sur ta page d'accueil que les crawlers devraient voir, envisage aussi un lien vers le répertoire MoveMentors ; le widget fournit l'UI de réservation, le lien fournit le jus SEO.
Performance
Le bundle du widget pèse environ 80 Ko gzippé. Il se charge de façon asynchrone (l'attribut async) donc ne bloque pas le rendu de ta page.
Rendu initial : 1 à 2 secondes sur une connexion correcte.
Après chargement :
- Interactions avec les cartes de cours : instantanées (état côté client).
- Ouverture du formulaire de réservation : instantanée.
- Envoi de la réservation : dépend du moyen de paiement (Stripe Checkout ajoute environ 1 seconde de surcharge de redirection).
Si la performance de ton site est critique, tu peux préférer charger le widget en différé (le monter seulement après une interaction utilisateur). Modèle :
<button id="open-booking">Parcourir les cours</button>
<div id="movementors-embed"></div>
<script>
document.getElementById('open-booking').addEventListener('click', () => {
const s = document.createElement('script');
s.src = 'https://movementors.com/embed.js';
s.dataset.studio = 'your-slug';
s.async = true;
document.body.appendChild(s);
});
</script>
Le widget se charge uniquement au clic. Compromis : un petit délai supplémentaire pour les utilisateurs qui cliquent.
Considérations mobiles
Le widget est responsive. Il s'adapte :
- Mise en page sur une seule colonne sous 640 px.
- Cibles tactiles confortables (44 × 44 minimum).
- Le formulaire de réservation utilise les claviers natifs mobiles (numérique pour les prix, e-mail pour les e-mails).
Si ton site a une mise en page spécifique mobile (différente du bureau), le widget peut être configuré par mise en page : utilise des attributs data-mode différents sur les balises de script bureau et mobile, conditionnés par des media queries CSS.
Questions fréquentes
Puis-je obtenir une version entièrement en marque blanche avec mon logo et sans branding MoveMentors ? Les clients entreprise peuvent en faire la demande. Par défaut, un petit pied de page "powered by MoveMentors" est inclus.
Puis-je faire tourner le widget sur plusieurs domaines ? Oui. Le widget ne met pas de liste blanche sur les domaines. Quiconque a ton slug de studio peut l'intégrer.
Puis-je empêcher d'autres personnes d'intégrer mon widget ? Pas pour l'instant. Le widget récupère des données publiques de cours ; quiconque connaît ton slug peut l'intégrer. Nous pourrions ajouter une liste blanche de domaines comme fonctionnalité entreprise.
Puis-je personnaliser les champs du formulaire de réservation ? Pas pour l'instant. Les champs sont les mêmes que ceux du site MoveMentors. La personnalisation des champs est dans la feuille de route.
Les réservations via le widget compteront-elles dans ma visibilité / mon classement MoveMentors ? Oui. Une réservation est une réservation quelle que soit la source. Les réservations provenant de l'intégration comptent dans les totaux de ton studio, tes avis sont agrégés de la même manière, etc.
Prochaines étapes
- Widget d'intégration : les bases.
- Le widget d'intégration ne se charge pas : diagnostic.