Attention les intégrations avec GTM créent du CLS sur votre site.
Ceci n'est pas spécifiques à JOIN Stories, mais pour 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 JOIN (format : votre-marque.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
Affiche le mĂȘme contenu pour tous les visiteurs d'une page. Usage : page d'accueil, page catĂ©gorie, landing page
âWidget Product Page
Affiche un contenu spécifique selon le produit consulté. Usage : fiche produit (PDP)
Intégration via Google Tag Manager
Le widget doit ĂȘtre injectĂ© dynamiquement Ă un emplacement spĂ©cifique de votre page.
Avec GTM, vous ne créez pas le conteneur en HTML. Le conteneur est créé dynamiquement en JavaScript et inséré aprÚs un élément cible de votre choix.
â
Widget Standard avec GTM
(function () {
// Configuration
var domainName = "votre-marque.join-stories.com";
var alias = "votre-alias";
var divId = "join-widget";
var targetSelector = ".product-info"; // âŹ
ïž SĂ©lecteur CSS de l'Ă©lĂ©ment cible
// Récupérer l'élément cible
var target = document.querySelector(targetSelector);
if (!target) {
console.warn("JOIN: ĂlĂ©ment cible non trouvĂ©");
return;
}
// Créer le conteneur dynamiquement
var container = document.createElement("div");
container.id = divId;
container.style.display = "block";
// Insérer le conteneur aprÚs l'élément cible
target.parentNode.insertBefore(container, target.nextSibling);
// Charger le widget
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.setAttribute("type", "text/javascript");
container.appendChild(script);
})();
Widget Product Page avec GTM
(function () {
// Configuration
var productId = "VOTRE_PRODUCT_ID"; // âŹ
ïž Ă rĂ©cupĂ©rer dynamiquement
var alias = "votre-alias";
var domainName = "votre-marque.join-stories.com";
var divId = "join-widget-pdp";
var targetSelector = ".product-form__quantity"; // âŹ
ïž SĂ©lecteur CSS
// Récupérer l'élément cible
var target = document.querySelector(targetSelector);
if (!target) {
console.warn("JOIN: ĂlĂ©ment cible non trouvĂ©");
return;
}
// Créer le conteneur dynamiquement
var container = document.createElement("div");
container.id = divId;
container.style.display = "block";
// Insérer le conteneur aprÚs l'élément cible
target.parentNode.insertBefore(container, target.nextSibling);
// Charger le widget avec fallback
var baseUrl = "https://" + domainName + "/widgets/" + alias;
var script = document.createElement("script");
script.setAttribute("src", baseUrl + "/" + productId + ".js");
script.setAttribute("type", "text/javascript");
script.setAttribute("data-join-widget-id", divId);
script.setAttribute("data-join-widget-alias", alias);
script.onerror = function () {
script.remove();
var fallback = document.createElement("script");
fallback.setAttribute("src", baseUrl + "/index.js");
fallback.setAttribute("type", "text/javascript");
fallback.setAttribute("data-join-widget-id", divId);
fallback.setAttribute("data-join-widget-alias", alias);
document.head.appendChild(fallback);
};
document.head.appendChild(script);
})();
Points importants
Sélecteur CSS (targetSelector)
Choisissez un élément stable qui existe toujours sur la page
Exemples courants :
.product-info: bloc d'informations produit.product-form__quantity: sélecteur de quantité.product-description: description du produit#add-to-cart-button: bouton d'ajout au panier
Position d'insertion
âtarget.nextSibling : insĂšre le widget aprĂšs l'Ă©lĂ©ment cible
Pour insérer avant :
target.parentNode.insertBefore(container, target)
Déclencheur GTM recommandé
Type : DOM Ready ou Window Loaded
Cela garantit que l'élément cible existe avant l'exécution du script
Style (optionnel)
Ajoutez du CSS pour personnaliser l'affichage du widget :
<style> #join-widget { margin: 20px 0; min-height: 114px; width: 100%; } /* Hauteur adaptée sur écrans larges */ @media (min-aspect-ratio: 3/4) { #join-widget { min-height: 283px; } } </style>
Pour GTM, ajoutez ces styles dans une balise HTML personnalisée ou directement dans votre thÚme.
Exemple 3 : Widget Product Page (GTM)
(function () {
// Configuration
var productId = {{Page.ProductId}}; // âŹ
ïž Variable GTM
var alias = "pdp";
var domainName = "ma-boutique.join-stories.com";
var divId = "join-widget-pdp";
var targetSelector = ".product-form__quantity";
// Récupérer l'élément cible
var target = document.querySelector(targetSelector);
if (!target) {
console.warn("JOIN: ĂlĂ©ment cible non trouvĂ©");
return;
}
// Créer le conteneur
var container = document.createElement("div");
container.id = divId;
container.style.display = "block";
container.style.margin = "20px 0";
container.style.minHeight = "114px";
container.style.width = "100%";
// Insérer aprÚs l'élément cible
target.parentNode.insertBefore(container, target.nextSibling);
// Charger le widget
var baseUrl = "https://" + domainName + "/widgets/" + alias;
var script = document.createElement("script");
script.setAttribute("src", baseUrl + "/" + productId + ".js");
script.setAttribute("type", "text/javascript");
script.setAttribute("data-join-widget-id", divId);
script.setAttribute("data-join-widget-alias", alias);
script.onerror = function () {
script.remove();
var fallback = document.createElement("script");
fallback.setAttribute("src", baseUrl + "/index.js");
fallback.setAttribute("type", "text/javascript");
fallback.setAttribute("data-join-widget-id", divId);
fallback.setAttribute("data-join-widget-alias", alias);
document.head.appendChild(fallback);
};
document.head.appendChild(script);
})();
Données d'audience (optionnel)
Pour transmettre des données de segmentation à JOIN :
// Ajouter AVANT loadWidget() window.sendAudienceData = function(data) { window.jDataLayer = window.jDataLayer || []; window.jDataLayer.push({ type: "audience", data: data }); }; // Exemple : envoyer le segment utilisateur sendAudienceData({ segment: "premium", source: "abtasty" });
