IAB Transparency and Consent Framework (TCF) Tool Suite

repository·master·Indexed 41 days ago

https://github.com/interactiveadvertisingbureau/iabtcf-es

A comprehensive TypeScript/JavaScript toolkit for implementing IAB TCF v2.3. The suite includes @iabtechlabtcf/core for encoding/decoding TC Strings and managing the Global Vendor List (GVL), @iabtechlabtcf/cmpapi for providing CMP transparency and consent information to digital marketing technologies, @iabtechlabtcf/cli for terminal-based TC String decoding, and @iabtechlabtcf/stub for mocking the __tcfapi() function during development.

Tokens
15.1K
Snippets
56
Records
70
Agent score
100%

What's inside IAB TCF

  1. Overview of the @iabtechlabtcf tool suite

    master
    The @iabtechlabtcf suite is an official JavaScript/TypeScript compliant toolkit for implementing the Transparency and Consent Framework (TCF) v2.3. It is designed primarily for Consent Management Platforms (CMPs) and provides the essential tools for managing TC strings and vendor lists.
  2. Implement custom commands

    master

    You can extend the window.__tcfapi functionality by passing a map of custom commands to the CmpApi constructor.

    Requirements:

    • Custom functions must accept a callback as the first parameter.
    • The CMP is responsible for validating and handling errors within these functions.

    Middleware Pattern: Starting from version 1.1.0, if a custom command name overlaps with a built-in command ("ping", "getTCData", "getInAppTCData", "getVendorList"), the custom command acts as middleware. It receives the built-in command's response and must call a next() function to pass the response along to the original caller.

    import {CmpApi} from '@iabtechlabtcf/cmpapi';
    
    const cmpApi = new CmpApi(1, 3, false, {
      // Standard custom command
      'bingo': (callback, dogName) => {
        callback(`There was a farmer who had a dog, and ${dogName} was his name-o`);
      },
    
      // Middleware for a built-in command
      'getTCData': (next, tcData, status) => {
        // Note: when used with 'removeEventListener', tcData might be a boolean
        if (typeof tcData !== 'boolean') {
          tcData.reallyImportantExtraProperty = true;
        }
        // You MUST call next() or the caller's callback will never execute
        next(tcData, status);
      },
    });
    
    // Calling a custom command via the global __tcfapi
    __tcfapi('bingo', 2, (lyrics, success) => {
      if(success) console.log(lyrics);
    }, 'Bingo');
  3. Explore the @iabtechlabtcf modules

    master

    The project is a monorepo consisting of five specialized modules:

    • Core (@iabtechlabtcf/core): Used for encoding and decoding Transparency and Consent (TC) strings and managing the Global Vendor List (GVL).
    • CmpApi (@iabtechlabtcf/cmpapi): Provides the in-page CMP API (__tcfapi()) and integrates with the core library.
    • cli (@iabtechlabtcf/cli): A command-line interface tool for decoding TC strings.
    • Testing (@iabtechlabtcf/testing): Utilities for testing the core library, including generators for random TCModel and GVL data.
    • Stub (@iabtechlabtcf/stub): Contains the code for the on-page __tcfapi() CMP stub.
  4. Manage consents using Vectors in TCModel

    master

    The TCModel uses a Vector data structure (similar to a JavaScript Set) to manage consents, opt-ins, and restrictions. This applies to properties like vendorConsents, purposeConsents, specialFeatureOptins, and various publisher properties.

    Common Vector methods include:

    • .set(id) or .set([ids]): Add a single ID or an array of IDs.
    • .has(id): Check if an ID is present.
    • .unset(id): Remove an ID.
    • .empty(): Clear all IDs.
    • .size: Get the number of elements.
    • .maxId: Get the highest ID in the vector.
    • .forEach((value, id) => ...): Iterate through the vector.
    // Give Vendor ID 24 consent
    tcModel.vendorConsents.set(24);
    
    console.log(tcModel.vendorConsents.has(24)); // true
    console.log(tcModel.vendorConsents.maxId); // 24
    console.log(tcModel.vendorConsents.size); // 1
    
    // remove vendor 24
    tcModel.vendorConsents.unset(24);
    console.log(tcModel.vendorConsents.has(24)); // false
    
    // give a group of vendors consent
    tcModel.vendorConsents.set([24, 14, 24, 100, 102]);
    console.log(tcModel.vendorConsents.has(24)); // true
    console.log(tcModel.vendorConsents.maxId); // 102
    console.log(tcModel.vendorConsents.size); // 5
    
    // loop through all ids 1 to maxId
    tcModel.vendorConsents.forEach((hasConsent, vendorId) => {
      // check each id for consent
    });
    
    // empty everything
    tcModel.vendorConsents.empty();
  5. Build the stub for direct page inclusion

    master

    If you need to drop the built stub directly onto a webpage, you must build it from the source repository. The built files will be output to the ./lib directory.

    git clone https://github.com/InteractiveAdvertisingBureau/iabtechtabtcf-es.git
    cd iabtechlabtcf-es/modules/stub/
    yarn // or npm install
    yarn build // or npm run build
  6. Instantiate and use the GVL class

    master

    The GVL (Global Vendor List) class can be instantiated in three ways: by autoloading the latest version, autoloading a specific version, or passing a pre-loaded JSON object.

    Important: When autoloading, you must set the static GVL.baseUrl property before creating an instance. Use gvl.readyPromise to ensure the asynchronous loading is complete before accessing data.

    Autoloading Latest

    Set GVL.baseUrl. If GVL.latestFilename is set, it will use that instead of the default vendor-list.json.

    Autoloading Specific Version

    Pass the version number to the constructor. You can customize the filename pattern using GVL.versionedFilename (use the [VERSION] token).

    Passing JSON Object

    If you already have the vendor-list.json object, pass it directly to the constructor. This is synchronous and does not require waiting for readyPromise.

    import {GVL} from '@iabtechlabtcf/core';
    
    // Autoload latest
    GVL.baseUrl = 'http://cmp.mysupercoolcmp.com/cmp/';
    const gvl = new GVL();
    await gvl.readyPromise;
    
    // Autoload specific version
    GVL.baseUrl = 'http://cmp.mysupercoolcmp.com/cmp/';
    const gvlVersioned = new GVL(23);
    await gvlVersioned.readyPromise;
    
    // Pass object directly
    const gvlFromObject = new GVL(gvljson);
  7. Initialize the CMP API Stub via module loading

    master

    To use the stub in a JavaScript environment, import the module and execute the default export. Executing the function initializes the __tcfapi() window function, which includes the necessary queuing functionality for TCF commands.

    // Using ES Modules
    import * as cmpstub from '@iabtechlabtcf/stub';
    
    // Or using CommonJS
    const cmpstub = require('@iabtechlabtcf/stub');
    
    // Execute to generate the __tcfapi() window function
    cmpstub();
  8. How the GVL class works

    master

    The GVL class acts as a manager for the Global Vendor List JSON data. It handles fetching the JSON from a configured baseUrl, caching the results (both the vendor list and language translations) to optimize performance, and providing high-level accessors to group vendors by their declared Purposes or Features.

    Lifecycle:

    1. Configuration: Set GVL.baseUrl.
    2. Instantiation: Create new GVL(...).
    3. Resolution: Wait for gvl.readyPromise to resolve.
    4. Usage: Access gvl.vendors, gvl.purposes, or use helper methods like getVendorsWithPurpose().

    Caching:

    • The class maintains static caches for both the vendor lists (by version) and language translations.
    • You can manually clear these using GVL.emptyCache(version?) or GVL.emptyLanguageCache(lang?).
    // Typical usage pattern
    GVL.baseUrl = 'https://my-cache.com/';
    const gvl = new GVL();
    
    gvl.readyPromise.then(() => {
      console.log('GVL is ready:', gvl.vendorListVersion);
      console.log('Vendors:', gvl.vendors);
    });