Knowledge Base/Using Google Tag Manager DataLayer with Uniform Signals

Using Google Tag Manager DataLayer with Uniform Signals

IntegrationDeveloperAnalyticsContextPersonalization

Overview

Uniform Signals can leverage Google Tag Manager (GTM) dataLayer events to create powerful, event-driven personalization experiences. While Uniform uses its own event tracking system, you can bridge GTM events to Uniform with a straightforward one-time integration.

How It Works

Uniform Signals are based on Uniform's tracking events, not directly on GTM dataLayer events. However, you can forward all GA events to Uniform's tracker, enabling you to create signals based on any current or future GTM event.

GTM events exists in the dataLayer within the same page where they are added. Refreshing the page or going to another one refreshes the dataLayer. When you push events into Uniform and have signals triggered, you can define the persistency of the signals, i.e. GTM events trigegred on one page may be configured to affect Uniform personalization on another page now

Limitations:

  • Uniform events are simple text values, i.e. you cannot add something more complicated, such as an array of purchased products with prices
  • The GA events → Uniform transformation events needs to be configured in the code and/or Google Tag Manager
  • Uniform personalization rules have only string-based conditions, such as equals, contains, etc.

Why isn't this automatic? Google Analytics events may have any kind of structure, and Uniform events are simple simple text values. The transformation needs to be project-specific

Implementation

The idea is to use Google Tag Manager custom event with a trigger for all events to produce a custom HTML tag. The tag code will trigger a JS event with GA event payload, which is to be picked up by the Uniform context code in React to push the event into Uniform. This approach was selected because:

  • Google Analytics or Google Tag Manager doesn't provide a way in the code to subscribe when dataLayer.push or gtag call occurs
  • Google discourages overriding or modifying the dataLayer logic
  • Uniform context.update call can only be added into a client-side React code

Steps:

In this example we used GA event like this: { event_label: 'purchase-successful', value: 100, } You can read any event, as long as appropriate tranformation is added. We only read the event_label to be used as event name in Uniform.
  1. In GTM, create a new user-defined variable. You will need to add all possible variables which you may want to use in Uniform in signal conditions:
    Name: dlv - event_label
    Variable Type: Data Layer Variable
    Data Layer Variable Name: event_label
  2. In GTM -> Triggers, add a Custom Event trigger for all events (.* RegEx Match) with tag configuration Custom HTML. You will need to add all the possible event values you'd like to use in Uniform. Make sure to Submit the change in the GTM dashboard
<script> (function () { window.dispatchEvent( new CustomEvent("gtm-event-triggered", { detail: { event: '{{dlv - event_label}}' } }) ) })(); </script>
  1. Create a new client-side component with an event subscriber. The handler is going to trigger the Uniform event push. The component should render no markup, we only need it for JS logic. Here is an NextJS app router example:
'use client'; import { useEffect } from 'react'; import { useUniformContext } from '@uniformdev/canvas-next-rsc/component'; type GtmEventDetail = { event?: string; }; export default function GaEventsTrigger() { const { context } = useUniformContext(); useEffect(() => { const handler = (e: CustomEvent<GtmEventDetail>) => { const detail = e.detail; if (detail?.event) { context ?.update({ events: [{ event: detail?.event }], }) .then(() => { console.log('GA event sent', detail?.event); }) .catch(err => { console.error('Failed to send GA event', err); }); } }; window.addEventListener('gtm-event-triggered', handler as EventListener); return () => { window.removeEventListener('gtm-event-triggered', handler as EventListener); }; }, [context]); return null; }

The useEffect dependency array has Uniform context. This is crucial, because Uniform context is initialized slightly later after the page load. Triggering further context.update won't trigger this useEffect
  1. Add the new GaEventsTrigger component to the layout.tsx inside the <UniformContext>

Now you can create Uniform signals with conditions based on the events.

Troubleshooting:

If you see Uniform signals not being triggered when a new GTM event is pushed, please check the items below:

  • Make sure the GTM event is visible in the report, i.e. the the push worked, the G-XXXX and GTM-YYYY codes are correct in the code, etc.
  • Add console.log into the GTM Custom HTML to see if this is executed when needed. The logs will be available in the browser console when visiting the site
  • Make sure the Uniform signals are published and GTM custom events are submitted to production
  • Consider installing Uniform Context browser extension to:
    • Try forcing a new signal via an override
    • Enable "Write Uniform Context diagnostics logs to browser console" to see when Uniform context update is received

Additional Resources

Published: December 16, 2025