Google Tag Manager (GTM)
Google Tag Manager (GTM) is a tool to manage and add third-party integrations to your website, configured within the unified gtag destination.
Installation
npm install @walkeros/web-destination-gtagimport { startFlow } from '@walkeros/collector';
import { destinationGtag } from '@walkeros/web-destination-gtag';
await startFlow({
destinations: {
gtag: {
code: destinationGtag,
config: {
settings: {
gtm: {
containerId: 'GTM-XXXXXXX',
dataLayer: 'dataLayer',
},
},
},
},
},
});Configuration
This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
como | boolean | object | Consent mode configuration: false (disabled), true (use defaults), or custom mapping | |
como_advanced | boolean | number | Advanced consent mode (non-EU): emit denied default at page load with wait_for_update (true=500ms, or a number of ms) | |
ga4 | ga4 | GA4-specific configuration settings | |
measurementId | string | GA4 Measurement ID from Google Analytics | |
debug | boolean | Enable debug mode for GA4 | |
pageview | boolean | Enable automatic pageview tracking | |
server_container_url | string | Server-side GTM container URL | |
snakeCase | boolean | Convert parameter names to snake_case | |
transport_url | string | Custom transport URL for GA4 | |
data | any | Custom data mapping configuration | |
ads | ads | Google Ads specific configuration settings | |
conversionId | string | Google Ads Conversion ID (required) | |
currency | string | Currency code (ISO 4217, e.g., USD, EUR) | |
data | any | Custom data mapping (WalkerOS.Mapping.Value | Values) | |
enhancedConversions | enhancedConversions | Enhanced conversions: maps event fields to Google user_data for improved measurement accuracy | |
email | any | Mapping value for user email | |
phone_number | any | Mapping value for user phone number | |
address | address | Address mapping for enhanced conversions | |
first_name | any | Mapping value for first name | |
last_name | any | Mapping value for last name | |
street | any | Mapping value for street address | |
city | any | Mapping value for city | |
region | any | Mapping value for region/state | |
postal_code | any | Mapping value for postal/zip code | |
country | any | Mapping value for country | |
gtm | gtm | Google Tag Manager specific configuration settings | |
containerId | string | GTM Container ID (required) | |
dataLayer | string | Custom dataLayer variable name (default: dataLayer) | |
domain | string | Custom GTM domain for script loading | |
data | any | Custom data mapping (WalkerOS.Mapping.Value | Values) |
Mapping
Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
| Property | Type | Description | More |
|---|---|---|---|
ga4 | ga4 | GA4-specific event mapping | |
ads | ads | Google Ads-specific event mapping | |
label | string | Conversion label for this specific event | |
gtm | gtm | GTM-specific event mapping |
Examples
Add to cart
A product add event is mapped to the GA4 add_to_cart event with item details and value.
{
"name": "product add",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"intent",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "9433bed2cc537782",
"trigger": "click",
"entity": "product",
"action": "add",
"timestamp": 1700000101,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "add_to_cart",
"include": [
"data"
],
"data": {
"map": {
"currency": {
"value": "EUR",
"key": "data.currency"
},
"value": "data.price",
"items": {
"loop": [
"this",
{
"map": {
"item_id": "data.id",
"item_variant": "data.color",
"quantity": {
"value": 1,
"key": "data.quantity"
}
}
}
]
}
}
}
}gtag("event", "add_to_cart", {
"currency": "EUR",
"value": 420,
"items": [
{
"item_id": "ers",
"item_variant": "black",
"quantity": 1
}
],
"data_id": "ers",
"data_name": "Everyday Ruck Snack",
"data_color": "black",
"data_size": "l",
"data_price": 420,
"send_to": "G-XXXXXX-1"
})Enhanced conversions
enhancedConversions maps event fields into a gtag set user_data call sent immediately before the conversion event.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555,
"customerEmail": "buyer@shop.com",
"customerPhone": "+1234567890"
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "14dfb640f7eed832",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000109,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "PURCHASE_EC2",
"settings": {
"ads": {
"label": "PURCHASE_EC2"
}
},
"data": {
"map": {
"value": "data.total"
}
}
}gtag("set", "user_data", {
"email": "buyer@shop.com",
"phone_number": "+1234567890"
});
gtag("event", "conversion", {
"send_to": "AW-123456789/PURCHASE_EC2",
"currency": "EUR",
"value": 555
})Google Ads init
The destination bootstraps gtag and configures a Google Ads account via its conversionId.
{
"settings": {
"ads": {
"conversionId": "AW-123456789",
"currency": "EUR"
}
}
}gtag("js", {});
gtag("config", "AW-123456789")Consent Mode v2
A walker consent command with marketing and functional granted updates gtag Consent Mode v2 parameters.
{
"marketing": true,
"functional": true
}gtag("consent", "default", {
"ad_storage": "denied",
"ad_user_data": "denied",
"ad_personalization": "denied",
"analytics_storage": "denied"
});
gtag("consent", "update", {
"ad_storage": "granted",
"ad_user_data": "granted",
"ad_personalization": "granted",
"analytics_storage": "granted"
})GA4 init
The destination bootstraps gtag and configures a GA4 property via its measurementId.
{
"settings": {
"ga4": {
"measurementId": "G-XXXXXX-1"
}
}
}gtag("js", {});
gtag("config", "G-XXXXXX-1", {})GA4 include all
Include flattens every event section into prefixed GA4 params, exposing data, context, user, source, and event fields.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev-1700000106",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000106,
"timing": 3.14,
"source": {
"count": 1,
"trace": "1700000106abcdef1700000106abcdef",
"type": "collector",
"schema": "4"
}
}{
"include": [
"data",
"context",
"globals",
"user",
"source",
"event"
]
}gtag("event", "page_view", {
"data_domain": "www.example.com",
"data_title": "walkerOS documentation",
"data_referrer": "https://www.walkeros.io/",
"data_search": "?foo=bar",
"data_hash": "#hash",
"data_id": "/docs/",
"context_dev": "test",
"globals_pagegroup": "docs",
"user_id": "us3r",
"user_device": "c00k13",
"user_session": "s3ss10n",
"source_type": "collector",
"source_schema": "4",
"source_count": 1,
"source_trace": "1700000106abcdef1700000106abcdef",
"source_release_default": "4.2.1",
"event_entity": "page",
"event_action": "view",
"event_trigger": "load",
"event_id": "ev-1700000106",
"event_name": "page view",
"event_timestamp": 1700000106,
"event_timing": 3.14,
"send_to": "G-XXXXXX-1"
})Ads conversion
An order complete event is sent as a Google Ads conversion with a configured label and transaction value.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "7f57f8c6fba9b725",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000103,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "PURCHASE_CONV",
"settings": {
"ads": {
"label": "PURCHASE_CONV"
}
},
"data": {
"map": {
"value": "data.total"
}
}
}gtag("event", "conversion", {
"send_to": "AW-123456789/PURCHASE_CONV",
"currency": "EUR",
"value": 555
})GTM dataLayer push
A page view event is pushed to window.dataLayer for GTM with the mapped event name and parameters.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "90b169aded2b6239",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000104,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "page_view",
"settings": {
"gtm": {}
},
"data": {
"map": {
"page_title": "data.title",
"page_location": "data.domain"
}
}
}dataLayer.push({
"event": "page_view",
"page_title": "walkerOS documentation",
"page_location": "www.example.com"
})GTM init
The destination initializes the dataLayer and pushes the gtm.js start event for a GTM container.
{
"settings": {
"gtm": {
"containerId": "GTM-XXXXXXX"
}
}
}dataLayer.push({
"gtm.start": 1700000000000,
"event": "gtm.js"
})Multi-tool push
A single order event fans out to GA4, Google Ads, and GTM from one mapping rule with per-tool settings.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "fa1aea4ccf03e63a",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000107,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "purchase",
"include": [
"data"
],
"settings": {
"ga4": {},
"ads": {
"label": "PURCHASE_CONV"
},
"gtm": {}
},
"data": {
"map": {
"value": "data.total",
"currency": {
"key": "data.currency",
"value": "EUR"
}
}
}
}gtag("event", "purchase", {
"value": 555,
"currency": "EUR",
"data_id": "0rd3r1d",
"data_currency": "EUR",
"data_shipping": 5.22,
"data_taxes": 73.76,
"data_total": 555,
"send_to": "G-XXXXXX-1"
});
gtag("event", "conversion", {
"send_to": "AW-123456789/PURCHASE_CONV",
"currency": "EUR",
"value": 555,
"data_id": "0rd3r1d",
"data_currency": "EUR",
"data_shipping": 5.22,
"data_taxes": 73.76,
"data_total": 555
});
dataLayer.push({
"event": "purchase",
"value": 555,
"currency": "EUR",
"data_id": "0rd3r1d",
"data_currency": "EUR",
"data_shipping": 5.22,
"data_taxes": 73.76,
"data_total": 555
})Page view
A page view event is forwarded as a GA4 page_view event with no additional mapping.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "8b162560dcd73d76",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000102,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}gtag("event", "page_view", {
"send_to": "G-XXXXXX-1"
})Purchase
An order complete event is mapped to the GA4 purchase event with transaction details and nested product items.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "51d0422ccb666f30",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000100,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "purchase",
"include": [
"data",
"context"
],
"data": {
"map": {
"transaction_id": "data.id",
"value": "data.total",
"tax": "data.taxes",
"shipping": "data.shipping",
"currency": {
"key": "data.currency",
"value": "EUR"
},
"items": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>U(e)&&\"product\"===e.entity"
},
"map": {
"item_id": "data.id",
"item_name": "data.name",
"quantity": {
"key": "data.quantity",
"value": 1
}
}
}
]
}
}
}
}gtag("event", "purchase", {
"transaction_id": "0rd3r1d",
"value": 555,
"tax": 73.76,
"shipping": 5.22,
"currency": "EUR",
"items": [
{
"item_id": "ers",
"item_name": "Everyday Ruck Snack",
"quantity": 1
},
{
"item_id": "cc",
"item_name": "Cool Cap",
"quantity": 1
}
],
"data_id": "0rd3r1d",
"data_currency": "EUR",
"data_shipping": 5.22,
"data_taxes": 73.76,
"data_total": 555,
"context_shopping": "complete",
"send_to": "G-XXXXXX-1"
})