Skip to main content
Ask your AI

Microsoft Clarity

Web Source code Package

Microsoft Clarity provides free session replays, heatmaps and behavioural insights for web products. This destination forwards walkerOS events to Clarity via the official @microsoft/clarity SDK, translating events into Clarity.event(...) calls, resolving custom tags, identities, session priority, and consent state.

Where this fits

Clarity is a web destination in the walkerOS flow:

Installation​

npm install @walkeros/web-destination-clarity
import { startFlow } from '@walkeros/collector';
import { destinationClarity } from '@walkeros/web-destination-clarity';

await startFlow({
  destinations: {
    clarity: {
      code: destinationClarity,
      config: {
        settings: {
          apiKey: '3t0wlogvdz',
          consent: {
            analytics: 'analytics_Storage',
            marketing: 'ad_Storage',
          },
        },
      },
    },
  },
});

Configuration​

This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.

Settings​

PropertyTypeDescriptionMore
apiKey*stringYour Microsoft Clarity project ID (e.g. "3t0wlogvdz"). Find it in your Clarity dashboard under Settings → Setup.
consentRecord<string, string>Translation table from walkerOS consent keys to Clarity ConsentV2 categories. Example: { "analytics": "analytics_Storage", "marketing": "ad_Storage" }. Required to get meaningful consent behavior, since Clarity expects its own category names.
identifyanywalkerOS mapping value resolving to positional arguments for Clarity.identify(). Keys: customId (required), customSessionId?, customPageId?, friendlyName?.
* Required fields

Mapping​

Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.

PropertyTypeDescriptionMore
identifyanyPer-event identity mapping. Resolves to { customId, customSessionId?, customPageId?, friendlyName? } → Clarity.identify(...).
setanyExplicit custom tag mapping. Resolved object keys become Clarity.setTag(key, value) calls. Array values pass through as string[] unchanged.
upgradeanySession priority reason. Resolves to a string → Clarity.upgrade(reason). Used to flag important sessions for retention beyond sampling.

Examples

Array tag values

Array values such as product tags are passed through to Clarity.setTag preserving the array shape.

Event
{
  "name": "product view",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420,
    "tags": [
      "sale",
      "featured"
    ]
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "fc2243e6d61de3af",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000105,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "settings": {
    "set": {
      "map": {
        "product_tags": "data.tags"
      }
    }
  }
}
Out
clarity.setTag("product_tags", [
  "sale",
  "featured"
]);

clarity.event("product view")

Combined features

A purchase identifies the user, sets an order tag, upgrades the session, and fires the Clarity event in order.

Event
{
  "name": "order complete",
  "data": {
    "id": "0rd3r1d",
    "currency": "EUR",
    "shipping": 5.22,
    "taxes": 73.76,
    "total": 555
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "ers",
        "name": "Everyday Ruck Snack",
        "color": "black",
        "size": "l",
        "price": 420
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "product",
      "data": {
        "id": "cc",
        "name": "Cool Cap",
        "size": "one size",
        "price": 42
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "gift",
      "data": {
        "name": "Surprise"
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "639f0fd878ea2560",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000108,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "name": "Purchase",
  "settings": {
    "identify": {
      "map": {
        "customId": "user.id"
      }
    },
    "set": {
      "map": {
        "order_id": "data.id"
      }
    },
    "upgrade": {
      "value": "purchase"
    }
  }
}
Out
clarity.identify("us3r");

clarity.setTag("order_id", "0rd3r1d");

clarity.upgrade("purchase");

clarity.event("Purchase")

Consent granted

With settings.consent mapping analytics to analytics_Storage and marketing to ad_Storage, a walker consent command granting both calls Clarity.consentV2 with both granted.

Event
{
  "analytics": true,
  "marketing": true
}
Out
clarity.consentV2({
  "analytics_Storage": "granted",
  "ad_Storage": "granted"
})

Consent revoked

With settings.consent mapping analytics to analytics_Storage and marketing to ad_Storage, a grant of both and then a walker consent command denying both call Clarity.consentV2 twice, the second time with denied flags.

Event
{
  "analytics": false,
  "marketing": false
}
Out
clarity.consentV2({
  "analytics_Storage": "granted",
  "ad_Storage": "granted"
});

clarity.consentV2({
  "analytics_Storage": "denied",
  "ad_Storage": "denied"
})

Default event

A walker event becomes a Clarity.event call with the event name as the Clarity custom event.

Event
{
  "name": "product view",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "53a59f58d4bfa495",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000100,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Out
clarity.event("product view")

Destination identify

With settings.identify mapping customId to 'user.id', the destination calls Clarity.identify on every push, as Clarity recommends, before the event.

Event
{
  "name": "page view",
  "data": {
    "domain": "www.example.com",
    "title": "walkerOS documentation",
    "referrer": "https://www.walkeros.io/",
    "search": "?foo=bar",
    "hash": "#hash",
    "id": "/docs/"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "pagegroup": "docs"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "c1f2ca57332c61f2",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000103,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Out
clarity.identify("us3r");

clarity.event("page view")

Include data as tags

A mapping include flattens the event data section into Clarity.setTag calls before the event fires.

Event
{
  "name": "order complete",
  "data": {
    "id": "0rd3r1d",
    "currency": "EUR",
    "shipping": 5.22,
    "taxes": 73.76,
    "total": 555
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "ers",
        "name": "Everyday Ruck Snack",
        "color": "black",
        "size": "l",
        "price": 420
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "product",
      "data": {
        "id": "cc",
        "name": "Cool Cap",
        "size": "one size",
        "price": 42
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "gift",
      "data": {
        "name": "Surprise"
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "197797eeb699f37d",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000107,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "include": [
    "data"
  ]
}
Out
clarity.setTag("data_id", "0rd3r1d");

clarity.setTag("data_currency", "EUR");

clarity.setTag("data_shipping", "5.22");

clarity.setTag("data_taxes", "73.76");

clarity.setTag("data_total", "555");

clarity.event("order complete")

Upgrade session

A completed order upgrades the Clarity session priority so it is retained beyond the sampling cap.

Event
{
  "name": "order complete",
  "data": {
    "id": "0rd3r1d",
    "currency": "EUR",
    "shipping": 5.22,
    "taxes": 73.76,
    "total": 555
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "ers",
        "name": "Everyday Ruck Snack",
        "color": "black",
        "size": "l",
        "price": 420
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "product",
      "data": {
        "id": "cc",
        "name": "Cool Cap",
        "size": "one size",
        "price": 42
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    },
    {
      "entity": "gift",
      "data": {
        "name": "Surprise"
      },
      "context": {
        "shopping": [
          "complete",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "e71f5d3dc21b1551",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000106,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "name": "Purchase",
  "settings": {
    "upgrade": {
      "value": "purchase"
    }
  }
}
Out
clarity.upgrade("purchase");

clarity.event("Purchase")

Tags without event

A page view sets Clarity tags while silent suppresses the event, letting Clarity handle page tracking itself.

Event
{
  "name": "page view",
  "data": {
    "domain": "www.example.com",
    "title": "walkerOS documentation",
    "referrer": "https://www.walkeros.io/",
    "search": "?foo=bar",
    "hash": "#hash",
    "id": "/docs/"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "pagegroup": "docs"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "46e410a3220a44ba",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000109,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "silent": true,
  "settings": {
    "set": {
      "map": {
        "page_id": "data.id"
      }
    }
  }
}
Out
clarity.setTag("page_id", "/docs/")

Custom tags

A product view sets Clarity session tags such as product color and id before firing the event.

Event
{
  "name": "product view",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "e50da0f65260f683",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000104,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "settings": {
    "set": {
      "map": {
        "product_color": "data.color",
        "product_id": "data.id"
      }
    }
  }
}
Out
clarity.setTag("product_color", "black");

clarity.setTag("product_id", "ers");

clarity.event("product view")

User login identify

A user login fires Clarity.identify with custom id, session id, page id, and friendly name then tracks the event.

Event
{
  "name": "user login",
  "data": {
    "id": "u-123",
    "name": "Jane Doe"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "pagegroup": "shop",
    "pagetype": "home"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "2ab796d1961993e1",
  "trigger": "test",
  "entity": "user",
  "action": "login",
  "timestamp": 1700000102,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
Mapping
{
  "settings": {
    "identify": {
      "map": {
        "customId": "data.id",
        "customSessionId": "user.session",
        "customPageId": "globals.pagetype",
        "friendlyName": "data.name"
      }
    }
  }
}
Out
clarity.identify("u-123", "s3ss10n", "home", "Jane Doe");

clarity.event("user login")

Clarity expects its own category names (analytics_Storage, ad_Storage). walkerOS uses arbitrary consent keys, so the translation is explicit: configure settings.consent once and the destination maps every walker consent event into Clarity.consentV2({ ... }). A granted key becomes granted, any other value denied, and a mapped key missing from the consent event is left out. Without settings.consent, the destination takes no action on consent changes.

settings.consent only tells Clarity the consent state. The destination loads the Clarity script when the flow starts. To load Clarity only after consent is granted, also set config.consent, see consent management.

💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)