> ## Documentation Index
> Fetch the complete documentation index at: https://client-integrations-api-dev.sequen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tag Managers

> Install the Sequen pixel through Adobe Tags or Google Tag Manager, and map the events your other pixels already send.

With a tag manager, one tag or rule loads the pixel on every page. Your existing event tags then call it, the same way they call your other marketing pixels. Read [Web Pixel](https://client-integrations-api-dev.sequen.ai/pixel/overview.md) first for what each call sends.

Two settings matter in a tag manager:

* **`autoPage: false`.** Your page-view tag sends page views. Without this, the pixel also sends one when it loads, and you get two.
* **No `spa` option.** Send `sequen("page", …)` from a tag on every page load and every route change instead.

## Load the pixel

> [tab] Adobe Tags
>
> 1. Create a rule named **Sequen – load**.
> 2. Event: **Core → Library Loaded (Page Top)**. Give it the lowest **Order** of your rules, so `sequen` exists before any other rule calls it.
> 3. Action: **Core → Custom Code**, language JavaScript:
>
> ```js theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> (function (w, d, u) {
>   w.sequen = w.sequen || function () { (w.sequen.q = w.sequen.q || []).push([arguments, +new Date()]); };
>   var s = d.createElement("script"); s.async = 1; s.src = u; d.head.appendChild(s);
> })(window, document, "https://s.sequen.com/s.js");
>
> sequen("init", "<PIXEL_ID>", {
>   autoPage: false,
>   itemIdRelation: "products",
>   sessionId: _satellite.getVar("Session ID"),
>   userId: _satellite.getVar("Customer ID") || "",
> });
> ```
>
> Replace `products` with the name of your [catalog](https://client-integrations-api-dev.sequen.ai/api-reference/catalog.md) table, and `Session ID` and `Customer ID` with the names of your own data elements. Or drop those two options to let the pixel keep its own ids.

> [tab] Google Tag Manager
>
> 1. Create a **Custom HTML** tag named **Sequen – load**:
>
> ```html theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> <script>
>   (function (w, d, u) {
>     w.sequen = w.sequen || function () { (w.sequen.q = w.sequen.q || []).push([arguments, +new Date()]); };
>     var s = d.createElement("script"); s.async = 1; s.src = u; d.head.appendChild(s);
>   })(window, document, "https://s.sequen.com/s.js");
>
>   sequen("init", "<PIXEL_ID>", {
>     autoPage: false,
>     itemIdRelation: "products",
>     sessionId: {{Session ID}},
>     userId: {{Customer ID}} || ""
>   });
> </script>
> ```
>
> 2. Trigger: **Initialization - All Pages**, so it fires before your other tags.
>
> Replace `products` with the name of your [catalog](https://client-integrations-api-dev.sequen.ai/api-reference/catalog.md) table, and `{{Session ID}}` and `{{Customer ID}}` with your own variables. Or drop those two options to let the pixel keep its own ids. Leave the variables unquoted: Google Tag Manager inserts each one's value.

Then add a page-view tag or rule that fires on every page and route change:

```js theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
sequen("page", { page_type: "product_detail", item_id: "SKU-123" });
```

Fill `page_type` and `item_id` from your data layer. In Google Tag Manager, wrap each call in `<script>` tags in a Custom HTML tag.

## Send events

Each event tag or rule gets one `sequen(…)` call, filled from your data layer. Most can start as copies of tags you already have: copy the tag, keep its trigger and variables, and swap the call.

> [!TIP]
>
> If your developers can add `data-sqn-*` attributes to product grids and tiles, the pixel records impressions and clicks itself, with no tags. Impressions from markup are also more accurate: they count only products that were actually in view. See [Impressions and clicks](https://client-integrations-api-dev.sequen.ai/pixel/overview.md#impressions-and-clicks).

> [!WARNING]
>
> Use markup or tags for each kind of event, not both. If your tiles carry `data-sqn-*` markup and tags also send `view_item_list`, `select_item` or `add_to_cart`, every impression, click or add to cart is sent twice, with different `event_id`s, and nothing removes the duplicates. To send those events only from tags, leave the markup out or set `autocapture: false` in `init`.

### From a GA4 ecommerce data layer

If your site already pushes [GA4 ecommerce events](https://developers.google.com/analytics/devguides/collection/ga4/ecommerce) to the data layer, map them like this:

| GA4 event | Sequen call | Field changes |
| - | - | - |
| `page_view` | `sequen("page", { page_type })` | Add `page_type` |
| `view_item` | `sequen("page", { page_type: "product_detail", item_id })` | `items[0].item_id` → `item_id` |
| `search` | `sequen("page", { page_type: "search", query, item_ids })` | `search_term` → `query`; `item_ids` = the results, in order |
| `view_item_list` | `sequen("track", "impression", { item_id, rank, module_name })`, once per item | `index + 1` → `rank`; `item_list_name` → `module_name` |
| `select_item` | `sequen("track", "click", { click_type: "product_click", item_id, rank, module_name })` | As for `view_item_list` |
| `add_to_wishlist` | `sequen("track", "click", { click_type: "product_favorite", item_id })` | `items[0].item_id` → `item_id` |
| `add_to_cart` | `sequen("conversion", "add_to_cart", { items })` | `items[]` keeps `item_id`, `quantity` and `price` |
| `purchase` | `sequen("conversion", "purchase", { order_id, revenue, currency, items })` | `transaction_id` → `order_id`; `value` → `revenue` |

GA4's `index` starts at 0, and Sequen's `rank` starts at 1. For example, a Google Tag Manager tag on the `view_item_list` event, with a Data Layer Variable `DLV - ecommerce` for `ecommerce`:

```html theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<script>
  var ec = {{DLV - ecommerce}} || {};
  (ec.items || []).forEach(function (item, i) {
    sequen("track", "impression", {
      item_id: String(item.item_id),
      rank: (typeof item.index === "number" ? item.index : i) + 1,
      module_name: item.item_list_name || ec.item_list_name || "list"
    });
  });
</script>
```

### From the Meta or TikTok pixel

| Meta pixel | TikTok pixel | Sequen call |
| - | - | - |
| `fbq("track", "PageView")` | `ttq.page()` | `sequen("page", { page_type })` |
| `ViewContent` | `ViewContent` | `sequen("page", { page_type: "product_detail", item_id })` |
| `Search` | `Search` | `sequen("page", { page_type: "search", query, item_ids })` |
| `AddToWishlist` | `AddToWishlist` | `sequen("track", "click", { click_type: "product_favorite", item_id })` |
| `AddToCart` | `AddToCart` | `sequen("conversion", "add_to_cart", { items })` |
| `Purchase` | `CompletePayment` or `PlaceAnOrder` | `sequen("conversion", "purchase", { order_id, revenue, currency, items })` |
| No equivalent | No equivalent | `sequen("track", "impression", { item_id, rank, module_name })`: new tags |

Field changes:

* **Item ids.** Meta's `content_ids`, or the `content_id` of each entry in TikTok's `contents`, become `item_ids`. When there is only one, as on `ViewContent` and `AddToWishlist`, send it as `item_id` instead.
* **Items.** Each entry in `contents` becomes an entry in `items`, with `item_id`, `quantity` and `price`.
* **Revenue.** `value` becomes `revenue`. Add `order_id`.
* **Customer id.** TikTok's `ttq.identify({ external_id })` becomes `userId` in the load tag, or `sequen("identify", id)`. Send the raw customer id, not a hash, and never an email address or phone number.
* **Consent.** Meta's `fbq("consent", "revoke" / "grant")` and TikTok's `holdConsent` / `grantConsent` / `revokeConsent` become `consent: "pending"` in `init`, then `sequen("consent", "granted")` or `sequen("consent", "denied")`.
* **Cookies.** TikTok's `ttq.disableCookie()` becomes `cookies: false` in `init`.

## Test

Add `debug: true` to the `init` options, for example only in your tag manager's development environment, and follow [Test, then go live](https://client-integrations-api-dev.sequen.ai/pixel/overview.md#test-then-go-live).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.