Référence du tag JavaScript

Installez le tag OmniLab réutilisable, configurez ses options, et traitez les messages qu'une expérience intégrée envoie à votre page.

6 min de lecture

Installez le tag réutilisable pour qu'une seule page puisse charger différentes expériences et que l'iframe se comporte correctement sans écrire vous-même la logique de dimensionnement et de drawers. Cette page s'adresse à votre développeur.

La valeur à obtenir d'abord

Le snippet ci-dessous a besoin de l'adresse depuis laquelle vos expériences sont servies. Tout le reste est fixe.

Cette adresse doit être un sous-domaine du site sur lequel vous intégrez — voir l'exigence ci-dessous — donc pour un site sur www.votremarque.com, ce sera quelque chose comme experience.votremarque.com. Configurez-la avant de développer. Voir Domaine personnalisé.

L'expérience doit partager le domaine de votre site

Si vous intégrez une expérience servie depuis un domaine différent de celui de la page — y compris le votre-marque.topage.co par défaut dans www.votremarque.com — le navigateur considère l'iframe comme tierce et bloque ou isole ses cookies. La connexion ne persiste pas, et l'aller-retour d'authentification perd son état en cours de route.

Servir l'expérience depuis un sous-domaine de votre propre site rend l'iframe same-site, et tout cela fonctionne normalement. C'est une exigence pour l'intégration, pas une préférence.

Installer le tag

L'adresse du script dépend de l'environnement OmniLab sur lequel tournent vos expériences. Utilisez la production, sauf si vous testez délibérément sur un autre, et gardez le script et le domaine d'expérience sur le même environnement — les mélanger produit une iframe qui se charge puis se comporte comme si la campagne n'existait pas.

EnvironnementAdresse du script
Productionhttps://cdn.21-digital.com/omplayer.js
UAThttps://cdn-uat.21-digital.com/omplayer.js
Développementhttps://cdn-dev.21-digital.com/omplayer.js
Conteneur + tag OmniLab
<div id="omnilab-container"></div>

<script>
  (function (b, o, n, u, s) {
    var a, t;
    a = b.createElement(u);
    a.async = 1;
    a.src = s;
    t = b.getElementsByTagName(u)[0];
    t.parentNode.insertBefore(a, t);
    o[n] = o[n] || [];
  })(document, window, "_om_async", "script", "https://cdn.21-digital.com/omplayer.js");

  _om_async.push([
    "init",
    {
      domain: "experience.example.com",
      targetId: "omnilab-container",
      queryParam: "id",
    },
  ]);
</script>

Une fois en place, c'est l'adresse de la page hôte qui décide quelle expérience se charge :

  • https://www.example.com/promo?id=summer-campaign
  • https://www.example.com/promo?id=summer-campaign?c=<touchpoint-id>

La valeur de id est le chemin après le domaine OmniLab. Un ? imbriqué passe tel quel, car le tag lit tout jusqu'au & suivant. Si vous devez transmettre plusieurs paramètres imbriqués, encodez toute la valeur pour que le & ne la tronque pas.

Inutile d'ajouter embedded=1 ici — le tag l'ajoute lui-même, avec l'adresse de la page hôte, au moment de construire l'iframe. Ce paramètre n'est à votre charge que si vous écrivez l'iframe vous-même.

Ce dont le tag a besoin de votre page

Trois choses, dont aucune n'est évidente à la lecture du snippet :

Laissez le conteneur vide. Le tag possède tout ce qui se trouve dans #omnilab-container — l'état de chargement, l'iframe, son habillage, sa largeur et sa hauteur. Si votre framework y affiche un placeholder ou un spinner, les deux se disputeront les mêmes nœuds. Affichez la div vide et laissez le tag la remplir.

Autorisez les deux domaines dans votre politique de sécurité de contenu. Si votre site envoie une CSP — c'est le cas de la plupart — l'intégration est bloquée silencieusement tant que vous n'ajoutez pas :

script-src  … https://cdn.21-digital.com
frame-src   … https://experience.votremarque.com

Autorisez le script de l'environnement que vous utilisez réellement. Si vous testez sur l'UAT depuis le même site, cet hôte doit aussi être autorisé, sinon le test échoue d'une façon qui ressemble à une campagne cassée.

frame-src désigne le domaine depuis lequel vos expériences sont servies — votre propre sous-domaine, conformément à l'exigence ci-dessus. C'est la raison la plus fréquente pour laquelle une intégration qui marchait sur une page de test échoue sur le vrai site : la page de test n'avait pas de politique, le vrai site en a une.

Réinitialisez après une navigation côté client. Le script se protège contre une double exécution : dans une application monopage qui quitte la page puis y revient, le tag ne redémarrera donc pas seul. Rappelez init une fois le script chargé.

Options

Passez-les dans le même objet que domain et targetId.

OptionDéfautRôle
domainL'adresse depuis laquelle vos expériences sont servies — votre sous-domaine OmniLab ou le vôtre. Obligatoire.
targetIdL'id du conteneur où l'iframe est insérée. Obligatoire.
queryParam"id"Quel paramètre de la page hôte porte le chemin OmniLab
width"100%"Largeur appliquée à l'iframe et à son conteneur
height"100px"Hauteur de départ, avant que l'expérience rapporte la sienne
iframeId"omnilab-iframe"id donné à l'iframe générée
iframeClass""Classes CSS supplémentaires sur l'iframe
iframeStyle"border: none;"Style inline sur l'iframe
allowFullscreeninactifAjoute les attributs plein écran
sandboxAttributesnon définiDéfinit un attribut sandbox avec la valeur donnée
stickyHeaderSelectordétectéUn sélecteur pour votre header sticky, pour que les drawers s'ouvrent en dessous
topOffset0Pixels fixes à laisser libres en haut, au lieu de la détection de header
scrollIntoViewOnNavigatetrueRamène l'embed dans le champ de vision quand le visiteur navigue à l'intérieur
instantGameHeightnon définiForce une hauteur d'iframe fixe pour les pages dimensionnées par le viewport
minFrameHeight320Plancher appliqué à la hauteur de viewport mesurée
maxFrameHeightnon définiPlafond appliqué à la hauteur de viewport mesurée

À confronter à votre propre CSS

Ces options habillent l'iframe générée par le tag. Si vous stylez aussi #omnilab-iframe depuis votre feuille de styles, assurez-vous que les deux concordent — celle qui perd le duel de spécificité gagne silencieusement la mise en page.

Headers sticky

Le tag repère seul un header de page standard et garde les drawers à l'écart, y compris quand le header défile hors du champ de vision. Indiquez le vôtre explicitement s'il n'est pas détecté :

Pointer le tag vers votre propre header
_om_async.push([
  "init",
  {
    domain: "experience.example.com",
    targetId: "omnilab-container",
    stickyHeaderSelector: "#site-nav",
  },
]);

Utilisez un sélecteur stable — un id ou un attribut de données, pas une classe de CSS-module hachée qui change à chaque build. Passez false pour désactiver la détection et utiliser topOffset à la place.

Écrire la page parente à la main

À ne faire que si quelque chose vous empêche de charger le tag. Le tag existe précisément pour vous éviter d'implémenter ce qui suit, et c'est le chemin sur lequel OmniLab teste.

Écrire la page parente vous-même signifie que vous prenez en charge la hauteur de l'iframe, le placement de tout drawer ouvert par l'expérience, et le maintien des deux quand l'expérience évolue. Tout ce qui suit est ce que le tag ferait à votre place.

Les entrées CSP restent nécessaires

Les deux directives ci-dessus s'appliquent dans les deux cas — le domaine de l'iframe doit être autorisé dans frame-src, que ce soit le tag ou vous qui la créiez.

Dimensionnement

L'expérience annonce à chaque chargement de page comment elle veut être dimensionnée, puis à chaque changement :

Message d'OmniLabCe que cela signifie
{ type: "sizing", mode: "content" }La page rapporte sa propre hauteur. Dimensionnez l'iframe à partir des messages resize qui suivent.
{ type: "sizing", mode: "viewport" }La page remplit l'iframe qu'on lui donne. Dimensionnez l'iframe vous-même, depuis votre propre viewport.

Les jeux instantanés sont dimensionnés par le viewport, car ils mesurent window.innerHeight — qui, dans une iframe, est la hauteur de l'iframe. Dimensionner l'iframe à partir d'une hauteur obtenue ainsi crée une boucle sans entrée extérieure et l'iframe se fige. OmniLab supprime totalement resize en mode viewport pour cette raison.

Le mode appartient à la page, pas à l'embed. Revenir d'un jeu vers une page d'accueil repasse en dimensionnement par le contenu et la page le ré-annonce : conservez donc le mode dans une variable.

Listener resize sur la page parente
<script>
  window.addEventListener("message", (event) => {
    if (event.origin !== "https://experience.example.com") return;

    const data = event.data;
    if (data?.type !== "resize" || data?.target !== "body") return;
    if (typeof data?.data?.height !== "number" || data.data.height < 100) return;

    const iframe = document.querySelector("#omnilab-embed");
    if (iframe) iframe.style.height = data.data.height + "px";
  });
</script>

OmniLab regroupe ces messages à un par frame d'animation et supprime les répétitions d'une même hauteur : appliquez-les directement, sans debounce. Ignorez toute valeur inférieure à 100 pixels (page en cours de mise en page) et toute valeur arrivant pendant qu'un drawer est ouvert (le viewport de l'iframe est alors la boîte du drawer ; l'appliquer rétrécit l'embed une fois refermé).

Drawers

D'OmniLabQuand
open-modalLe premier drawer s'ouvre. Les drawers imbriqués ne le répètent pas.
close-modal (avec source)Le dernier drawer se ferme : cela signifie toujours « entièrement fermé ».
Vers OmniLabRôle
ready-to-open-modal (avec parentHeight, parentWidth, scrollTop, stickyOffset, position)Accuse réception de open-modal et transmet au drawer la portion de l'iframe réellement visible. À envoyer à chaque open-modal, y compris imbriqué.
ready-to-close-modal (avec source)Ferme le drawer au sommet de la pile. À envoyer quand votre propre interface le referme.

Si vous n'envoyez jamais ready-to-open-modal, les drawers s'ouvrent quand même — ils se replient sur une présentation par défaut en pleine hauteur.

Vérifiez event.origin dans tout ce que vous mettez en production. Le tag le fait déjà ; un listener écrit à la main qui l'omet réagira aux messages de n'importe quelle page chargée dans l'iframe.

Pour aller plus loin

Sur cette page