Alterner les créations publicitaires avec l'API Select URL

Utilisez l'API Select URL pour profiter du stockage partagé et déterminer la création qu'un utilisateur voit sur les sites.

Un annonceur ou un producteur de contenu peut souhaiter appliquer différentes stratégies de rotation de contenu à une campagne et faire tourner les contenus ou les créations pour accroître l'efficacité. L'API Select URL peut être utilisée pour exécuter différentes stratégies de rotation, telles que la rotation séquentielle et la rotation à répartition égale, sur différents sites.

Avec la rotation des créations de l'API Select URL, vous pouvez stocker des données telles que l'ID de la création, le nombre de vues et l'interaction des utilisateurs pour déterminer la création que les utilisateurs voient sur différents sites.

Pour en savoir plus sur l'API sous-jacente et sur le fonctionnement de la sélection, consultez la documentation de l'API Select URL.

Essayer la rotation des créations

Pour tester la rotation des créations, assurez-vous que l'API Select URL et Shared Storage sont activés :

  • Dans chrome://settings/content/siteData, sélectionnez Allow sites to save data on your device ou Delete data sites have saved to your device when you close all windows.
  • Dans chrome://settings/adPrivacy/sites, sélectionnez Site-suggested ads.

Testez notre démonstration en direct du stockage partagé pour obtenir une version en direct des exemples de code de ce document.

Démonstration avec des exemples de code

Dans cet exemple :

  • creative-rotation.js est le script tiers qui définit le contenu à faire tourner, ainsi que toutes les données qui déterminent le prochain contenu à sélectionner et à afficher, comme les pondérations dans cet exemple. La page de l'éditeur exécute ce script. Ce script appelle le worklet Shared Storage pour déterminer le contenu à afficher en fonction des données disponibles dans le stockage et de la liste des URL à partir desquelles effectuer la sélection.

  • creative-rotation-worklet.js est le worklet de stockage partagé du tiers qui recherche la stratégie de rotation, calcule le contenu à publier ensuite et renvoie ce contenu.

Fonctionnement de la démo

  1. Lorsqu'un utilisateur accède à la page de l'éditeur, le script creative-rotation.js du tiers se charge. Le script de rotation des créations est chargé de charger et d'exécuter le worklet de stockage partagé. Le script fournit à l'appel de worklet une liste d'URL à partir de laquelle effectuer la sélection.
  2. Dans le worklet, si le stockage partagé n'a pas encore été initialisé, il l'est avec la stratégie de rotation des créations et l'index des créations initiaux. La stratégie de rotation initiale utilisée dans cette démo est la stratégie séquentielle.
  3. Le worklet lit le mode de rotation à partir du stockage partagé et renvoie l'index de la prochaine annonce. Dans le cas du mode de rotation séquentielle, il met également à jour l'index de la création dans le stockage partagé avec la nouvelle valeur à utiliser pour le prochain appel.Le worklet renvoie un objet FencedFrameConfig ou URN opaque en fonction de la valeur resolveToConfig utilisée lors de l'appel de selectURL.
  4. Le script de rotation des créations affiche l'annonce sélectionnée dans un cadre clôturé ou un iFrame. Pour en savoir plus sur les types de valeurs renvoyées, consultez le document sur l'affichage d'une annonce.
  5. Lorsqu'un utilisateur modifie le mode de rotation, le worklet Shared Storage met à jour la valeur du mode de rotation de la création stockée dans Shared Storage.
  6. Lorsque la page de l'éditeur est rechargée, les étapes 1 à 4 sont répétées, ce qui permet de sélectionner la prochaine annonce à afficher en fonction de la stratégie de rotation sélectionnée.

Exemples de code

Vous trouverez ci-dessous les exemples de code pour creative-rotation.js et creative-rotation-worklet.js.

creative-rotation.js

const contentProducerUrl = 'https://your-server.example';

// Ad config with the URL of the ad, a probability weight for rotation, and the clickthrough rate.
const DEMO_AD_CONFIG = [
  {
    url: `${contentProducerUrl}/ads/ad-1.html`,
    weight: 0.7,
  },
  {
    url: `${contentProducerUrl}/ads/ad-2.html`,
    weight: 0.2,
  },
  {
    url: `${contentProducerUrl}/ads/ad-3.html`,
    weight: 0.1,
  },
];

async function setRotationMode(rotationMode) {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  await creativeRotationWorklet.run('set-rotation-mode', {
    data: { rotationMode }
  });
  console.log(`creative rotation mode set to ${rotationMode}`);
}

async function injectAd() {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  const urls = DEMO_AD_CONFIG.map(({ url }) => ({ url }));

  // Resolve the selectURL call to a fenced frame config only when it exists on the page
  const resolveToConfig = typeof window.FencedFrameConfig !== 'undefined';

  // Run the URL selection operation to determine the next ad that should be rendered
  const selectedUrl = await creativeRotationWorklet.selectURL('creative-rotation', urls, {
    data: DEMO_AD_CONFIG,
    resolveToConfig
  });

  const adSlot = document.getElementById('ad-slot');

  if (resolveToConfig && selectedUrl instanceof FencedFrameConfig) {
    adSlot.config = selectedUrl;
  } else {
    adSlot.src = selectedUrl;
  }
}

injectAd();

creative-rotation-worklet.js

class SelectURLOperation {
  async run(urls, data) {
    // Initially set the storage to sequential mode for the demo
    await SelectURLOperation.seedStorage();

    // Read the rotation mode from Shared Storage
    const rotationMode = await sharedStorage.get('creative-rotation-mode');

    // Generate a random number to be used for rotation
    const randomNumber = Math.random();

    let index;

    switch (rotationMode) {
      /**
       * Sequential rotation
       * - Rotates the creatives in order
       * - Example: A -> B -> C -> A ...
       */
      case 'sequential':
        const currentIndex = await sharedStorage.get('creative-rotation-index');
        index = parseInt(currentIndex, 10);
        const nextIndex = (index + 1) % urls.length;

        console.log(`index = ${index} / next index = ${nextIndex}`);

        await sharedStorage.set('creative-rotation-index', nextIndex.toString());
        break;

      /**
       * Evenly-distributed rotation
       * - Rotates the creatives with equal probability
       * - Example: A=33% / B=33% / C=33%
       */
      case 'even-distribution':
        index = Math.floor(randomNumber * urls.length);
        break;

      /**
       * Weighted rotation
       * - Rotates the creatives with weighted probability
       * - Example: A=70% / B=20% / C=10%
       */
      case 'weighted-distribution':
        console.log('data = ', JSON.stringify(data));
        // Find the first URL where the cumnulative sum of the weights
        // exceed the random number. The array is sorted by the weight
        // in descending order.
        let weightSum = 0;
        const { url } = data
          .sort((a, b) => b.weight - a.weight)
          .find(({ weight }) => {
            weightSum += weight;
            return weightSum > randomNumber;
          });

        index = urls.indexOf(url);
        break;

      default:
        index = 0;
    }

    console.log(JSON.stringify({ index, randomNumber, rotationMode }));
    return index;
  }

  // Set the mode to sequential and set the starting index to 0.
  static async seedStorage() {
    await sharedStorage.set('creative-rotation-mode', 'sequential', {
      ignoreIfPresent: true,
    });

    await sharedStorage.set('creative-rotation-index', 0, {
      ignoreIfPresent: true,
    });
  }
}

class SetRotationModeOperation {
  async run({ rotationMode }) {
    await sharedStorage.set('creative-rotation-mode', rotationMode);
  }
}

// Register the operation as 'creative-rotation'
register('creative-rotation', SelectURLOperation);
register('set-rotation-mode', SetRotationModeOperation);

Procédure détaillée avec captures d'écran

  1. Pour accéder à la rotation des créations à l'aide de l'API Select URL et du stockage partagé, accédez à https://shared-storage-demo.web.app/. Choisissez la démo "Rotation des créations".

  2. Choisissez d 'explorer la démo en tant qu'éditeur A. Vous serez redirigé vers https://shared-storage-demo-publisher-a.web.app/creative-rotation. La page charge le contenu numéroté en fonction des données de rotation des créations enregistrées dans Shared Storage, accessibles via l'API Select URL. Les modes de démonstration pour la rotation des créations sont la distribution séquentielle, la distribution uniforme et la distribution pondérée. Le worklet exécute la logique permettant de sélectionner le contenu qui s'affiche dans l'iframe. L'image suivante montre la page de l'éditeur. Capture d'écran montrant le contenu de la page de l'éditeur A https://shared-storage-demo-publisher-a.web.app/creative-rotation contenant un iFrame avec une image du chiffre 1, des commandes permettant de choisir les stratégies de rotation des créations (séquentielle, distribution uniforme et distribution pondérée). Une zone de texte décrit également les différentes stratégies de rotation des créations et fournit des liens vers les logiques d'iframe et de worklet.

    Capture d'écran de la page de l'éditeur A avec l'image du chiffre 1 et les commandes permettant de choisir les stratégies de rotation des créations.

  3. Pour afficher ce qui est stocké dans Shared Storage, accédez à Application > Shared Storage dans les outils de développement Chrome. Deux entrées sont créées pour l'espace de stockage partagé. Un espace de stockage vide est disponible pour l'origine https://shared-storage-demo-publisher-a.web.app. Il contiendra le stockage spécifique à cette origine et restera vide pour notre démonstration, car l'éditeur n'a pas besoin d'écrire dans le stockage partagé. Notez qu'un espace de stockage similaire sera créé pour l'éditeur B lorsque vous visiterez cette page ultérieurement pour la démonstration. Capture d'écran montrant les Outils pour les développeurs Chrome, plus précisément la section "Application", mettant en évidence les entrées de stockage partagé et montrant le stockage vide pour l'origine "Éditeur A" https://shared-storage-demo-publisher-a.web.app

    Les outils pour les développeurs Chrome affichent un stockage partagé vide pour l'éditeur A.

  4. Une autre entrée Shared Storage sera créée pour l'origine https://shared-storage-demo-content-producer.web.app. Il s'agit du stockage de l'iFrame tiers intégré à la page de l'éditeur. Cet espace de stockage sera utilisé pour partager des données entre les deux éditeurs disponibles afin de coordonner la sélection des créations. Cet espace de stockage partagé servira à enregistrer des informations sur la création affichée et la stratégie de rotation en enregistrant deux paires clé-valeur. La première clé utilisée dans la démo est creative-rotation-index, dont la valeur est l'index de la création actuelle en mode séquentiel. La deuxième clé est creative-rotation-mode, qui détermine la stratégie de rotation utilisée. Capture d'écran montrant les outils de développement Chrome, en particulier le stockage partagé pour l'origine https://shared-storage-demo-content-producer.web.app. Le stockage n'est pas vide et affiche deux paires clé/valeur enregistrées. La première clé est "creative-rotation-index" avec la valeur 1. La deuxième clé enregistrée est "creative-rotation-mode" avec la valeur "sequential".

    Capture d'écran montrant le stockage partagé des outils pour les développeurs Chrome avec deux paires clé/valeur : creative-rotation-index: 1 et creative-rotation-mode: "sequential".

  5. Si vous actualisez la page en mode séquentiel, la création suivante de la séquence s'affiche (1, 2, 3, 1, etc.). La valeur de la clé creative-rotation-index change en fonction de l'index de la création affichée en mode séquentiel. Capture d'écran montrant la page Web de l'éditeur A ainsi que les outils de développement affichant la section "Shared Storage" (Stockage partagé). La création sur la page est étiquetée 2, tandis que la valeur de la clé "creative-rotation-index" est également mise en évidence et correspond à l'index de la création affichée. Le mode de rotation des créations actuel est séquentiel.

    Capture d'écran montrant la page Web de l'éditeur A et les outils de développement. La création affichée est la création 2, le mode de rotation des créations est séquentiel et l'index de rotation des créations est 2.

  6. Si vous modifiez le mode de rotation des créations à l'aide des boutons de commande, la valeur de la clé "creative-rotation-mode" sera mise à jour dans la stratégie correspondante. Le code du worklet l'utilisera pour choisir la prochaine création à afficher dans l'iFrame. Notez que la valeur enregistrée pour creative-rotation-index ne change pas pour les modes de rotation autres que séquentiel. Capture d'écran montrant la page Web de l'éditeur A ainsi que les outils de développement affichant la section "Shared Storage" (Stockage partagé). La création sur la page est indiquée par le chiffre 1. Mise en évidence du mode de rotation des créations défini sur "Distribution pondérée" et du contrôle correspondant permettant de définir le mode de rotation sur "Distribution pondérée". La valeur de creative-rotation-index est définie sur 2, alors que la création affichée est la création 1. En effet, l'index n'est pas utilisé ni mis à jour pour les modes de rotation autres que séquentiel.

    Capture d'écran montrant la page Web de l'éditeur A et les outils de développement. La création affichée est 1, le mode de rotation des créations est la distribution pondérée et l'index de rotation des créations est 2 (non utilisé).

  7. Accédez à la page de l'éditeur B à l'adresse https://shared-storage-demo-publisher-b.web.app/creative-rotation. En mode séquentiel, la création affichée doit être la suivante dans la séquence lorsqu'un utilisateur accède à l'URL de l'éditeur A. En inspectant le stockage partagé du producteur de contenu, vous pouvez constater que "Éditeur A" et "Éditeur B" partagent le même stockage et utilisent les paramètres qui y sont définis pour sélectionner la prochaine création à afficher et la stratégie de rotation à utiliser. Capture d'écran montrant la page Web de l'éditeur B ainsi que les outils de développement affichant la section "Shared Storage" (Stockage partagé) pour l'origine https://shared-storage-demo-content-producer.web.app. La création sur la page est affichée sous le numéro 3. L'index de rotation des créations mis en évidence est défini sur 3 et le mode de rotation des créations est séquentiel.

    Page Web et outils de développement de l'éditeur B. La création de stockage partagé est définie sur 3, l'index de rotation des créations est défini sur 3 et le mode de rotation des créations est défini sur "séquentiel".

  8. Le stockage partagé de "Éditeur B" est vide, comme celui de "Éditeur A".  Capture d'écran des Outils pour les développeurs Chrome, plus précisément de la section "Application", mettant en évidence les entrées de stockage partagé et montrant le stockage vide pour l'origine "Éditeur B" https://shared-storage-demo-publisher-b.web.app.

    Les outils pour les développeurs Chrome affichent un espace de stockage partagé vide pour l'origine de l'éditeur B.

    Cas d'utilisation

    Vous trouverez dans cette section tous les cas d'utilisation disponibles pour l'API Select URL. Nous continuerons d'ajouter des exemples à mesure que nous recevrons des commentaires et découvrirons de nouveaux cas de test.

Interagir et envoyer des commentaires

Notez que la proposition d'API Select URL est en cours de discussion et de développement, et qu'elle est susceptible d'être modifiée.

Nous aimerions connaître votre avis sur l'API Select URL.