Skip to main content
Ask your AI
Source code Package

DataLayer source

Integrates with existing Google Analytics 4 and GTM dataLayer implementations by intercepting dataLayer.push() calls.

Where this fits

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
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
  },
});

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​

PropertyTypeDescriptionMore
namestringDataLayer variable name (default: dataLayer)
prefixstringEvent prefix for filtering which events to process
filterfunctionCustom filter function: (event: unknown) => boolean | Promise<boolean>

Mapping​

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.

Examples

Consent update

A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.

Event
[
  "consent",
  "update",
  {
    "ad_storage": "granted",
    "analytics_storage": "granted"
  }
]
Out
elb({
  "name": "dataLayer consent update",
  "data": {
    "ad_storage": "granted",
    "analytics_storage": "granted"
  },
  "source": {
    "type": "dataLayer",
    "platform": "web"
  }
})

Direct dataLayer event

A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.

Event
{
  "event": "custom_event",
  "category": "engagement",
  "label": "video_play"
}
Out
elb({
  "name": "dataLayer custom_event",
  "data": {
    "category": "engagement",
    "label": "video_play"
  },
  "source": {
    "type": "dataLayer",
    "platform": "web"
  }
})

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
[
  "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
      }
    ]
  }
]
Out
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
      }
    ]
  },
  "source": {
    "type": "dataLayer",
    "platform": "web"
  }
})

gtag purchase

A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.

Event
[
  "event",
  "purchase",
  {
    "transaction_id": "T-12345",
    "value": 25.42,
    "currency": "EUR",
    "items": [
      {
        "item_id": "SKU-1",
        "item_name": "T-Shirt",
        "quantity": 1
      }
    ]
  }
]
Out
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
      }
    ]
  },
  "source": {
    "type": "dataLayer",
    "platform": "web"
  }
})

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
[
  "event",
  "view_item",
  {
    "currency": "EUR",
    "value": 29.99,
    "items": [
      {
        "item_id": "SKU_67890",
        "item_name": "Sneakers",
        "item_category": "Footwear",
        "price": 29.99
      }
    ]
  }
]
Out
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
      }
    ]
  },
  "source": {
    "type": "dataLayer",
    "platform": "web"
  }
})

How it works​

The dataLayer source intercepts dataLayer.push() calls and transforms them into walkerOS events:

  1. Intercepts existing dataLayer.push() calls
  2. Filters events based on prefix or custom filter function
  3. Transforms dataLayer format to walkerOS event format
  4. 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 event

Custom 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 walkerOS

Phase 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​

💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)