Featurevisor

Integrations

Google Analytics

Record which variation each user sees as an event in Google Analytics, sent through Google Tag Manager, and compare how the variations perform.

An engineer adds the tracking module once. The Tag Manager and Analytics steps after it need no code, so an analyst or marketer can own them.

Push an activation event

An activation is the first time a user is shown a variation. A module can see every variation read, and push one event to the dataLayer per user and feature. Create one per browser session and user, not per render. It counts reads with the allocated, rule or sticky reasons, and skips reads made only to check conditions, errors, disabled values and forced QA assignments:

your-app/activation-tracking.js
export function createActivationModule({
subjectId,
identityAttribute = 'userId',
send,
}) {
if (typeof subjectId !== 'string' || !subjectId) {
throw new Error('Tracking needs a subject identity')
}
const seen = new Set()
let closed = false
return {
name: 'activationTracking',
afterEvaluation(evaluation, options) {
const { reason, type, featureKey } = evaluation
const variationValue =
evaluation.variationValue ?? evaluation.variation?.value
if (
closed ||
options.dependencyPurpose === 'condition' ||
type !== 'variation' ||
!['allocated', 'rule', 'sticky'].includes(reason) ||
evaluation.enabled === false ||
typeof variationValue !== 'string' ||
options.context[identityAttribute] !== subjectId
) {
return evaluation
}
const key = JSON.stringify([featureKey, variationValue])
if (seen.has(key) || seen.size >= 1000) return evaluation
seen.add(key)
try {
// send must synchronously enqueue the event, not return a network promise.
send({
event: 'featurevisorActivation',
featureKey,
variationValue,
reason,
})
} catch (error) {
seen.delete(key)
console.warn('Could not queue experiment activation', error)
}
return evaluation
},
close() {
closed = true
seen.clear()
},
}
}

The module skips eligibility checks with dependencyPurpose: 'condition'. A variation read through a composition is consumed by the application, so 'composition' reads can send an activation too. Do not skip every read with dependencyOf. Evaluate the composition when the user sees the view, not during speculative loading.

Once the user has consented, add the module with your application's user identity:

your-app/index.js
import { createFeaturevisor } from '@featurevisor/sdk'
import { createActivationModule } from './activation-tracking'
import datafile from './datafile.json'
window.dataLayer = window.dataLayer || []
const tracking = createActivationModule({
subjectId: userProfile.id,
send: (payload) => window.dataLayer.push(payload),
})
const f = createFeaturevisor({
datafile,
modules: [tracking],
})
const context = {
userId: userProfile.id,
}
// Evaluate only when the user sees the variation
const variation = f.getVariation('pricing', context)
  • Match the experiment's bucketing identity: use identityAttribute: 'deviceId' and a stable device ID for anonymous experiments. Identity stays local, not in the event payload.
  • On logout, identity change, consent withdrawal or session expiry, call await f.removeModule('activationTracking'). For the next permitted session or user, add a fresh module with f.addModule(...). SDK close also clears the cache. Never share it across server users.
  • Memory is capped at 1000 pairs, after which new pairs are skipped. Reloads and tabs have separate caches. A failed synchronous enqueue can retry on a later evaluation.
  • Call getVariation only when you show the variation, not while prefetching, or the user is counted before seeing anything.

Send it to Google Analytics

In Google Tag Manager, create a tag from the GA4 event template:

  1. Set the event name to featurevisor_activation.
  2. Add the parameters and user properties you want to send with it.
  3. Fire it on a Custom Event trigger matching featurevisorActivation, the event the module pushes.

GA4 event names use underscores, while dataLayer events are usually camel case, which is why the two names differ.

Add custom dimensions

To split users by experiment and variation, send the feature key and the variation as custom dimensions. Register a custom dimension called featureKey in Google Analytics, as an event parameter or a user property depending on how you analyse, then add the parameter to your GA4 tags. Do the same for variationValue.

Analyse the results

Before the experiment starts, decide which outcome it is meant to change, such as purchases, and how long it will run. Choosing them afterwards makes any difference easy to find and hard to trust.

Then compare the users who saw control with those who saw treatment on that outcome. Explorations in Google Analytics can break results down by the custom dimensions above. Export the raw events to BigQuery for deeper analysis, such as a significance test.

Previous
Cloudflare Pages