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

# Piwik PRO

[Web](#)[ Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/web/destinations/piwikpro)[ Package](https://www.npmjs.com/package/@walkeros/web-destination-piwikpro)

[Piwik PRO](https://piwik.pro/) is a European, privacy-focused web analytics and marketing platform. The destination sends events to Piwik PRO via the `_paq` command queue: page views, custom events, goals, site search, links, content tracking, ecommerce and custom dimensions. With `loadScript: true` it also loads the Piwik PRO JavaScript tracking client from your account. For server-side delivery with the same mapping, see the [Piwik PRO server destination](/preview/pr-749/docs/destinations/server/piwikpro.md).

Where this fits

Piwik PRO is a **web destination** in the walkerOS flow:

## Installation[​](#installation "Direct link to Installation")

```bash
npm install @walkeros/web-destination-piwikpro
```

* Integrated
* Bundled

```typescript
import { startFlow } from '@walkeros/collector';
import { destinationPiwikPro } from '@walkeros/web-destination-piwikpro';

await startFlow({
  destinations: {
    piwikpro: {
      code: destinationPiwikPro,
      config: {
        loadScript: true,
        settings: {
          appId: 'XXX-XXX-XXX-XXX-XXX',
          url: 'https://your_account_name.piwik.pro/',
        },
      },
    },
  },
});
```

Add to your `flow.json` destinations:

```json
"destinations": {
  "piwikpro": {
    "package": "@walkeros/web-destination-piwikpro",
    "config": {
      "loadScript": true,
      "settings": {
        "appId": "XXX-XXX-XXX-XXX-XXX",
        "url": "https://your_account_name.piwik.pro/"
      }
    }
  }
}
```

[See bundled mode setup](/preview/pr-749/docs/getting-started/modes/bundled.md) | [CLI reference](/preview/pr-749/docs/apps/cli.md)

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

This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see [destination configuration](/docs/destinations#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property           | Type                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | More |
| ------------------ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| `appId`            | `string`                        | ID of the Piwik PRO site (like XXX-XXX-XXX-XXX-XXX). Required when loadScript is true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |      |
| `url`              | `string`                        | URL of your Piwik PRO account, normalized to one trailing slash (like https\://your\_account\_name.piwik.pro/). Required when loadScript is true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |      |
| `linkTracking`     | `boolean`                       | Automatic outlink and download tracking, enabled right after the first hit this destination sends. Default: true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |      |
| `identified`       | `boolean \| object`             | Identified or anonymous tracking. true (default) identifies every hit, false switches the tracker to anonymous mode without cookies (disableCookies, deleteCookies, setUserIsAnonymous) at init. A consent object like { marketing: true } identifies only while that consent is granted and calls enableCookies and deanonymizeUser once it is. Do not repeat these states in config.consent: a destination needs only one of its config.consent states granted, so next to another state the repeated one lets events through on its own, and as the only state it queues every event until granted, so no anonymous hit is sent. |      |
| `customDimensions` | `Record<string, Mapping.Value>` | Custom dimensions applied to every hit, keyed by bare dimension id (like { "1": "data.size" }). Rule-level customDimensions win per key.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |      |

## 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](/docs/mapping).

| Property           | Type                            | Description                                                                                                                                  | More |
| ------------------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| `goalId`           | `string \| number`              | Piwik PRO goal id (UUID or legacy integer). Adds a second hit, trackGoal.                                                                    |      |
| `goalValue`        | `Mapping.Value`                 |                                                                                                                                              |      |
| `customDimensions` | `Record<string, Mapping.Value>` | Custom dimensions for this rule, keyed by bare dimension id (like { "1": "data.size" }). Wins per key over the destination customDimensions. |      |

## Examples

### Cart update

A cart view fires Piwik PRO ecommerceCartUpdate with nested products and the cart total.

Event

```json
{
  "name": "cart view",
  "data": {
    "currency": "EUR",
    "value": 840
  },
  "context": {
    "shopping": [
      "cart",
      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,
        "quantity": 2
      },
      "context": {
        "shopping": [
          "cart",
          0
        ]
      },
      "nested": []
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "511cb65fb7d9bc25",
  "trigger": "load",
  "entity": "cart",
  "action": "view",
  "timestamp": 1700000303,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ecommerceCartUpdate",
  "data": {
    "set": [
      {
        "loop": [
          "nested",
          {
            "condition": {
              "$code": "e=>\"object\"==typeof e&&null!==e&&\"entity\"in e&&\"product\"===e.entity"
            },
            "map": {
              "sku": "data.id",
              "name": "data.name",
              "price": "data.price",
              "quantity": {
                "value": 1
              },
              "variant": {
                "key": "data.color"
              },
              "customDimensions": {
                "map": {
                  "1": "data.size"
                }
              }
            }
          }
        ]
      },
      "data.value"
    ]
  }
}
```

Out

```javascript
ecommerceCartUpdate([
  {
    "sku": "ers",
    "name": "Everyday Ruck Snack",
    "price": 420,
    "quantity": 1,
    "variant": "black",
    "customDimensions": {
      "1": "l"
    }
  }
], 840)
```

### Event with custom dimensions

A product add fires Piwik PRO trackEvent with rule-level custom dimensions as its dimensions argument, values percent-encoded.

Event

```json
{
  "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": "191e67670875a6da",
  "trigger": "click",
  "entity": "product",
  "action": "add",
  "timestamp": 1700000313,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "trackEvent",
  "data": {
    "set": [
      "entity",
      "action",
      "data.name",
      "data.price"
    ]
  },
  "settings": {
    "customDimensions": {
      "1": "data.size",
      "2": "data.name"
    }
  }
}
```

Out

```javascript
trackEvent("product", "add", "Everyday Ruck Snack", 420, {
  "dimension1": "l",
  "dimension2": "Everyday%20Ruck%20Snack"
})
```

### Page view with custom dimensions

trackPageView has no dimensions argument, so rule-level custom dimensions are set right before the hit and deleted right after it.

Event

```json
{
  "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": "6f94b0c20c51d3f3",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000314,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "settings": {
    "customDimensions": {
      "1": "globals.pagegroup"
    }
  }
}
```

Out

```javascript
setCustomDimensionValue(1, "docs");

trackPageView("walkerOS documentation");

deleteCustomDimension(1)
```

### Custom event with goal

A promotion visible event fires Piwik PRO trackEvent and then trackGoal to record a goal conversion.

Event

```json
{
  "name": "promotion visible",
  "data": {
    "name": "Setting up tracking easily",
    "position": "hero"
  },
  "context": {
    "ab_test": [
      "engagement",
      0
    ]
  },
  "globals": {
    "pagegroup": "homepage"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "3cef5bb6f3d5408f",
  "trigger": "visible",
  "entity": "promotion",
  "action": "visible",
  "timestamp": 1700000304,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "trackEvent",
  "settings": {
    "goalId": "goal_1"
  },
  "data": {
    "set": [
      "data.name",
      "data.position"
    ]
  }
}
```

Out

```javascript
trackEvent("Setting up tracking easily", "hero");

trackGoal("goal_1")
```

### Add to cart

A product add fires Piwik PRO ecommerceAddToCart with the added item.

Event

```json
{
  "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": "76dbd2b9ee678832",
  "trigger": "click",
  "entity": "product",
  "action": "add",
  "timestamp": 1700000301,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ecommerceAddToCart",
  "data": {
    "set": [
      {
        "set": [
          {
            "map": {
              "sku": "data.id",
              "name": "data.name",
              "price": "data.price",
              "quantity": {
                "value": 1
              },
              "variant": {
                "key": "data.color"
              },
              "customDimensions": {
                "map": {
                  "1": "data.size"
                }
              }
            }
          }
        ]
      }
    ]
  }
}
```

Out

```javascript
ecommerceAddToCart([
  {
    "sku": "ers",
    "name": "Everyday Ruck Snack",
    "price": 420,
    "quantity": 1,
    "variant": "black",
    "customDimensions": {
      "1": "l"
    }
  }
])
```

### Ecommerce order

A completed order calls Piwik PRO ecommerceOrder with line items and order totals.

Event

```json
{
  "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": "6e4426a2eba7ce77",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000300,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ecommerceOrder",
  "data": {
    "set": [
      {
        "loop": [
          "nested",
          {
            "condition": {
              "$code": "e=>\"object\"==typeof e&&null!==e&&\"entity\"in e&&\"product\"===e.entity"
            },
            "map": {
              "sku": "data.id",
              "name": "data.name",
              "price": "data.price",
              "quantity": {
                "value": 1
              },
              "variant": {
                "key": "data.color"
              },
              "customDimensions": {
                "map": {
                  "1": "data.size"
                }
              }
            }
          }
        ]
      },
      {
        "map": {
          "orderId": "data.id",
          "grandTotal": "data.total",
          "tax": "data.taxes",
          "shipping": "data.shipping"
        }
      }
    ]
  }
}
```

Out

```javascript
ecommerceOrder([
  {
    "sku": "ers",
    "name": "Everyday Ruck Snack",
    "price": 420,
    "quantity": 1,
    "variant": "black",
    "customDimensions": {
      "1": "l"
    }
  },
  {
    "sku": "cc",
    "name": "Cool Cap",
    "price": 42,
    "quantity": 1,
    "customDimensions": {
      "1": "one size"
    }
  }
], {
  "orderId": "0rd3r1d",
  "grandTotal": 555,
  "tax": 73.76,
  "shipping": 5.22
})
```

### Remove from cart

A product remove fires Piwik PRO ecommerceRemoveFromCart with the removed item.

Event

```json
{
  "name": "product remove",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "60a0746806ebe8e7",
  "trigger": "test",
  "entity": "product",
  "action": "remove",
  "timestamp": 1700000308,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ecommerceRemoveFromCart",
  "data": {
    "set": [
      {
        "set": [
          {
            "map": {
              "sku": "data.id",
              "name": "data.name",
              "price": "data.price",
              "quantity": {
                "value": 1
              },
              "variant": {
                "key": "data.color"
              }
            }
          }
        ]
      }
    ]
  }
}
```

Out

```javascript
ecommerceRemoveFromCart([
  {
    "sku": "ers",
    "name": "Everyday Ruck Snack",
    "price": 420,
    "quantity": 1,
    "variant": "black"
  }
])
```

### Event with goal value

An order complete fires Piwik PRO trackEvent and then trackGoal with the order total as the conversion value.

Event

```json
{
  "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": "a5464cb6bdc6915d",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000307,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "trackEvent",
  "data": {
    "set": [
      {
        "value": "order"
      },
      {
        "value": "complete"
      },
      "data.id"
    ]
  },
  "settings": {
    "goalId": "goal_1",
    "goalValue": "data.total"
  }
}
```

Out

```javascript
trackEvent("order", "complete", "0rd3r1d");

trackGoal("goal_1", 555)
```

### Initialization

Destination bootstrap loads the Piwik PRO tracker and configures the tracker URL and app id.

Event

```json
{
  "loadScript": true,
  "settings": {
    "appId": "XXX-XXX-XXX-XXX-XXX",
    "url": "https://your_account_name.piwik.pro/"
  }
}
```

Out

```javascript
_paq.push([
  "setTrackerUrl",
  "https://your_account_name.piwik.pro/ppms.php"
]);

_paq.push([
  "setSiteId",
  "XXX-XXX-XXX-XXX-XXX"
])
```

### Download link

A file download fires Piwik PRO trackLink with the file URL and the download link type.

Event

```json
{
  "name": "file download",
  "data": {
    "url": "https://www.example.com/whitepaper.pdf"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "c315cba579c593e0",
  "trigger": "test",
  "entity": "file",
  "action": "download",
  "timestamp": 1700000310,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "trackLink",
  "data": {
    "set": [
      "data.url",
      {
        "value": "download"
      }
    ]
  }
}
```

Out

```javascript
trackLink("https://www.example.com/whitepaper.pdf", "download")
```

### Link tracking after the first hit

With the default linkTracking setting, the first hit is followed by enableLinkTracking for automatic outlink and download tracking.

Event

```json
{
  "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": "9cb134ef8f5fc70d",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000312,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```javascript
trackPageView("walkerOS documentation");

enableLinkTracking()
```

### Page view with goal

A page view rule with a goal keeps the default trackPageView and adds a trackGoal conversion.

Event

```json
{
  "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": "dcd2345d1d8d45d9",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000306,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "settings": {
    "goalId": "goal_1"
  }
}
```

Out

```javascript
trackPageView("walkerOS documentation");

trackGoal("goal_1")
```

### Page view

A page view fires Piwik PRO trackPageView with the page title resolved from event data.

Event

```json
{
  "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": "8909c34e44b6e1f7",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000305,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "data": "data.title"
}
```

Out

```javascript
trackPageView("walkerOS documentation")
```

### Ping

A pulse-triggered event fires Piwik PRO ping to extend the time spent on the page.

Event

```json
{
  "name": "page ping",
  "data": {
    "string": "foo",
    "number": 1,
    "boolean": true,
    "array": [
      0,
      "text",
      false
    ]
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "1f0dd2403b6deb80",
  "trigger": "pulse",
  "entity": "page",
  "action": "ping",
  "timestamp": 1700000311,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ping"
}
```

Out

```javascript
ping()
```

### Product detail view

A product view fires Piwik PRO ecommerceProductDetailView with a single-item array.

Event

```json
{
  "name": "product view",
  "data": {
    "id": "ers",
    "name": "Everyday Ruck Snack",
    "color": "black",
    "size": "l",
    "price": 420
  },
  "context": {
    "shopping": [
      "detail",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "ae17f21ffc325fa8",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000302,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "ecommerceProductDetailView",
  "data": {
    "set": [
      {
        "set": [
          {
            "map": {
              "sku": "data.id",
              "name": "data.name",
              "price": "data.price",
              "quantity": {
                "value": 1
              },
              "variant": {
                "key": "data.color"
              },
              "customDimensions": {
                "map": {
                  "1": "data.size"
                }
              }
            }
          }
        ]
      }
    ]
  }
}
```

Out

```javascript
ecommerceProductDetailView([
  {
    "sku": "ers",
    "name": "Everyday Ruck Snack",
    "price": 420,
    "quantity": 1,
    "variant": "black",
    "customDimensions": {
      "1": "l"
    }
  }
])
```

### Site search

A search submit fires Piwik PRO trackSiteSearch with the keyword, category, and result count.

Event

```json
{
  "name": "search submit",
  "data": {
    "query": "rucksack",
    "category": "bags",
    "results": 12
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "us3r",
    "device": "c00k13",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "6dc6a8af03c41b77",
  "trigger": "test",
  "entity": "search",
  "action": "submit",
  "timestamp": 1700000309,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```json
{
  "name": "trackSiteSearch",
  "data": {
    "set": [
      "data.query",
      "data.category",
      "data.results"
    ]
  }
}
```

Out

```javascript
trackSiteSearch("rucksack", "bags", 12)
```

## Loading the tracker[​](#loading-the-tracker "Direct link to Loading the tracker")

With `loadScript: true`, the destination loads `ppms.js` from your account URL and registers the tracker URL and site id. `url` and `appId` are required only then. When the Piwik PRO container already runs on the page, leave `loadScript` unset. The destination then only pushes commands to `_paq`.

## Methods[​](#methods "Direct link to Methods")

`rule.name` is a Piwik PRO JavaScript method, and `data` resolves to its arguments in order. An array built with `set` is spread, any other value is a single argument. Trailing undefined arguments are dropped. A `page view` without `rule.name` calls `trackPageView`, with `rule.data` as its arguments, or else `data.title` as the title.

| Method                                                             | Arguments                                                              | Custom dimensions   |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------- | ------------------- |
| `trackPageView`                                                    | `[title]`                                                              | Set around the hit  |
| `trackEvent`                                                       | `category, action[, name[, value[, dimensions]]]`                      | Dimensions argument |
| `trackGoal`                                                        | `goalId[, conversionValue[, dimensions]]`                              | Dimensions argument |
| `trackSiteSearch`                                                  | `keyword[, category[, resultCount[, dimensions]]]`                     | Dimensions argument |
| `trackLink`                                                        | `linkAddress, linkType[, dimensions]`                                  | Dimensions argument |
| `trackContentImpression`                                           | `contentName[, contentPiece[, contentTarget]]`                         | Set around the hit  |
| `trackContentInteraction`                                          | `contentInteraction, contentName[, contentPiece[, contentTarget]]`     | Set around the hit  |
| `ecommerceProductDetailView`                                       | `products`                                                             | Set around the hit  |
| `ecommerceAddToCart`                                               | `products`                                                             | Set around the hit  |
| `ecommerceRemoveFromCart`                                          | `products`                                                             | Set around the hit  |
| `ecommerceCartUpdate`                                              | `products, grandTotal`                                                 | Set around the hit  |
| `ecommerceOrder`                                                   | `products, { orderId, grandTotal, subTotal, tax, shipping, discount }` | Set around the hit  |
| `ping`                                                             | none                                                                   | Set around the hit  |
| Any other `_paq` command by its explicit name, such as `setUserId` | As your mapping passes them                                            | None                |

The first 13 are the portable methods: the [server destination](/preview/pr-749/docs/destinations/server/piwikpro.md) builds the same hits from the same mapping. Any other command works only in the browser. The destination passes it through as a state command: it gets no custom dimensions and does not count as a hit for link tracking. The ecommerce methods take no currency argument.

An event without `rule.name` that is not a page view is skipped, unless its rule has a goal, which then is sent alone (see [goals](#goals)). The destination logs a warning once per event name, then repeats at debug level. To keep unmapped events out of the destination entirely, ignore everything with a wildcard and map what you need:

```json
"mapping": {
  "*": { "*": { "ignore": true } },
  "page": { "view": {} }
}
```

## Goals[​](#goals "Direct link to Goals")

A rule's `settings.goalId` adds a `trackGoal` call after the method hit. `settings.goalValue` is a mapping value for its conversion value, such as `"data.total"`. A page view rule with goal settings still tracks its page view. With `silent: true`, the rule sends only the goal, with its dimensions. A `silent` rule without a goal sends nothing and logs a skip.

A rule without `name` on an event that is not a page view sends only the goal when it has a `goalId`:

```json
"order": {
  "complete": {
    "settings": {
      "goalId": "6a0f4c1e-3b2d-4e8f-a7c9-1d2e3f4a5b6c",
      "goalValue": "data.total"
    }
  }
}
```

## Custom dimensions[​](#custom-dimensions "Direct link to Custom dimensions")

Custom dimensions are keyed by bare dimension id, like `{ "1": "data.size" }`. Each value is a mapping value, resolved for every event.

* `settings.customDimensions` applies to every hit.
* A rule's `settings.customDimensions` applies to that rule's hits and wins per key. A rule dimension that resolves to nothing removes that dimension from the hit, even when the destination sets it.
* A dimensions object your mapping passes as the method's own argument wins over both settings. Its values are passed unencoded, so percent-encode them yourself. Keys other than `dimension{id}` are dropped.

How the dimensions reach Piwik PRO depends on the method:

* `trackEvent`, `trackGoal`, `trackSiteSearch` and `trackLink` get them as their dimensions argument, `{ "dimension1": "l" }`, with the values from the settings percent-encoded. The goal gets the destination and rule dimensions.
* Page view, content, ecommerce and `ping` hits have no dimensions argument. Their dimensions are set just before the hit with `setCustomDimensionValue` and restored after it: rule-only dimensions are deleted with `deleteCustomDimension`, and the destination values are set again. A rule value therefore never leaks into the tracker's automatic hits, such as outlinks, while destination values stay set on purpose. This requires the Piwik PRO tracker 15.3 or later.

## Identified and anonymous[​](#identified-and-anonymous "Direct link to Identified and anonymous")

The `identified` setting decides whether the tracker identifies the visitor.

| `identified`                                   | Tracker                                                                    |
| ---------------------------------------------- | -------------------------------------------------------------------------- |
| absent or `true`                               | Identified, the Piwik PRO default.                                         |
| `false`                                        | Anonymous and without tracker cookies from init.                           |
| a consent object, like `{ "marketing": true }` | Identified while any listed consent state is granted, anonymous otherwise. |

While anonymous, the tracker runs without cookies. Switching to anonymous pushes `disableCookies`, `deleteCookies` and `setUserIsAnonymous(true)`, so a returning visitor who revoked consent loses the tracker's existing cookies too.

With a consent object, the destination starts the tracker anonymous at init, unless the collector's consent already grants identification. Before each hit it matches the tracker to the current consent: `enableCookies` and `deanonymizeUser` when identification becomes granted, which turns the cookies back on and merges the anonymous session into the identified visitor, and the anonymous commands above when it is revoked.

Use `config.consent` for the states that gate tracking at all, and `identified` for the states that gate identification:

```json
"config": {
  "consent": { "analytics": true },
  "settings": {
    "identified": { "marketing": true }
  }
}
```

caution

Do not repeat the `identified` states in `config.consent`. A destination needs only one of its `config.consent` states granted, so `{ "analytics": true, "marketing": true }` sends events to Piwik PRO when only `marketing` is granted. With `{ "marketing": true }` alone, events wait in the queue until `marketing` is granted, and the tracker never sends an anonymous hit.

## Link tracking[​](#link-tracking "Direct link to Link tracking")

Automatic outlink and download tracking is on by default. The destination pushes `enableLinkTracking` once per page, right after the first hit it sends, such as a page view, an event or a goal. It never pushes it at init, so a page without a hit gets no automatic link tracking. Commands that set state, such as `setUserId`, are not hits and do not start it. Set `linkTracking: false` to switch it off.

## Several Piwik PRO destinations[​](#several-piwik-pro-destinations "Direct link to Several Piwik PRO destinations")

The tracker state the destination manages, link tracking and the identified state, belongs to the collector. Two Piwik PRO destinations on one page share it: link tracking starts once, after the first hit of either destination. Give both the same `identified` setting, or each will switch the shared tracker back and forth.

## Related[​](#related "Direct link to Related")

* [Piwik PRO server destination](/preview/pr-749/docs/destinations/server/piwikpro.md)
* [Consent management](/preview/pr-749/docs/guides/consent.md)
