Google Analytics 4 Hook
Send feature flag events to Google Analytics 4 for analytics and user behavior correlation.
Overview
The @ops-ai/toggly-ga4-hook package automatically sends feature flag telemetry to Google Analytics 4. This allows you to:
- Track feature flag usage as GA4 events
- Correlate features with user behavior in GA4 reports
- Set user properties for feature flag states
- Analyze A/B test results with GA4's built-in analysis tools
- Build audiences based on feature flag exposure
- Monitor real-time feature changes via GA4 events
Installation
$ npm i -s @ops-ai/toggly-ga4-hook
Prerequisites
- Toggly SDK - Any JavaScript-based Toggly SDK with hooks support (v1.0.0+)
- Google Analytics 4 - GA4 tracking code (
gtag.js) must be loaded on your page
How It Works
The hook implements multiple lifecycle events:
| Hook | GA4 Action |
|---|---|
afterEvaluation | Sends feature_flag_evaluated event |
afterIdentify | Sets user_id via gtag('config') |
afterRefresh | Sends feature_flag_changed event on state changes |
Example evaluation event:
gtag('event', 'feature_flag_evaluated', {
feature_key: 'checkout-v2',
feature_enabled: true,
event_category: 'toggly'
});
Usage
Vanilla JavaScript
import { Toggly } from '@ops-ai/feature-flags-toggly';
import { GA4Hook } from '@ops-ai/toggly-ga4-hook';
Toggly.init({
appKey: 'your-app-key',
environment: 'Production',
hooks: [
new GA4Hook({
measurementId: 'G-XXXXXXXXXX',
trackEvaluations: true,
trackChanges: true,
setUserProperties: true,
checkConsent: () => cookieConsent.analytics
})
]
});
React
import { createTogglyProvider } from '@ops-ai/react-feature-flags-toggly';
import { GA4Hook } from '@ops-ai/toggly-ga4-hook';
const TogglyProvider = await createTogglyProvider({
appKey: 'your-app-key',
environment: 'Production',
hooks: [new GA4Hook({ measurementId: 'G-XXXXXXXXXX' })]
});
Angular
import { provideToggly } from '@ops-ai/ngx-feature-flags-toggly';
import { GA4Hook } from '@ops-ai/toggly-ga4-hook';
bootstrapApplication(AppComponent, {
providers: [
provideToggly({
appKey: 'your-app-key',
environment: 'Production',
hooks: [new GA4Hook({ measurementId: 'G-XXXXXXXXXX' })]
})
]
});
Vue
import { createApp } from 'vue';
import { TogglyPlugin } from 'vue-feature-flags-toggly';
import { GA4Hook } from '@ops-ai/toggly-ga4-hook';
app.use(TogglyPlugin, {
appKey: 'your-app-key',
environment: 'Production',
hooks: [new GA4Hook({ measurementId: 'G-XXXXXXXXXX' })]
});
Svelte / Astro / Gatsby
import { Toggly } from '@ops-ai/feature-flags-toggly';
import { GA4Hook } from '@ops-ai/toggly-ga4-hook';
Toggly.init({
appKey: 'your-app-key',
environment: 'Production',
hooks: [new GA4Hook({ measurementId: 'G-XXXXXXXXXX' })]
});
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable or disable the hook |
measurementId | string | - | GA4 Measurement ID (optional, uses default gtag) |
evaluationEventName | string | "feature_flag_evaluated" | Custom event name for evaluations |
changeEventName | string | "feature_flag_changed" | Custom event name for changes |
trackEvaluations | boolean | true | Track feature flag evaluations |
trackAllResults | boolean | true | Track both true and false results |
setUserProperties | boolean | false | Set GA4 user properties for features |
userPropertyPrefix | string | "ff_" | Prefix for user property names |
trackChanges | boolean | true | Track real-time feature changes |
trackIdentity | boolean | true | Set user_id in GA4 |
customParameters | object | {} | Custom parameters for all events |
checkConsent | () => boolean | () => true | Consent callback called before each event |
debug | boolean | false | Enable debug logging |
Full Configuration Example
const ga4Hook = new GA4Hook({
enabled: process.env.NODE_ENV === 'production',
measurementId: 'G-XXXXXXXXXX',
evaluationEventName: 'ff_evaluated',
changeEventName: 'ff_changed',
trackEvaluations: true,
trackAllResults: true,
setUserProperties: true,
userPropertyPrefix: 'feature_',
trackChanges: true,
trackIdentity: true,
customParameters: {
app_version: '2.0.0',
environment: 'production'
},
checkConsent: () => {
return window.cookieConsent?.analytics ?? false;
},
debug: false
});
Privacy & Consent (GDPR/CCPA)
The checkConsent callback integrates with consent management platforms:
// OneTrust
new GA4Hook({
checkConsent: () => window.OneTrust?.IsAlertBoxClosed() ?? false
});
// Google Consent Mode v2
new GA4Hook({
checkConsent: () => {
return window.dataLayer?.some(item =>
item[0] === 'consent' &&
item[1] === 'update' &&
item[2]?.analytics_storage === 'granted'
) ?? false;
}
});
Only feature flag keys, evaluation results, optional custom parameters, and (when enabled) user identity are sent. No automatic PII collection.
Viewing in GA4
- Go to GA4 Admin → Events
- Look for
feature_flag_evaluatedandfeature_flag_changed - In Explore → Free Form, add
feature_keyandfeature_enabledas dimensions - Optionally create custom dimensions for
ff_*user properties under Custom definitions
Error Handling
The hook never breaks the Toggly SDK:
- gtag API calls are wrapped in try-catch
- Missing gtag is handled silently
- A console warning (not error) is shown if gtag is not detected at initialization
- gtag becoming available after initialization is handled automatically
Dynamic Management
// Add at runtime
Toggly.addHook(new GA4Hook({ measurementId: 'G-XXXXXXXXXX' }));
// Remove by name
Toggly.removeHook('ga4-hook');
Troubleshooting
Events not appearing
- Verify gtag is loaded:
console.log(typeof window.gtag === 'function') - Check your measurement ID format (
G-XXXXXXXXXX) - Check your
checkConsentcallback returnstrue - Enable debug mode:
new GA4Hook({ debug: true }) - Use GA4 DebugView for real-time event inspection
Console warning at startup
The warning "Google Analytics 4 gtag not detected" means gtag was not loaded when the hook was created. The hook will start sending events once gtag becomes available.
Performance
- Overhead: <0.1ms per evaluation
- Bundle size: ~2KB minified
- No batching (gtag handles its own queue)