@d-cat/tag-manager

A fully Node, Web and TypeScript supported Tag Manager. Designed, developed and maintained by D-CAT.

Usage no npm install needed!

<script type="module">
  import dCatTagManager from 'https://cdn.skypack.dev/@d-cat/tag-manager';
</script>

README

@d-cat/tag-manager

codecov

A fully node, web and TypeScript supported Tag Manager. It offers 100% control on manipulating your environment through a Tag Manager. The built-in dataLayer provides everything you need to futurize your Tag Management.

Install

npm i @d-cat/tag-manager

Usage

The constructor accepts 1 parameter: a manifest, with the following keys:


parameter type Description
dataLayer Object Object that is used to initialize DDM.
date Date Release date of Tag Manager.
id Number Container ID.
prefix String The prefix of the container.
releaseId String Unique releaseID of this deployment.
tags ITags[] An array with the object structure of a tag. More about tags in the next chapter.
version String Version of the used Tag Manager package.

The render method is the main method of the class. The other methods are invoked within the constructor. You can override this behavior.

import TagManager from '@d-cat/tag-manager';

const myTagManager = () => {
  const tagManager = new TagManager({
    dataLayer: {
      events: ['_ddm.loaded', '_dd.loaded', '_ddm.core.initiated.ready'],
      listenKey: '_ddm.restored',
      version: '2.0.1',
      hooks: '4.0.0',
    },
    date: new Date(Date.now()),
    id: Math.random(),
    prefix: 'vodafone',
    tags: [], // tags array
    version: '1.0.0',
  });

  return tagManager.render(); // undefined
};

NOTE: for convenience the constructor invokes initializeDataLayer, filterTagsOnUrl and sortTagsOnPriority.

initializeDataLayer: void

The initializeDataLayer method initializes DDM on either global (Node) or window (Web). DDM is our Event Emitter and state tree and only communication layer between services.

Once DDM is initialized, it will trigger tag-manager:start.

Example

import TagManager from '@d-cat/tag-manager';

class MyTagManager extends TagManager {
  constructor(...args: any[]) {
    super(...args);
  }

  protected initializeDataLayer(...args: any[]): void {
    super.initializeDataLayer(...args);
    // your logic
  }
}

const myTagManager = () => {
  const tagManager = new MyTagManager({
    dataLayer: {
      events: ['_ddm.loaded', '_dd.loaded', '_ddm.core.initiated.ready'],
      listenKey: '_ddm.restored',
      version: '2.0.1',
      hooks: '4.0.0',
    },
    date: new Date(Date.now()),
    id: Math.random(),
    prefix: 'vodafone',
    tags: [], // tags array
    version: '1.0.0',
  });

  return tagManager.initializeDataLayer(); // undefined
};

filterTagsOnUrl(tags?: ITags[]): ITags[]

The filterTagsOnUrl is used to return only the tags that should execute on the current page. To determine which tags are applicable, it uses the urls array in manifest.

Example

import TagManager from '@d-cat/tag-manager';

class MyTagManager extends TagManager {
  constructor(...args: any[]) {
    super(...args);
  }

  protected filterTagsOnUrl(...args: any[]): void {
    super.filterTagsOnUrl(...args);
    // your logic
  }
}

const myTagManager = () => {
  const tagManager = new MyTagManager({
    dataLayer: {
      events: ['_ddm.loaded', '_dd.loaded', '_ddm.core.initiated.ready'],
      listenKey: '_ddm.restored',
      version: '2.0.1',
      hooks: '4.0.0',
    },
    date: new Date(Date.now()),
    id: Math.random(),
    prefix: 'vodafone',
    tags: [], // tags array
    version: '1.0.0',
  });

  return tagManager.filterTagsOnUrl(tagManager.tags); // []
};

sortTagsOnPriority(tags: ITags[]): ITags[]

The sortTagsOnPriority is used to order tags on a given priority.

Example

import TagManager from '@d-cat/tag-manager';

class MyTagManager extends TagManager {
  constructor(...args: any[]) {
    super(...args);
  }

  protected sortTagsOnPriority(...args: any[]): void {
    super.sortTagsOnPriority(...args);
    // your logic
  }
}

const myTagManager = () => {
  const tagManager = new MyTagManager({
    dataLayer: {
      events: ['_ddm.loaded', '_dd.loaded', '_ddm.core.initiated.ready'],
      listenKey: '_ddm.restored',
      version: '2.0.1',
      hooks: '4.0.0',
    },
    date: new Date(Date.now()),
    id: Math.random(),
    prefix: 'vodafone',
    tags: [], // tags array
    version: '1.0.0',
  });

  return tagManager.sortTagsOnPriority(tagManager.tags); // []
};

render(): void

The render method is used to loop over all the tags and assign a generator to each tag, that keep pending untill all triggers apply.

Example

import TagManager from '@d-cat/tag-manager';

class MyTagManager extends TagManager {
  constructor(...args: any[]) {
    super(...args);
  }

  protected render(...args: any[]): void {
    super.render(...args);
    // your logic
  }
}

const myTagManager = () => {
  const tagManager = new MyTagManager({
    dataLayer: {
      events: ['_ddm.loaded', '_dd.loaded', '_ddm.core.initiated.ready'],
      listenKey: '_ddm.restored',
      version: '2.0.1',
      hooks: '4.0.0',
    },
    date: new Date(Date.now()),
    id: Math.random(),
    prefix: 'vodafone',
    tags: [], // tags array
    version: '1.0.0',
  });

  return tagManager.render(); // undefined
};

ITags

Tags are objects with business rules and a handler that will be invoked when all business rules apply.

const tags = [
  {
    name: `example tag`,
    id: '1234-4567-79810',
    urls: [
      {
        url: '.*',
        reverse: false,
      },
    ],
    handler: () => console.log('all business rules apply'),
    triggers: [
      {
        type: 'instantly',
        id: '12345',
      },
    ],
    priority: 1,
    firingAmount: 1,
  },
];
Tag property type Description
name String The name of the tag.
id String Unique tag ID. Note that for TypeScript projects uuid/v1 type is used.
urls Array<{url: String, reverse: Boolean}> Array of objects with 2 keys: url (string) and reverse (boolean). The objects in this array determine on what pages the tag should be initialized. Url is a regular expression that matches certain urls and reverse determine if url should match or that it should not match the regex. On each page the regex is tested against the current document.location.href. Note that single page applications should always use ".*" as the Tag Manager will only initialize once.
handler Function The handler that should be invoked.
triggers ITrigger An Array of ITrigger.
priority Number Number that indicates the importancy of a tag. Where 1 is highest priority.
firingAmount Number Number that indicates the amount a tag should fire when all business rules meet. When a tag should always fire, use Infinity as number type.

ITrigger

Each tag can have unlimited amount of triggers, there are 5 trigger types:

TriggerType Description
instantly wildcard to execute immediatelly, without waiting for other triggers
datalayer Specific datalayer value of DDM that should or should not equal given values.
event Specific DDM event that should trigger.
domEvent Specific DOM Event, either on the window, document or on an element id.
persisted A specific cookie or localStorage value.

Example of triggers:

triggers: [
  {
    id: '1',
    type: 'dataLayer',
    name: 'user.id',
    reverse: false,
    value: '.*',
  },
  {
    id: '12345',
    type: 'datalayer',
    name: 'user.bladder',
    reverse: false,
    value: 'bladder1',
  },
  {
    id: '1234567',
    type: 'event',
    name: 'userr',
  },
];
Trigger property type Description
id Number Unique tag ID.
type String The type of the trigger: domEvent, event, datalayer, persisted or instantly.
name String The name linked to the trigger type. For each trigger type the name property has a different function. When using domEvent the name property will be the DOM event. When using event, the name property will be the name to listen to (i.e. dataLayer.listen(name) ). When using triggerType dataLayer the name property will be the name of the dataLayer value (i.e. dataLayer.get(name)). When using triggerType persisted the name property will be the cookie or localStorage name. When using triggerType instantly the name property is unneccessary.
reverse Boolean Indicates wether the business rules should match ( false ) or should not match ( true ).
value any The value that should match the business rule.
element String Either window, document or an element ID.