Skip to content

Examples ​

A simple page that requests a TrueX ad with client.js, shows a trigger point, and loads the ad into a container when the user selects it. The whole integration is one page, so there is no separate reference app.

Live ads

The example requests a real ad. Staying with the ad and interacting with it behaves like a real TrueX ad.

Live Example ​

Select the trigger, interact with the ad for about 30 seconds, and watch the log. When the user closes the ad, the page requests a new one.

What the Example Shows ​

  • truex.client is created with the user_id and the placement_hash. The demo generates a new user_id for each page load.
  • client.requestAd returns an ad, or nothing if no ad is available. The page shows the trigger point only when there is an ad, and calls trackTriggerPointImpression.
  • The ad opens in the page's container with loadAdIntoContainer, sized with width and height options.
  • onCredit fires after about 30 seconds and one interaction. This is where your page sends the engagement to your server, which verifies it and grants the reward. It is shown in bold in the log.
  • onClose removes the container and requests a new ad, so an expired ad is never shown.

Full Listing ​

The page that runs in the live example above:

html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>client.js demo</title>
<style>
  html, body { margin: 0; height: 100%; font-family: sans-serif; }
  body { background: #F0F0F0; color: #2D2D2D; }
  #trigger {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 12px;
    height: 100%; text-align: center; padding: 16px; box-sizing: border-box;
  }
  #trigger button {
    display: flex; flex-direction: column; align-items: center; gap: 12px;
    max-width: 60%; max-height: 90%; padding: 16px 16px 14px;
    border: 0; border-radius: 12px;
    background: #9920E7; color: #fff; font-size: 16px; cursor: pointer;
  }
  #trigger img { min-height: 0; max-width: 100%; border-radius: 8px; }
  /* The same offset on all sides keeps the ad clear of the Close button */
  #adView {
    position: fixed; inset: 0; box-sizing: border-box;
    padding: 36px; background: #F0F0F0;
  }
  #adContainer { position: relative; width: 100%; height: 100%; background: #000; }
  #close {
    position: absolute; top: 5px; right: 36px;
    padding: 4px 12px; border: 0; border-radius: 6px;
    background: #606061; color: #fff; cursor: pointer;
  }
  [hidden] { display: none !important; }
</style>
<script src="https://static.truex.com/js/client.js"></script>
</head>
<body>
<div id="trigger"></div>
<div id="adView" hidden>
  <button id="close" type="button">Close</button>
  <div id="adContainer"></div>
</div>
<script>
  // Placement hash provided by Infillion for your placement
  const PLACEMENT_HASH = 'f36118c71a996fd53537f3f05e533291f0f85b6f';
  // Any string that identifies the current user
  const USER_ID = 'docs-demo-' + crypto.randomUUID();

  const trigger = document.getElementById('trigger');
  const adView = document.getElementById('adView');
  const adContainer = document.getElementById('adContainer');
  const closeButton = document.getElementById('close');
  let adOpen = false;

  // Sends an event to the docs page, which shows it in the log
  function notify(name, detail) {
    parent.postMessage(
      { source: 'clientjs-demo', name: name, detail: detail || '' },
      location.origin
    );
  }

  function showMessage(text) {
    trigger.textContent = text;
  }

  function showTrigger(ad, client) {
    trigger.innerHTML = '';

    const image = document.createElement('img');
    image.src = ad.image_url;
    image.alt = '';

    const label = document.createElement('span');
    label.textContent = ad.display_text || 'Watch ad';

    // The ad image is part of the call-to-action
    const button = document.createElement('button');
    button.type = 'button';
    button.setAttribute('aria-label', ad.name);
    button.append(image, label);
    button.addEventListener('click', function () {
      openAd(ad, client);
    });

    trigger.append(button);
  }

  function openAd(ad, client) {
    adOpen = true;
    adView.hidden = false;
    client.loadAdIntoContainer(ad, adContainer, {
      width: '100%',
      height: '100%'
    });
  }

  // Remove the ad and request a fresh one, so that no expired ad is shown
  function closeAd(client) {
    if (!adOpen) {
      return;
    }
    adOpen = false;
    adContainer.innerHTML = '';
    adView.hidden = true;
    requestAd(client);
  }

  function requestAd(client) {
    showMessage('Requesting an ad...');
    client.requestAd(function (ad) {
      if (!ad) {
        showMessage('No ad available for this user.');
        notify('requestAd', 'no ad');
        return;
      }

      ad.onStart(function () {
        notify('onStart');
      });
      ad.onCredit(function (engagement) {
        // The user spent 30 seconds and interacted at least once.
        // Verify engagement.signature on your server, then grant the reward.
        notify('onCredit', engagement.key);
      });
      ad.onFinish(function () {
        notify('onFinish');
      });
      ad.onError(function () {
        notify('onError');
        closeAd(client);
      });
      ad.onClose(function () {
        notify('onClose');
        closeAd(client);
      });

      // Optional: lets Infillion calculate the click-through rate
      client.trackTriggerPointImpression(ad);
      showTrigger(ad, client);
      notify('requestAd', ad.name);
    });
  }

  truex.client(
    { user_id: USER_ID, placement_hash: PLACEMENT_HASH },
    function (client) {
      closeButton.addEventListener('click', function () {
        notify('closed by the page');
        closeAd(client);
      });
      requestAd(client);
    }
  );
</script>
</body>
</html>

Integration documentation for Infillion Ads