Attention : Les intégrations via GTM peuvent créer du CLS (Cumulative Layout Shift) sur votre site. Ceci n'est pas spécifique à JOIN Stories, mais s'applique à toute intégration dans le DOM via un Tag Manager.
Prérequis
Avant de commencer, récupérez ces informations dans votre back-office JOIN :
1. Nom de domaine
Votre domaine au format : votre-marque.my.join-stories.com
â
2. Alias du widget
L'identifiant de votre widget (ex : homepage, products, pdp)
â
Type de widget
JOIN propose deux types de widgets. Choisissez celui qui correspond Ă votre besoin :
Widget Standard : MĂȘme contenu pour tous les visiteurs. Usage : Page d'accueil, catĂ©gorie, landing page
Widget Product Page Contenu spécifique selon le produit consulté. Usage : Fiche produit (PDP)
Intégration via Google Tag Manager
Avec GTM, vous ne créez pas le conteneur en HTML. Le conteneur est créé dynamiquement en JavaScript et inséré à un emplacement précis de votre page via un sélecteur CSS.
Dans GTM, créez une balise HTML personnalisée (Custom HTML Tag) et collez-y le snippet correspondant à votre type de widget.
â
Widget Standard
<script>
(function () {
// âââ Configuration âââââââââââââââââââââââââââââââââââââââââââ
var domainName = "votre-marque.my.join-stories.com"; // :arrow_left: Votre domaine JOIN
var alias = "votre-alias"; // :arrow_left: Alias du widget
var divId = "join-widget";
var targetSelector = ".product-info"; // :arrow_left: Sélecteur CSS de l'élément cible
// âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
var target = document.querySelector(targetSelector);
if (!target) {
console.warn("JOIN: ĂlĂ©ment cible non trouvĂ© (" + targetSelector + ")");
return;
}
var container = document.createElement("div");
container.id = divId;
// Méthodes d'insertion disponibles (gardez-en une seule) :
target.insertAdjacentElement("afterend", container); // AprÚs l'élément
// target.insertAdjacentElement("beforebegin", container); // Avant l'élément
// target.appendChild(container); // à la fin de l'élément
// target.prepend(container); // Au début de l'élément
var script = document.createElement("script");
script.src = "https://" + domainName + "/widgets/" + alias + "/index.js";
script.setAttribute("data-join-widget-id", divId);
script.setAttribute("data-join-widget-alias", alias);
script.type = "text/javascript";
container.appendChild(script);
})();
</script>
Widget Product Page
Ce snippet charge le widget spécifique au produit consulté, avec un fallback automatique vers le widget par défaut si le produit n'a pas de contenu associé.
<script>
(function () {
// âââ Configuration âââââââââââââââââââââââââââââââââââââââââââ
var domainName = "votre-marque.my.join-stories.com"; // âŹ ïž Votre domaine JOIN
var alias = "pdp"; // âŹ ïž Alias du widget PDP
var divId = "join-widget-pdp";
var targetSelector = ".product-form__quantity"; // âŹ ïž SĂ©lecteur CSS de l'Ă©lĂ©ment cible
var productId = {{Page.ProductId}}; // âŹ ïž Variable GTM contenant l'ID produit
// âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
var target = document.querySelector(targetSelector);
if (!target) {
console.warn("JOIN: ĂlĂ©ment cible non trouvĂ© (" + targetSelector + ")");
return;
}
var container = document.createElement("div");
container.id = divId;
target.insertAdjacentElement("afterend", container);
var baseUrl = "https://" + domainName + "/widgets/" + alias;
var script = document.createElement("script");
script.src = baseUrl + "/" + productId + ".js";
script.setAttribute("data-join-widget-id", divId);
script.setAttribute("data-join-widget-alias", alias);
script.type = "text/javascript";
script.onerror = function () {
script.remove();
var fallback = document.createElement("script");
fallback.src = baseUrl + "/index.js";
fallback.setAttribute("data-join-widget-id", divId);
fallback.setAttribute("data-join-widget-alias", alias);
fallback.type = "text/javascript";
container.appendChild(fallback);
};
container.appendChild(script);
})();
</script>
Points importants
Sélecteur CSS (targetSelector)
Choisissez un élément stable, toujours présent sur la page. Exemples courants :
.product-infoâ bloc d'informations produit.product-form__quantityâ sĂ©lecteur de quantitĂ©.product-descriptionâ description produit#add-to-cart-buttonâ bouton d'ajout au panier
Déclencheur GTM recommandé
Utilisez DOM Ready ou Window Loaded pour garantir que l'élément cible existe avant l'exécution du script.
â
Méthode d'insertion
âUne seule mĂ©thode d'insertion doit ĂȘtre active Ă la fois (les autres commentĂ©es). Par dĂ©faut : insertAdjacentElement("afterend", container) insĂšre le widget juste aprĂšs l'Ă©lĂ©ment cible.
â
âRĂ©duire le CLS (optionnel mais recommandĂ©)
âPour limiter le saut de mise en page, ajoutez une hauteur minimale au conteneur du widget via une balise HTML GTM sĂ©parĂ©e ou directement dans votre thĂšme :
<style>
#join-widget,
#join-widget-pdp {
display: block;
width: 100%;
min-height: 114px;
margin: 20px 0;
}
/* Hauteur adaptée sur écrans larges */
@media (min-aspect-ratio: 3/4) {
#join-widget,
#join-widget-pdp {
min-height: 283px;
}
}
</style>
â
âDonnĂ©es d'audience (optionnel)
Vous pouvez transmettre des données de segmentation à JOIN avant le chargement du widget, en poussant dans window.jDataLayer.
Audience (segmentation personnalisée)
<script>
window.jDataLayer = window.jDataLayer || [];
window.jDataLayer.push({
type: "audience",
data: "premium" // ex: "premium", "member", "vip"
});
</script>
Ces scripts doivent ĂȘtre exĂ©cutĂ©s avant les balises de chargement du widget JOIN dans GTM.

