> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/web/sources/datalayer)[ ](https://www.npmjs.com/package/@walkeros/web-source-datalayer)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/web-source-datalayer)

# 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[​](#installation "Direct link to 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"
      }
    }
  }
}
```

[See bundled mode setup](https://www.walkeros.io/docs/getting-started/modes/bundled.md) | [CLI reference](https://www.walkeros.io/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->source<!-- --> uses the standard <!-- -->source<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [source<!-- --> configuration](https://www.walkeros.io/docs/sources.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to 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[​](#mapping "Direct link to Mapping")

Per-event rules under `config.mapping`. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

| 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.

Event

```
[
  "consent",
  "update",
  {
    "ad_storage": "granted",
    "analytics_storage": "granted"
  }
]
```

Out

```
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

```
{
  "event": "custom_event",
  "category": "engagement",
  "label": "video_play"
}
```

Out

```
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

```
[
  "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
      }
    ]
  }
})
```

### 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
      }
    ]
  }
})
```

### 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
      }
    ]
  }
})
```

## How it works[​](#how-it-works "Direct link to 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[​](#custom-filtering "Direct link to 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[​](#source-level-mapping "Direct link to 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[​](#migration-strategy "Direct link to Migration strategy")

Use the dataLayer source for gradual migration from GA4/GTM:

### Phase 1: Add walkerOS alongside existing dataLayer[​](#phase-1-add-walkeros-alongside-existing-datalayer "Direct link to 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[​](#phase-2-map-datalayer-events-to-walkeros-destinations "Direct link to 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()[​](#phase-3-gradually-replace-datalayerpush-with-elb "Direct link to 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[​](#next-steps "Direct link to Next steps")

* Review [event mapping](https://www.walkeros.io/docs/mapping.md) for transforming dataLayer events
* Check [GA4 destination](https://www.walkeros.io/docs/destinations/web/gtag/ga4.md) for Google Analytics integration
