DataLayer source
Integrates with existing Google Analytics 4 and GTM dataLayer implementations by intercepting dataLayer.push() calls.
The DataLayer source is a web source in the walkerOS flow:
It bridges existing GA4/GTM implementations to walkerOS destinations.
Installation
npm install @walkeros/web-source-datalayer- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { sourceDataLayer } from '@walkeros/web-source-datalayer';
const { collector, elb } = await startFlow({
sources: {
dataLayer: {
code: sourceDataLayer,
config: {
settings: {
name: 'dataLayer', // Name of global dataLayer array
prefix: 'dataLayer', // Event prefix for filtering
},
},
},
},
destinations: {
// Your destinations
},
});Add to your flow.json sources:
"sources": {
"dataLayer": {
"package": "@walkeros/web-source-datalayer",
"config": {
"settings": {
"name": "dataLayer",
"prefix": "dataLayer"
}
}
}
}Configuration
This source uses the standard source config wrapper (consent, data, env, id, ...). For the shared fields see source configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
name | string | DataLayer variable name (default: dataLayer) | |
prefix | string | Event prefix for filtering which events to process | |
filter | function | Custom filter function: (event: unknown) => boolean | Promise<boolean> |
Mapping
Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
| Property | Type | Description | More |
|---|---|---|---|
command | any | Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates). |
Examples
Consent update
A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.
[
"consent",
"update",
{
"ad_storage": "granted",
"analytics_storage": "granted"
}
]elb({
"name": "dataLayer consent update",
"data": {
"ad_storage": "granted",
"analytics_storage": "granted"
}
})Direct dataLayer event
A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.
{
"event": "custom_event",
"category": "engagement",
"label": "video_play"
}elb({
"name": "dataLayer custom_event",
"data": {
"category": "engagement",
"label": "video_play"
}
})gtag add_to_cart
A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.
[
"event",
"add_to_cart",
{
"currency": "EUR",
"value": 15.25,
"items": [
{
"item_id": "SKU_12345",
"item_name": "T-Shirt",
"item_variant": "red",
"quantity": 1,
"price": 15.25
}
]
}
]elb({
"name": "dataLayer add_to_cart",
"data": {
"currency": "EUR",
"value": 15.25,
"items": [
{
"item_id": "SKU_12345",
"item_name": "T-Shirt",
"item_variant": "red",
"quantity": 1,
"price": 15.25
}
]
}
})gtag purchase
A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.
[
"event",
"purchase",
{
"transaction_id": "T-12345",
"value": 25.42,
"currency": "EUR",
"items": [
{
"item_id": "SKU-1",
"item_name": "T-Shirt",
"quantity": 1
}
]
}
]elb({
"name": "dataLayer purchase",
"data": {
"transaction_id": "T-12345",
"value": 25.42,
"currency": "EUR",
"items": [
{
"item_id": "SKU-1",
"item_name": "T-Shirt",
"quantity": 1
}
]
}
})gtag view_item
A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.
[
"event",
"view_item",
{
"currency": "EUR",
"value": 29.99,
"items": [
{
"item_id": "SKU_67890",
"item_name": "Sneakers",
"item_category": "Footwear",
"price": 29.99
}
]
}
]elb({
"name": "dataLayer view_item",
"data": {
"currency": "EUR",
"value": 29.99,
"items": [
{
"item_id": "SKU_67890",
"item_name": "Sneakers",
"item_category": "Footwear",
"price": 29.99
}
]
}
})How it works
The dataLayer source intercepts dataLayer.push() calls and transforms them into walkerOS events:
- Intercepts existing
dataLayer.push()calls - Filters events based on prefix or custom filter function
- Transforms dataLayer format to walkerOS event format
- Forwards to collector for processing
// Existing dataLayer code (unchanged)
window.dataLayer = window.dataLayer || [];
dataLayer.push({ event: 'purchase', value: 99.99 });
// Automatically captured and transformed by sourceDataLayer
// → Sent to walkerOS collector as standard eventCustom filtering
Filter which dataLayer events get processed:
const { elb } = await startFlow({
sources: {
dataLayer: {
code: sourceDataLayer,
config: {
settings: {
filter: (event) => {
// Only process purchase and add_to_cart events
if (typeof event === 'object' && event !== null) {
const e = event as { event?: string };
return e.event === 'purchase' || e.event === 'add_to_cart';
}
return false;
},
},
},
},
},
});Source-level mapping
The source emits walkerOS events whose name is "<prefix> <gtag-action>". The collector splits name on the first space into entity and action, so the prefix becomes the entity and the gtag action becomes the action. Source-level mapping rules key on that pair:
"sources": {
"dataLayer": {
"package": "@walkeros/web-source-datalayer",
"config": {
"settings": { "prefix": "dataLayer" },
"mapping": {
"dataLayer": {
"add_to_cart": {
"name": "product add",
"data": {
"map": {
"id": "items.0.item_id",
"name": "items.0.item_name",
"price": "value",
"currency": "currency",
"quantity": "items.0.quantity"
}
}
},
"purchase": {
"name": "order complete",
"data": {
"map": {
"id": "transaction_id",
"total": "value",
"currency": "currency"
}
}
}
}
}
}
}
}For the gtag commands consent, config, and set, the action equals the command name (any trailing token such as update or a measurement ID is dropped by the entity/action split). Branch on the dropped value via rule-level condition or event.data if you need to distinguish, for example, consent default from consent update.
If you set a custom prefix (for example "gtag"), use that string as the entity key: mapping.gtag.add_to_cart.
Migration strategy
Use the dataLayer source for gradual migration from GA4/GTM:
Phase 1: Add walkerOS alongside existing dataLayer
// Existing code continues to work
dataLayer.push({ event: 'purchase', value: 99.99 });
// Now also captured by walkerOSPhase 2: Map dataLayer events to walkerOS destinations
destinations: {
ga4: {
code: destinationGtag,
config: {
mapping: {
// Map dataLayer purchase to GA4 format
}
}
}
}Phase 3: Gradually replace dataLayer.push with elb()
// Old
dataLayer.push({ event: 'purchase', value: 99.99 });
// New
elb('order complete', { total: 99.99 });Next steps
- Review event mapping for transforming dataLayer events
- Check GA4 destination for Google Analytics integration