Consent Management

By default, Fuse integrates the Quantcast Consent Management Platform (CMP) at no additional charge. However, Fuse is also compatible with all IAB compliant CMPs.

If you wish to use your own CMP, please notify Publift during the onboarding process.

Quantcast CMP

Personalisation widget

Fuse includes a widget which allows your European/Californian users easy opt-in/out of ad personalisation.

This is done using the following snippet:

<style>
  #fuse-privacy-tool {
    font-size: 0.5rem;
  }
</style>
<div data-fuse-privacy-tool></div>

This widget will only work if fuse.js has been included in the header of your privacy page, however there is no requirement to add body tags.

California Consumer Privacy Act (CCPA) Compliance

As part of CCPA compliance, you will need to offer your Californian users the ability to opt in/out of ad personalisation. This opt-in/out process is best linked from your Privacy Policy.

Please add the following snippet to your privacy policy:

California Consumer Privacy Act (“CCPA”)

Under CCPA, Californian residents have the right to declare their preferences on the sale
of data for advertising and marketing purposes. If you wish to change your preferences,
click this link to launch our preference portal:

{INSERT data-fuse-privacy-tool DIV HERE}

We use a third-party to provide monetisation technologies for our site. You can review their
privacy and cookie policy at https://publift.com/privacy-policy/.

3rd-Party CMP

If you have elected to use a 3rd-party CMP, please notify Publift so we can ensure Quantcast is disabled.

Publift will validate that your CMP is working correctly during onboarding, and will contact you if there are any issues.

Testing CMP

To properly validate GDPR/CCPA compliance, you will need to use a VPN so that your traffic appears to the CMP as originating from a regulated region.

Subscribing to Fuse CMP events

If you are using the CMP provided by Fuse, and have other scripts on your page which need to listen to CMP events, the best approach is to embed a ‘stub’ CMP directly into a <script> section at the top of your document <body>.

This approach allows other scripts to subscribe to CMP events at any stage in the page lifecycle, and the events will fire events once the stub is replaced with a real CMP.

CMP Stub

Place the stub below in the <head> section of your page.

Now you can subscribe to CMP events as follows:

<script type="text/javascript">
  __tcfapi('addEventListener', 2, function( tcData, success ) {
    console.log(`CMP event fired: ${JSON.stringify(tcData)}`);
  });
</script>

An example of this approach can be found by viewing the source code of the dynamic page example.

<script type="text/javascript">
  (function() {
    function makeStub() {
      var TCF_LOCATOR_NAME = '__tcfapiLocator';
      var queue = [];
      var win = window;
      var cmpFrame;

      function addFrame() {
        var doc = win.document;
        var otherCMP = !!(win.frames[TCF_LOCATOR_NAME]);

        if (!otherCMP) {
          if (doc.body) {
            var iframe = doc.createElement('iframe');

            iframe.style.cssText = 'display:none';
            iframe.name = TCF_LOCATOR_NAME;
            doc.body.appendChild(iframe);
          } else {
            setTimeout(addFrame, 5);
          }
        }
        return !otherCMP;
      }

      function tcfAPIHandler() {
        var gdprApplies;
        var args = arguments;

        if (!args.length) {
          return queue;
        } else if (args[0] === 'setGdprApplies') {
          if (
            args.length > 3 &&
            args[2] === 2 &&
            typeof args[3] === 'boolean'
          ) {
            gdprApplies = args[3];
            if (typeof args[2] === 'function') {
              args[2]('set', true);
            }
          }
        } else if (args[0] === 'ping') {
          var retr = {
            gdprApplies: gdprApplies,
            cmpLoaded: false,
            cmpStatus: 'stub'
          };

          if (typeof args[2] === 'function') {
            args[2](retr);
          }
        } else {
          queue.push(args);
        }
      }

      function postMessageEventHandler(event) {
        var msgIsString = typeof event.data === 'string';
        var json = {};

        try {
          if (msgIsString) {
            json = JSON.parse(event.data);
          } else {
            json = event.data;
          }
        } catch (ignore) {}

        var payload = json.__tcfapiCall;

        if (payload) {
          window.__tcfapi(
            payload.command,
            payload.version,
            function(retValue, success) {
              var returnMsg = {
                __tcfapiReturn: {
                  returnValue: retValue,
                  success: success,
                  callId: payload.callId
                }
              };
              if (msgIsString) {
                returnMsg = JSON.stringify(returnMsg);
              }
              if (event && event.source && event.source.postMessage) {
                event.source.postMessage(returnMsg, '*');
              }
            },
            payload.parameter
          );
        }
      }

      while (win) {
        try {
          if (win.frames[TCF_LOCATOR_NAME]) {
            cmpFrame = win;
            break;
          }
        } catch (ignore) {}

        if (win === window.top) {
          break;
        }
        win = win.parent;
      }
      if (!cmpFrame) {
        addFrame();
        win.__tcfapi = tcfAPIHandler;
        win.addEventListener('message', postMessageEventHandler, false);
      }
    }

    makeStub();
  })();
</script>