Using Google Tag Manager DataLayer with Uniform Signals
Last updated: February 4, 2026
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 exist in the dataLayer within the same page where they are added. Refreshing the page or navigating refreshes the dataLayer. When you push events into Uniform and trigger signals, you can define the persistency of the signals, meaning GTM events triggered on one page may be configured to affect Uniform personalization on another page.
Limitations
Uniform events are simple text values; you cannot add complex structures like arrays of purchased products with prices
The GA events → Uniform transformation needs to be configured in code and/or Google Tag Manager
Uniform personalization rules use only string-based conditions (equals, contains, etc.)
Why isn't this automatic? Google Analytics events may have any kind of structure, and Uniform events are simple text values. The transformation needs to be project-specific.
Implementation
The approach uses a Google Tag Manager custom event with a trigger for all events to produce a custom HTML tag. The tag code triggers a JavaScript event with the GA event payload, which is picked up by the Uniform context code in React to push the event into Uniform.
This approach was selected because:
Google Analytics or GTM doesn't provide a way to subscribe when
dataLayer.pushorgtagcalls occurGoogle discourages overriding or modifying the
dataLayerlogicUniform
context.updatecall can only be added into a client-side React code
Example GA event structure:
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.
Step 1: Create a GTM User-Defined Variable
In your Google Tag Manager container:
Navigate to Variables in the left sidebar
Click New under User-Defined Variables
Configure the variable:
Name:
dlv - event_labelVariable Type:
Data Layer VariableData Layer Variable Name:
event_label
Save the variable
Step 2: Add a Custom Event Trigger in GTM
Create a Custom Event trigger for all events:
Navigate to Triggers in GTM
Click New and select Custom Event as the trigger type
Configure the trigger:
Event name:
.*(RegEx Match)This trigger fires on: All Custom Events
Save the trigger
Now create a Custom HTML tag:
Navigate to Tags and click New
Select Custom HTML as the tag type
Add this code:
<script>
(function () {
window.dispatchEvent(
new CustomEvent("gtm-event-triggered", {
detail: { event: '{{dlv - event_label}}' }
})
)
})();
</script>
Set the Triggering to the custom event trigger you created
Save and Submit your GTM container changes
Step 3: Create a Next.js Client-Side Component
Create a new file at src/components/GaEventsTrigger.tsx:
'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 includes Uniform context. This is crucial, because Uniform context is initialized slightly later after the page load.
Step 4: Add Component to Your Layout
Update your src/app/layout.tsx to include the new component:
import { UniformContext } from '@uniformdev/canvas-next-rsc';
import GaEventsTrigger from '@/components/GaEventsTrigger';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<UniformContext>
<GaEventsTrigger />
{children}
</UniformContext>
</body>
</html>
);
}
The component renders nothing visually but listens for GTM events in the background.
Step 5: Create Uniform Signals
After implementation, you can create Uniform signals with conditions based on the events:
Navigate to Optimization > Signals in Uniform
Create a new signal based on the events forwarded from GTM
Set conditions using the event values (e.g., event equals "purchase-successful")
Publish your manifest
Verification
To confirm the integration is working:
1. Test Event Forwarding
Open your website in a browser
Open browser DevTools (F12) and go to the Console tab
Trigger a GTM event (e.g., click a button that fires a GTM event)
Look for console logs showing "GA event sent" with the event name
If you see the log, events are successfully forwarding to Uniform
2. Verify in GTM Preview Mode
In GTM, click Preview to enter preview mode
Visit your website
Trigger an event
In GTM Preview, verify:
The custom event trigger fires
The custom HTML tag executes
The dataLayer variable is populated
3. Check Uniform Context
Install the Uniform Context browser extension
Open your website and trigger a GTM event
Open the Uniform Context extension
Verify the event appears in the context data
4. Test Signal Activation
Create a test signal in Uniform based on your GTM event
Add personalization to a component using this signal
Trigger the GTM event on your site
Verify the personalization activates
Troubleshooting
Events Not Appearing in Uniform
Problem: GTM events fire but don't show up in Uniform signals
Solutions:
Verify the GTM event appears in GTM Preview and GA reports
Confirm your G-XXXX and GTM-YYYY codes are correct
Check browser console for errors in the
GaEventsTriggercomponentEnsure the Uniform Context is properly initialized before events fire
Custom HTML Tag Not Executing
Problem: The GTM custom HTML tag doesn't fire
Solutions:
Add
console.log('GTM tag fired')to the custom HTML to verify executionCheck the trigger configuration matches all custom events (
.*regex)Ensure the tag is published in GTM (not just saved)
Verify the GTM container is loaded on your page
Signals Not Triggering Personalization
Problem: Events reach Uniform but personalization doesn't activate
Solutions:
Ensure Uniform signals are published (not just saved as drafts)
Verify signal conditions match the exact event values
Check signal persistence settings if testing across page navigations
Use the Uniform Context browser extension to force signal overrides for testing
Console Errors About Missing Context
Problem: "Cannot read property 'update' of undefined" errors
Solutions:
Verify
GaEventsTriggeris placed inside<UniformContext>Check that the Uniform Context provider is properly configured
Ensure environment variables for Uniform are set correctly
Additional Resources
Last Updated: January 28, 2026