> For the complete documentation index, see [llms.txt](https://docs.peakcommerce.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peakcommerce.com/guides/administration-guides/guide-installing-analytics-and-tag-manager-scripts.md).

# Guide: Installing Analytics and Tag Manager Scripts

### Overview

PeakCommerce can inject your analytics and tag-manager snippets — Google Tag Manager, VWO, GA4, Heap, and similar tools — into the pages and journeys your visitors see. You paste the snippet once; PeakCommerce places head scripts as high in the page `<head>` as possible (what GTM asks for) and body-start snippets (like the GTM `<noscript>` iframe) right after `<body>`.

Scripts can be configured at three levels that **stack**:

* **Tenant-wide** — your default container, on every public page and journey.
* **Per page** — extra snippets for one page (for example a tool you only run on signup).
* **Per journey** — extra snippets that load whenever a specific journey runs, on any page, including journeys launched inside the customer portal.

Page and journey snippets **extend** the tenant default — your main container keeps running — unless you deliberately switch on **Suppress tenant default** for that page or journey.

Configuring tracking scripts requires a **system administrator**: whatever you paste here executes in your visitors' browsers exactly as written, so authoring access is the security boundary. PeakCommerce staff and CSR screens never run these scripts.

### 1. Add your tenant-wide snippets

1. Open your **user menu** (bottom-left corner) → **Settings** → **Tracking Scripts** (under *Developer Tools*).
2. Paste your head snippet and (if your tool provides one) the body-start snippet.
3. Click **Save Tracking Scripts**.

**You are always configuring the environment you're signed in to** — the page shows which one. Your staging site and your production site are separate environments with separate data, so their scripts are configured separately: to set up production, open this page on your production site. A snippet saved on staging can only ever run on staging.

### 2. Keep staging traffic out of your production analytics

Test traffic can silently pollute your production dashboards. Because each environment holds its own scripts, staging and production can never accidentally share a snippet — but you should still scope the snippets themselves to the right analytics environment:

* **Google Tag Manager** — create a GTM **Environment** (in GTM: Admin → Environments) for staging and paste that environment-specific snippet on your staging site. Your production container snippet goes on your production site.
* **GA4** — additionally define an internal/test `traffic_type` filter so any stray test hits are excluded from reports.
* **VWO** — use your staging/sandbox VWO account on staging, or domain targeting so campaigns only activate on your production hostnames.

### 3. Track a specific page or journey differently

There are three places to add a snippet below the tenant-wide level. Each opens the same editor — head and body-start fields for the environment you're signed in to, plus a *Suppress tenant default* switch:

* **A standalone page**: open the page in the page editor and click **Tracking** in the top bar.
* **A whole journey**: open the journey editor → **Settings** tab → **Tracking scripts** section. A journey-level snippet loads **once when the journey starts** — whichever steps it visits. Use this for a snippet that should run everywhere in the flow.
* **A single step of a journey**: open the journey editor, click the step to edit it, and scroll to the **Tracking scripts** section. This snippet runs **when a visitor reaches that step** — which is what you want for per-step funnel goals (next section).

A note on *Suppress tenant default*: on a page served on its own domain, suppression takes effect on the next page load. A visitor navigating within the app to that page may already have the tenant container loaded — an already-running container cannot be unloaded mid-session. If a page must never carry your default container, give it its own domain.

### 4. Track each step of a multi-step flow (funnel tracking)

Multi-step flows built as a journey — a signup, a checkout, an application — run on a **single URL** that doesn't change as the visitor moves from step to step. That breaks the common "track each step by its URL" setup, because there's only one URL to match on.

PeakCommerce solves this without any URL trick: **each step of a journey is its own page**, and a snippet attached to a step's page runs **at the moment the visitor reaches that step**. So you can fire a distinct conversion or goal event per step, even though the address bar never changes.

Two properties make this reliable for funnel measurement:

* **Fires on step entry** — the snippet runs when its step loads, not at the start of the flow. Put a *Step 2* goal on the Step 2 page and it fires when (and only when) the visitor arrives at Step 2.
* **Fires once per visitor per step** — moving back and forth between steps won't double-count a conversion. This matches how funnel goals are meant to behave.

**The recipe:**

1. Put your **main container/library snippet** at the **tenant-wide** level (Section 1) — or at the **journey** level if you only want it inside this one flow. It loads once, before any step, so the tool is ready when the per-step events fire.
2. Put each **per-step event snippet** on its step: in the journey editor, click the step and use its **Tracking scripts** section (Section 3).

**VWO example.** A per-step goal, on the page for that step — the `_vis_opt_queue` pattern is safe even if the main VWO snippet is still loading:

```html
<script type="text/javascript">
window._vis_opt_queue = window._vis_opt_queue || [];
window._vis_opt_queue.push(function () { _vis_opt_goal_conversion(<your-goal-id>); });
</script>
```

Use a different goal id on each step's page; use `_vis_opt_register_conversion(<test>, <goal>)` on the final/success step to register the funnel completion.

**Google Tag Manager example.** Either approach works — pick one per tool:

* *Step-level snippet* — push a dataLayer event on each step's page, and build your GTM triggers on those events:

  ```html
  <script>
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({ event: 'signup_step', step: 'billing' });
  </script>
  ```
* *Element-visibility trigger* — keep just the main container tenant-wide, and configure GTM triggers that fire when a step's element becomes visible (for example the billing form or the confirmation box). GTM does the step detection client-side.

**Worked example — a three-step signup in VWO.** Say your signup journey has three steps: **Contact info**, **Billing**, and **Confirmation**, and you want a VWO goal recorded when a visitor reaches each one.

First, put your **main VWO snippet** at the tenant-wide level (Section 1) so the VWO library is loaded on the page. Then add one snippet per step: in the **journey editor**, click each step and use its **Tracking scripts** section (Section 3).

*On the Contact info step:*

```html
<script type="text/javascript">
window._vis_opt_queue = window._vis_opt_queue || [];
window._vis_opt_queue.push(function () { _vis_opt_goal_conversion(200); });
</script>
```

*On the Billing step:*

```html
<script type="text/javascript">
window._vis_opt_queue = window._vis_opt_queue || [];
window._vis_opt_queue.push(function () { _vis_opt_goal_conversion(201); });
</script>
```

*On the Confirmation step:*

```html
<script type="text/javascript">
window._vis_opt_queue = window._vis_opt_queue || [];
window._vis_opt_queue.push(function () { _vis_opt_register_conversion(5, 21); });
</script>
```

The result: as a visitor advances through the flow, VWO records goal **200** when they reach Contact info, **201** at Billing, and the funnel completion (test **5**, goal **21**) at Confirmation — each once per visitor, all on the same unchanging URL. Replace the goal and test ids with your own from VWO.

### 5. Tracking on the signed-in customer portal (optional)

By default, **no scripts run behind login** — not even your tenant-wide default. If you want product analytics (for example Heap) on your customers' portal experience:

1. Go to **Settings** → **Tracking Scripts**.
2. Enable **Customer portal tracking** and save.

Treat this as a deliberate decision: trackers on authenticated pages observe *identified* customer activity, and your organization owns the corresponding privacy disclosure to your customers. The switch is off until you turn it on, and page/journey snippets follow the same gate.

### 6. Verify your setup

1. Configure your snippet on staging first (Section 2).
2. Open your public signup or storefront page on the staging domain and use your tool's preview mode (for example **GTM Preview** or the **VWO** editor) to confirm the container fires.
3. For a multi-step flow (Section 4), step through the journey and confirm each step's event fires as you arrive at that step — and that events land in your **staging** property or account, not production.
4. Once staging looks right, open this page on your **production** site and paste the production snippet there.

### Troubleshooting

* **My script doesn't fire.** Check you saved it on the same environment you're testing — staging and production are separate sites with separate scripts, so saving on one never affects the other. Also confirm you're viewing the page as a visitor or customer: admin and CSR sessions never execute tenant scripts.
* **Nothing fires on the customer portal.** Enable **Customer portal tracking** (Section 5).
* **My page-level snippet fires twice?** It shouldn't: injection is deduplicated per loaded page, including when a journey revisits a step. If you see double events, check whether the same snippet is pasted at two levels (tenant *and* page) — the levels stack.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.peakcommerce.com/guides/administration-guides/guide-installing-analytics-and-tag-manager-scripts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
